// * scrie pe MMC
// * trimite pe GPRS
// * reconecteaza la error
// * opreste GSM daca sta pe loc
// * reporneste GSM daca se deplaseaza
// * reporneste GSM daca se opreste accidental


#class auto
#define LX_2_USE			fs_get_ram_lx()

#use "fs2.lib"
#use "mmc.lib"

#define BINBUFSIZE 63
#define BOUTBUFSIZE 63
#define CINBUFSIZE 63
#define COUTBUFSIZE 63

char HA,HB,LB,LB_temp,cnttr,GSM_re_conn,GSM_stare,GSM_off;
char tmt,rxx,active,rx,tmppp,fis_buf[3],rez,interval[1];
char mem_contor,sir[90],rezultat[100],de_trimis[23];
unsigned char mem_temporar,counter,counter1;
unsigned int stationari,interval_calculat;

File fis,fis1;
const char LB_locatie=2;


void delay_1ms(int cite){
    int totale;
    char numarator;
    for (totale=1;totale<=cite;totale++){
       for (numarator=1;numarator<=204;numarator++){
       }
    }
}

void led(int on,int off){
    int numarator;
    BitWrPortI(PEDR,&PEDRShadow,1,1);
    delay_1ms(on);
    BitWrPortI(PEDR,&PEDRShadow,0,1);
    delay_1ms(off);
}

void led1(char stat){
    BitWrPortI(PEDR,&PEDRShadow,stat,1);
}

void led2(char stat){
    BitWrPortI(PEDR,&PEDRShadow,stat,7);
}

void scrie_adresa(char HHA,char HHB,char LLB){
    fopen_wr(&fis,2);
    fis_buf[0] = HHA;
    fis_buf[1] = HHB;
    fis_buf[2] = LLB;
    fwrite(&fis,fis_buf,sizeof(fis_buf));
    fclose(&fis);
}

void citeste_adresa(void){
    fopen_rd(&fis,2);
    rez = fread(&fis,fis_buf,3);
    if (rez == 3){
      HA = fis_buf[0];
      HB = fis_buf[1];
      LB = fis_buf[2];
    }else{
      led1(1);
    }
    fclose(&fis);
}

void mmc_store(void){
    int i,lead;
    citeste_adresa();
    counter1 = 0;
    lead =(256 - strlen(sir)) + 3 ;
       BitWrPortI(PADR,&PADRShadow,0,3);
       delay_1ms(500);
       BitWrPortI(PADR,&PADRShadow,1,3);
       delay_1ms(500);
       spi_init();
       delay_1ms(100);
    write(HB,HA,LB);
    if (answer(0x00) == 0){
       led2(0);
       BitWrPortI(PADR,&PADRShadow,0,3);
       delay_1ms(500);
       BitWrPortI(PADR,&PADRShadow,1,3);
       delay_1ms(500);
       led2(1);
          while (spi_init() == 0){
            led2(0);
            BitWrPortI(PADR,&PADRShadow,0,3);
            delay_1ms(2000);
            BitWrPortI(PADR,&PADRShadow,1,3);
            delay_1ms(2000);
            led2(1);
          }
          return;
    }
    spi_send(0xFE);
    counter1 = 4;
    counter--;
    while (counter >= counter1){
        spi_send(sir[counter1]);
        counter1++;
    }
    for (i=0;i<=lead;i++){
       spi_send(0x6E);
    }

    for (i=0;i<=255;i++){
       spi_send(0x4C);
    }

    if (answer1(0x05) == 0){
       led2(0);
       BitWrPortI(PADR,&PADRShadow,0,3);
       delay_1ms(2000);
       BitWrPortI(PADR,&PADRShadow,1,3);
       delay_1ms(2000);
       led2(1);
          while (spi_init() == 0){
            led2(0);
            BitWrPortI(PADR,&PADRShadow,0,3);
            delay_1ms(2000);
            BitWrPortI(PADR,&PADRShadow,1,3);
            delay_1ms(2000);
            led2(1);
          }
       return;
    }
    BitWrPortI(PADR,&PADRShadow,1,0);
    for (i=1;i<=10;i++){
       clocks();
    }
    BitWrPortI(PADR,&PADRShadow,0,0);
    delay_1ms(300);
    if (LB > 0xFC){
       LB = 0;
       if (HA == 0xFF){
          HA = 0;
          if (HB == 0x0E){
             HA = 1;
             HB = 0;
             LB = 0;
          } else {
             HB = HB + 1;
          }
          // eeprom_put HA
          // eeprom_put HB
       } else {
          HA = HA + 1;
       }
    } else {
       LB = LB + 2;
    }
    scrie_adresa(HA,HB,LB);
    active = 0;
    tmppp = 0;
}

void readCbuf(void){
   char raspuns[100],intrare;
   char iii;
   while ((intrare = serCgetc()) == -1){
   }
   iii = 0;

   while ((intrare = serCgetc()) != -1 && iii < 100){
      raspuns[iii] = intrare;
      iii++;
   }
}
char ring(void){
   return 0;
}

void send_sms(void){
   return;
}

void drop(void){
   return;
}

void conn_init(void){
    serBputs("ATZ\r\n");
    delay_1ms(100);
    serBputs("AT&F&C1&D2E0\r\n");
    delay_1ms(200);
    serBputs("AT+CIPCLOSE\r\n");
    delay_1ms(2000);
    serBputs("AT+CIPSHUT\r\n");
    delay_1ms(2000);
    serBputs("AT+CDNSCFG=\"193.231.236.30\"\r\n");
    delay_1ms(200);
    serBputs("AT+CDNSORIP=1\r\n");
    delay_1ms(200);
    serBputs("AT+CIPSPRT=1\r\n");
    delay_1ms(200);
    serBputs("AT+CIPDPDP=0\r\n");
    delay_1ms(200);
    serBputs("AT+CIPHEAD=0\r\n");
    delay_1ms(200);
    serBputs("AT+CIPSRIP=0\r\n");
    delay_1ms(200);
    serBputs("AT+CIPMODE=0\r\n");
    delay_1ms(200);
    serBputs("AT+CSTT=\"internet\",\"\",\"\"\r\n");
    delay_1ms(200);
    serBputs("AT+CIICR\r\n");
    delay_1ms(2500);
    serBputs("AT+CIFSR\r\n");
    delay_1ms(2000);
    serBrdFlush();
    delay_1ms(500);

}

void conn_open(void){
    serBputs("AT+CIPSTART=\"tcp\",\"gps1.autotrack.ro\",\"51117\"\r\n");
    delay_1ms(6000);
}
void conn_close(void){
    serBputs("AT+CIPCLOSE\r\n");
    delay_1ms(2000);
    serBputs("AT+CIPSHUT\r\n");
    delay_1ms(4000);
    serBrdFlush();
}

int pos(void){
char cnt1,pozitie;
pozitie=1;
cnt1=0;
while (pozitie<=9){
   if (sir[cnt1]==44) pozitie++;
   cnt1++;
}
return cnt1;

}

void GSM_power(char stt){
   BitWrPortI(PEDR,& PEDRShadow,1,0);
   delay_1ms(2000);
   BitWrPortI(PEDR,& PEDRShadow,0,0);
   if (stt==1){
      GSM_stare = 1;
   }else{
      GSM_stare = 0;
   }
}

void SMS_verifica(void){
   serBputs("AT+CMGF=1\r\n");
   delay_1ms(300);
   serBputs("AT+CMGR=1\r\n");
   delay_1ms(1000);
}

void send_data(void){
char cnt1,sss,cnti,SMS[100];

   SMS_verifica();
   for (cnt1=1;cnt1<=99;cnt1++){
      rezultat[cnt1]=32;
   }
   for (cnt1=0;cnt1<23;cnt1++){
      de_trimis[cnt1]=32;
   }
   rezultat[0]=0;

     if (serBread(rezultat,99,1000) > 0){
         if (strstr(rezultat,"READ") != 0){// daca are SMS in modem
            serBrdFlush();
            delay_1ms(1000);
            SMS_verifica();
            serBread(SMS,99,1000);
            printf(SMS);
         }
         if (strstr(rezultat,"ERROR") != 0){
            printf("CONN error\r\n");
            GSM_re_conn=5;
         }
         if (strstr(rezultat,"GPS") != 0){
            printf(rezultat);
            printf("\r\n");
         }else{
            for (cnti=1;cnti<=5;cnti++){
               led2(1);
               delay_1ms(50);
               led2(0);
               delay_1ms(50);
            }
            delay_1ms(50);
            printf("No conn\r\n");
            printf(rezultat);
            printf("\r\n");
            GSM_re_conn++;
         }
         // codeaza ora
         sss=sir[7]-48;
         sss <<= 4;
         de_trimis[0]=sss+(sir[8]-48)+65;

         //codeaza minutul
         sss=sir[9]-48;
         sss <<= 4;
         de_trimis[1]=sss+(sir[10]-48)+65;

         //codeaza secunda
         sss=sir[11]-48;
         sss <<= 4;
         de_trimis[2]=sss+(sir[12]-48)+65;

         // lat grd
         sss=sir[20]-48;
         sss <<= 4;
         de_trimis[3]=sss+(sir[21]-48)+65;

         //lat sec
         sss=sir[22]-48;
         sss <<= 4;
         de_trimis[4]=sss+(sir[23]-48)+65;

         //lat fract1
         sss=sir[25]-48;
         sss <<= 4;
         de_trimis[5]=sss+(sir[26]-48)+65;

         //lat fract 2
         sss=sir[27]-48;
         sss <<= 4;
         de_trimis[6]=sss+(sir[28]-48)+65;

         //long grd
         sss=sir[32]-48;
         sss <<= 4;
         de_trimis[7]=sss+(sir[33]-48)+65;

         //long grd+min
         sss=sir[34]-48;
         sss <<= 4;
         de_trimis[8]=sss+(sir[35]-48)+65;

         //long min  + fract
         sss=sir[36]-48;
         sss <<= 4;
         de_trimis[9]=sss+(sir[38]-48)+65;

         //long fract
         sss=sir[39]-48;
         sss <<= 4;
         de_trimis[10]=sss+(sir[40]-48)+65;

         //long fract + flags
         sss=sir[41]-48;
         sss <<= 4;
         de_trimis[11]=sss;
         //NS
         if (sir[30]==78){
            de_trimis[11]=de_trimis[11]+4;
         }
         //EV
         if (sir[43]==69){
            de_trimis[11]=de_trimis[11]+2;
         }
        //valid/invalid
         if (sir[18]==65){
            de_trimis[11]=de_trimis[11]+1;
         }
         de_trimis[11]=de_trimis[11]+65;

         //viteza
         if (sir[46]==46){
           de_trimis[12]=65;
           sss=sir[45]-48;
           sss<<=4;
           de_trimis[13]=sss+(sir[47]-48)+65;
           sss=sir[48]-48;
           sss<<=4;
           de_trimis[14]=sss+65;
         }
         else if (sir[47]==46){
            de_trimis[12]=(sir[45]-48)+65;
            sss=sir[46]-48;
            sss<<=4;
            de_trimis[13]=sss+(sir[48]-48)+65;
            sss=sir[49]-48;
            sss<<=4;
            de_trimis[14]=sss+65;
         }
         else if (sir[48]==46){
            sss=sir[45]-48;
            sss<<=4;
            de_trimis[12]=sss+(sir[46]-48)+65;
            sss=sir[47]-48;
            sss<<=4;
            de_trimis[13]=sss+(sir[49]-48)+65;
            de_trimis[14]=65;
         }

         // ziua
            sss=sir[pos()]-48;
            sss<<=4;
            de_trimis[17]=sss+(sir[pos()+1]-48)+65;
         //luna
            sss=sir[pos()+2]-48;
            sss<<=4;
            de_trimis[18]=sss+(sir[pos()+3]-48)+65;
         //anul
            sss=sir[pos()+4]-48;
            sss<<=4;
            de_trimis[19]=sss+(sir[pos()+5]-48)+65;

         //cod masina
            de_trimis[20]=0+65;
            de_trimis[21]=1+65;
         // senzori
            de_trimis[22]=0+65;


         serBputs("AT+CIPSEND\r\n");
         delay_1ms(500);
         for (cnt1=0;cnt1<23;cnt1++){
             serBputc(de_trimis[cnt1]);
         }
         serBputs("\r\n");
         serBputc(26);
         delay_1ms(500);
     }else{ //daca nu primeste chiar nimic de la GSM, incrementeaza contorul de timeout
        printf("GSM oprit?\r\n");
        GSM_off++;
     }
}


void main(){
     unsigned int c,contor,netransmise,viteza_zero;
     char stare,prelucrare,stare_clipire;
     char octet_citit,i;
     char viteza[5];


     rez = 0;
     HA = 1;
     HB = 0;
     LB = 0;
     LB_temp = 0;
     active = 0;
     rx = 0;
     counter = 0;
     counter1 = 0;
     tmppp = 0;
     netransmise = 0;
     viteza_zero = 0;

     serBopen(115200);
     serCopen(4800);

     WrPortI(SPCR, & SPCRShadow, 0x84);
     WrPortI(PEFR, & PEFRShadow,0x00);
     WrPortI(PEDDR, & PEDDRShadow,0xDF);
     WrPortI(PEDR,& PEDRShadow,0x00);
     delay_1ms(100);
     BitWrPortI(PEDR,& PEDRShadow,0,5);
     delay_1ms(2000);
     GSM_power(1);
     delay_1ms(25000);
     printf("DELSMS\r\n");
//     for (i=0;i<=10;i++){
//         serBputs("AT+CMGD=");
//         serBputc(i+48);
//         serBputs("\r\n");
//         delay_1ms(100);
//     }
     delay_1ms(1000);

SMS_verifica();
serBread(rezultat,88,300);
printf(rezultat);
printf("\r\n");
     serBrdFlush();
     led1(1);
     led2(1);

     stare = 0;
     stare_clipire = 0;
     counter = 0;
     prelucrare = 0;
     GSM_off = 1;
     strcpy(sir,"");

     // verifica daca poate scrie in fisier
     if (!LX_2_USE){
       //printf("eroare FS\r\n");
       for (;;){ // eroare, nu poate scrie in fisier
          led(1000,1000);
       }
     }else{ // minunat, poate sa faca scrierea
        //printf("FS OK\r\n");
        for (i=1;i<=5;i++){
           led(200,200);
        }
        led1(1);
     }
     // initializeaza FS
     rez = fs_init(0,0);
     if (rez){
        //printf("NO FS INIT\r\n");
        for (;;){ // nashpa, nu poate initializa file-system-ul
           led(100,100);
        }
     }
     // configureaza lungime memorie pentru fisier
     fs_set_lx(LX_2_USE,LX_2_USE);
     //printf("FSLENOK\r\n");

     // daca este apasat butonul de reset la alimentare
     // sterge fisierul de stocare
     if ( BitRdPortI(PBDR,2)==0 ){
        fdelete(2);
        fdelete(3);
        led(100,100);
        led(1000,1000);
        led(100,100);
        led1(1);
     }

     // incearca sa creeze fisier
     // daca exista inseamna ca il deschide pentru citire
     rez=fcreate(&fis,2);
     if (rez && errno == EEXIST){
        printf("RDADDR\r\n");
        citeste_adresa();
     } else { // daca nu exista fiserul atunci scrie varianta initiala
        led2(0);
        scrie_adresa(0xFF,0x0E,0x00);
        delay_1ms(100);
        led2(1);
        printf("WRADDR\r\n");
        //printf("WRFILE\r\n");
     }

     // fisierul cu intirzierea
     interval[0]=0;
     rez=fcreate(&fis1,3);
     if (rez && errno == EEXIST){
        printf("RDDELAY\r\n");
        fopen_rd(&fis1,3);
        fread(&fis1,interval,sizeof(interval));
        fclose(&fis1);
     } else { // daca nu exista fiserul atunci scrie varianta initiala
        led2(0);
        fopen_wr(&fis1,3);
        fwrite(&fis1,interval,sizeof(interval));
        fclose(&fis1);
        delay_1ms(100);
        led2(1);
        printf("WRDELAY\r\n");

     }
     interval_calculat=interval[0] * 60;

    while (spi_init() != 1){
       led1(0);
       BitWrPortI(PADR,&PADRShadow,0,3);
       delay_1ms(100);
       led1(1);
       BitWrPortI(PADR,&PADRShadow,1,3);
       delay_1ms(100);
     }
     led2(0);
     counter = 0;
     stationari = 1;
     GSM_stare = 1;
     GSM_re_conn=0;
     conn_init();
     conn_open();
     printf("Sistem pregatit\r\n");
        for (;;)
        {
          costate {
             c = serCgetc();
                if (c != -1){
                   if ((c==0x24) || (counter>0)){
                      led1(1);
                      sir[counter] = c;
                      sir[counter+1] = 0x00;
                      counter++;
                      if (counter==6){
                         if (strstr(sir,"$GPRMC")!=0){ // daca este RMC, prelucreaza
                            while ((counter<85) && (c!=0x0A)){
                               while ((c=serCgetc()) == -1){
                               }
                               sir[counter]=c;
                               sir[counter+1]=0x00;
                               counter++;
                            }
                            // stocheaza si transmite
                            printf("scriu pe MMC\r\n");
                            printf(sir);
                            printf("\r\n");

                            mmc_store();
                            led(200,200);
                            // a terminat de stocat

                            // incepe sa transmita
                            // daca sta pe loc, transmite de 2 ori si sta
                            // daca e setat sa nu trimita, nu trimite
                            if (interval_calculat < 15300){ // daca intervalul e mai mic de 255 minute, trimite cu delay-ul de rigoare
                            if ((sir[45] == 48) && (BitRdPortI(PBDR,2)==1)){
                               led2(0);
                               if (stationari<4){
                                   if (GSM_re_conn == 5) { // daca a acumulat 5 erori, reconecteaza
                                      printf("RECONNECT\r\n");
                                      conn_close();
                                      conn_init();
                                      GSM_re_conn = 0;
                                      conn_open();
                                   }
                                   printf("Stau, dar trimit\r\n");
                                   send_data();
                                   delay_1ms(1000);
                                   waitfor(DelaySec(interval_calculat));
                                   stationari++;
                               }else if (stationari>=4){ // la 3 stationari de 10 secunde numai trimir
                                  if (stationari>=350){ // la 350 stationari de 10 secunde, opresc GSM
                                     if (GSM_stare==1){
                                        printf("Opresc GSM\r\n");
                                        conn_close();
                                        GSM_power(0);
                                        delay_1ms(2000);
                                     }else{
                                        printf("Zzzzz!!!\r\n");
                                        delay_1ms(4000);
                                     }
                                  }else{
                                     printf("Stau si nu trimit\r\n");
                                     delay_1ms(5000);
                                     stationari++;
                                  }
                               }
                            }else{
                                led2(1);
                                if (GSM_off > 3){ // daca nu raspunde de 3 ori, modemul pe local
                                    printf("modem oprit? repornire\r\n");
                                    conn_close();
                                    GSM_power(1);
                                    delay_1ms(25000);
                                    conn_init();
                                    conn_open();
                                    send_data();
                                    delay_1ms(1000);
                                    waitfor(DelaySec(interval_calculat));
                                    GSM_off=1;

                                }

                                if (GSM_stare==0){
                                   printf("Pornesc GSM\r\n");
                                   GSM_power(1);
                                   delay_1ms(25000);
                                   conn_init();
                                   conn_open();
                                   send_data();
                                   delay_1ms(1000);
                                   waitfor(DelaySec(interval_calculat));
                                   stationari=1;
                                }else{
                                   if (GSM_re_conn >= 5) { // daca a acumulat 3 erori, reconecteaza
                                      printf("RECONNECT\r\n");
                                      conn_close();
                                      conn_init();
                                      GSM_re_conn = 0;
                                      conn_open();
                                   }
                                   printf("Trimit\r\n");
                                   send_data();
                                   delay_1ms(1000);
                                   waitfor(DelaySec(interval_calculat));
                                   stationari=1;
                                }

                            }

                          // a terminat de transmis
                           }else{ // daca intervalul este 255 secunde
                                conn_close();
                                SMS_verifica();
                           } // sfirsit daca intervalul este mai mic de 255 sec
                            // sfirsit stocheaza si transmite
                         } //sfirsit prelucrare, daca este RMC
                         counter = 0;
                         strcpy(sir,"");
                      }
                   }
                }

          }
          costate { //verifica daca are SMS de comanda
          }
        } // inchide loop-ul infinit
}



