#include "serial_fuggv.h"
#define _haromezer 100

int SAVE_SIGNAL = 0;

int isOK(char *s) {
  return strstr(s,"OK") != NULL;
}
    
int teszt(void)
{
  HANDLE hCom; 
  hCom = initComPort("COM6");
  initModul(hCom);  
  //connect(5,hCom);
  send(hCom);
#ifndef mikro  
  CloseHandle(hCom);
//  system("PAUSE");
#endif
  return 0;
}

void error(char *msg);
void save(char *msg);

#ifdef mikro
       #include "mikro_lib.c"
#endif

/**FÜGGVÉNYEK*/

void sendSMS(char* num, char* msg,HANDLE hCom){  //tarolt sms kuldese
//num formátuma:+36....
    char * resp;
    char * s;
    int j;
    char c[2];
    DWORD bytesRead;
    BOOL bRead;

    s = (char*)malloc(sizeof(char)*180);
    sprintf(s,"AT+CMGS=%s\r",num);
    writeCommand(s,hCom);

    printf("Szam:%s\n",s);
    sprintf(s,"%s%c",msg,'\x1a');

    for(j=0; j < 3; j++)
           ReadFile(hCom,c,1,&bytesRead,NULL);
    printf("Kapott prompt:%c\n",c[0]);

    printf("Uzenet:%s\n",s);
    sleep(2000);
    writeCommand(s,hCom);
    sleep(2000);
    resp = readResponse(hCom);
    printf("SMS status:%s\n",resp);
    resp = readResponse(hCom);
    printf("SMS status2:%s\n",resp);
    free(resp);
    free(s);
}

int connect(int attemptNum, HANDLE hCom){
    int contextCounter = 0;
    int connectionCounter =0;
    int connectionCommandCounter =0,i;
    char errors[BUFFER_SIZE], msg[200], *resp;
    
/*
    writeCommand("at\r",hCom); puts(_readResponse(hCom));
    sleep(30);
    writeCommand("AT+CMGF=1\r",hCom); puts(_readResponse(hCom)); //  instruct the GSM / GPRS modem to operate in SMS text mode. 
    sleep(30);
    writeCommand("AT+CMGW=\"+36706218378\"\r",hCom);
    
    printf(_readResponse(hCom));

    sprintf(msg,"A simple demo of SMS text messaging.%c",26);
    
    writeCommand(msg,hCom);sleep(30);
    resp = _readResponse(hCom); while (*resp != '+' && *resp) resp++; printf("_%s_",resp);

    if (!strncmp(resp,"+CMGW",5)) {
      int smspos;
      char p[80];
      sscanf(resp,"+CMGW: %d",&smspos);
      sprintf(p,"AT+CMSS=%d\r",smspos);
      printf("smspos = %d\n", smspos);
      writeCommand(p,hCom); sleep(30); puts(_readResponse(hCom)); // send the SMS text message from the message storage of the GSM / GPRS modem.
    }
    else puts("hiba");
*/

    for(i=0; i < attemptNum; ++i) {
            sleep(_haromezer);
            writeCommand("AT+CIPCSGP=1,net\r",hCom);
            sleep(_haromezer);
            char* resp = readResponse(hCom);

            if(!isOK(resp)){
                sprintf(errors,"\nSetting PDP context:%s\n",resp);
                //dprintf("Setting PDP context failed!\n");
                error(errors);
                errors[0]='\0';
                contextCounter++;
                continue;
            }
            resp = '\0';            
//            writeCommand("AT+CIPSTART=\"TCP\",\"193.138.125.249\",\"80\"\r",hCom);            
            writeCommand("AT+CIPSTART=\"TCP\",\"193.6.181.254\",\"80\"\r",hCom);
            sleep(_haromezer);
            resp = readResponse(hCom);
            dprintf("\nAT+CIPSTART:%s\n",resp);
            if(!isOK(resp)){   
                 sprintf(errors,"Connection command format: %s\n",resp);
                 connectionCommandCounter++;
                 error(errors);
                 errors[0]='\0';                             
                 continue;
            }
            sleep(_haromezer);
            resp = readResponse(hCom);
            dprintf("CONNECTION STATUS: %s\n",resp);
            if(isOK(resp)) return 1;
            else {
                 sprintf(errors,"Connection status: %s\n",resp);
                 connectionCounter++;
                 error(errors);
                 errors[0]='\0';   
                 continue;   
                 }            
        }
  
        sprintf(errors,"Analysis:\nThe value of contextCounter: %d\nThe value of connectionCounter: %d\nThe value of connectionCommandCounter: %d\n\n\n",contextCounter,connectionCounter,connectionCommandCounter);
        error(errors);
        errors[0]='\0';    
        return 0;
}

#ifndef mikro
int send(HANDLE hCom){ //visszatér a sikeresen elküldött sorok számával
//	connect(NUM_ATTEMPT,hCom);
//	return 0;	
    char *send= NULL;
    FILE *fsend;
    char *seged;
    int hour;
    int block_id;
    int data;
    char s[256];
    int rowCounter = 0;
    
    dprintf("Csatlakozas...\n");
    if(connect(NUM_ATTEMPT,hCom)){
       dprintf("Start sending tosend.txt\n");
       fsend = fopen("tosend.txt","r");
       if(!fsend){
           error("Nem tudom megnyitni a kuldendo adatok fajljat!\n");
           system("pause");
           exit(-1);
       }
       while(fgets(s,256,fsend)){
          int i=0;
          s[strlen(s)-1] = '\0';//leszedjük az újsort
          seged = strtok(s," ");
          hour = atoi(seged);
          seged = strtok(NULL," ");
          block_id = atoi(seged);
          seged = strtok(NULL," ");
          data = atoi(seged);
          send = make_message(hour,block_id,data); 
          dprintf("send_data jon!\n");
          dprintf("%d. proba\n",i);
          while(!send_data(send,hCom)) {
            i++;
            char * resp;
            
            writeCommand("AT+CIPSTATUS\r",hCom);
            resp = readResponse(hCom);
            dprintf("El meg a felepitett kapcsolat? Valasz: %s\n",resp);
            if (!strcmp(resp,"ERROR")) connect(NUM_ATTEMPT, hCom);
            
            dprintf("%d. proba\n",i);
            sleep(_haromezer);
            if (i == 4) while (!connect(NUM_ATTEMPT,hCom));
            if (i > 8) break;
          }
          rowCounter++;          
       }
    }
         
    dprintf("Kapcsolat zarasa!\n");
    writeCommand("AT+CIPCLOSE\r",hCom);
    sleep(_haromezer);
    dprintf("Cipclose kiirva!\n");
    seged = readResponse(hCom);
    dprintf("Cipclose result: %s",seged);
       
    return rowCounter;
}
#endif	   

int send_data(char *send, HANDLE hCom) {
    char *resp;
	int i;
    char cipsend[BUFFER_SIZE];
    
    for(i=0; i < 3; i++) {         //egy adatcsomag elkuldesevel 3 x probalkozik
      sleep(_haromezer);
      dprintf("\nProbalkozas: %d. / 3\n",i+1);      
      sprintf(cipsend,"AT+CIPSEND=%d\r",strlen(send));
      dprintf("AT + CIPSEND kezdete:%s\n",cipsend);
      writeCommand(cipsend,hCom);
//      sleep(2000);
      dprintf("AT + CIPSEND olvasas adatkuldes kov.\n");

//         while (bytesRead) ReadFile(hCom,(PVOID)&sor[k++],1,&bytesRead,NULL);     

      resp = readResponse(hCom);
      dprintf("Kapott prompt: %s\n",resp);
      if (!isOK(resp)) continue;
      
      dprintf("Sending %s\n",send);
      writeCommand(send,hCom);
      resp=readResponse(hCom);
      dprintf("\nCIPSEND status: %s\n",resp);
      if (!strcmp(resp,"ERROR")) continue;

      dprintf("Szerverre varunk!\n");
      sleep(_haromezer);
      if(!process_response(hCom)) continue;                
      dprintf("A szerver valaszolt!");
      return 1; //sikeresen átment az adat
    }
    return 0;//nem sikerult elkuldeni az adatot
}



void initModul(HANDLE hCom){    //modul állapotának ellenőrzése PIN megadása
      dprintf("Modul configuration is started!\n");
      char* resp;
      
      writeCommand("AT+CBC\r",hCom);
      dprintf("Akku: %s%s\n",readResponse(hCom),readResponse(hCom));

      writeCommand("at+cgmi\r",hCom);
      dprintf("Gyarto: %s%s\n",readResponse(hCom),readResponse(hCom));
      
      writeCommand("at+cpas\r",hCom);
      dprintf("Activity status: %s\n",readResponse(hCom));

      writeCommand("AT+CPIN?\r",hCom);  
      resp = readResponse(hCom);     //TO DO: SIM kártya állapotának ellenőrzése
      dprintf("\nPIN state = %s\n",resp);
      if (strstr(resp,"+CPIN: SIM PUK") != NULL) {
        dprintf("Meg kell adni a PUK-kodot\n");
        exit(0);
      }
      
      if(getPhoneStatus(hCom) == 1){  //PIN kódot meg kell adni 
         writeCommand("AT+CPIN=6377\r",hCom);
         resp = readResponse(hCom);
         if(isOK(resp)){
            dprintf("\nPIN code is OK!");
            dprintf("\nModul's activity status: READY(0)\n");
            }
         else {                         //TODO: mi legyen a vacak PIN koddal ?
              dprintf("Wrong PIN code");
              exit(100);
              }

        
         //hibakodokat is kerek a hiba melle
         writeCommand("AT+CMEE=1\r",hCom);
         sleep(30);
         resp = readResponse(hCom);
         if(isOK(resp)){
             dprintf("\nError reporting enabled!");
             }
         //küldésnél nem kell prompt              EZ NEM CSINAL SEMMIT!
         writeCommand("AT+CIPSPRT=0\r",hCom);
         sleep(30);
         resp = readResponse(hCom);
         if(isOK(resp)){
            dprintf("\nCIPSEND prompt turned off!\n");
            }
        
         }     
      
}

#ifndef mikro     
void sleep(unsigned int mseconds)
{
    clock_t goal = mseconds + clock();
    while (goal > clock());
}
#endif

int getPhoneStatus(HANDLE hCom){
    char *resp;   
    int status;
    char seged1[10];
    dprintf("\nGetting modul's activity status!");
    writeCommand("AT+CPAS\r",hCom);
    resp = readResponse(hCom);
    sscanf(resp,"%s %d ",seged1,&status);
    dprintf("\nModul's activity status: %d\n",status);
    return status;
    }
    

BOOL writeCommand(char *msg, HANDLE hCom){         //soros portra iras
     BOOL bWrite;
     DWORD bytesWritten;
     bWrite = WriteFile(hCom,msg,strlen(msg),&bytesWritten,NULL);
     puts(msg);
     if(bWrite != 0){ 
            //   dprintf("\nAz uzenet sikeresen kiirasra kerult: %s\nAz uzenet merete: %d\n",msg,strlen(msg));
               return TRUE;
               }
     dprintf("Sikertelen kiirási kisérlet!\n");
     return FALSE;
     }


char * readResponse(HANDLE hCom){    //soros portrol erkezo valasz beolvasasa
     BOOL bRead;
     DWORD bytesRead;
     int i = 0, j,z;
     char c[2];
return _readResponse(hCom);
     c[1]='\0';
     int carriageCounter = 0; // a válasz <CR><LF>szoveg<CR><LF> formátumu 
     char *buffer = (char*)malloc(sizeof(char)*BUFFER_SIZE);
     char *usefull = (char*)malloc(sizeof(char)* BUFFER_SIZE);   
     buffer[0] = usefull[0] ='\0';
     while((bRead = ReadFile(hCom,c,1,&bytesRead,NULL))== TRUE){
               if(c[0] == '\n' && c[1] == '\r') carriageCounter++;
               if(carriageCounter == 2) break;
               c[1] = c[0];
               buffer[i++] = c[1];
               }
     buffer[i] ='\n'; //mert ezt már nem másolom át

     //Az i tartalmazza a buffer aktuális méretét    
     for(z=2, j=0; z <= i-2; ++z, ++j) //hasznos válasz kinyerése
              usefull[j] = buffer[z];
     usefull[j] = '\0';
     free(buffer);
    // dprintf("Kiszemetelt valasz:%s", usefull);
     return usefull;
}

char * _readResponse(HANDLE hCom){    //soros portrol erkezo valasz beolvasasa
     DWORD bytesRead;
     int timeout = 50;
     char sor[1024];
     char *buffer = (char*)malloc(sizeof(char)*BUFFER_SIZE);
     buffer[0] = 0;
     while(ReadFile(hCom,sor,1,&bytesRead,NULL) == TRUE && timeout--) {
       if (strlen(buffer) < 1000) strcat(buffer, sor);
     }
     while (buffer[strlen(buffer)-1] == '\n') buffer[strlen(buffer)-1] = 0;
     while (buffer[0] == '\n') buffer++;

     strcpy(sor, buffer);
     free(buffer);
     return strdup(sor);
}

#ifndef mikro     
void error(char *msg) { //error log készítéséhez
     FILE *flog;
     dprintf("Error: %s",msg);
     flog=fopen("gprs.log","a");
     if(!flog){
      dprintf("Nemtudok logolni!\n");
      system("pause");
      exit(-1);          
     }
     fprintf(flog,"Error: %s",msg);
     fflush(flog);
     fclose(flog);
}
#endif	 

#ifndef mikro
void save(char *msg) { //error log készítéséhez
     FILE *fsave;
     dprintf("Mentett: %s",msg);
     fsave=fopen("save.log","a");
     if(!fsave){
      dprintf("Nemtudok menteni!\n");
      system("pause");
      exit(-1);          
     }
     fprintf(fsave,"Error: %s",msg);
     fflush(fsave);
     fclose(fsave);
     SAVE_SIGNAL = 1;     
}
#endif	 
          
BOOL process_response(HANDLE hCom){ //TODO: A PHP SZKRIPTET MÓDOSÍTANI KELL ERRE, hogy legyen benne ##!
//    int hashmarkCounter = 0;    
    char message[1024];
    int charCounter = 0;
/*
    while (ReadFile(hCom,c,1,&bytesRead,NULL)== TRUE) {
               dprintf("%c",c[0]);
               charCounter ++;               
               if(c[0] == '#') hashmarkCounter++;                      
               if(hashmarkCounter != 0){
                    if(c[0] != '#') message[i++] = c[0];     
                    if(hashmarkCounter == 2) break;                    
               }              
         }
*/
    strcpy(message, readResponse(hCom)); 
    dprintf(message);

         dprintf("\nA szerver valasza: %s\n",message,readResponse(hCom));
//         dprintf("\nA szervervalasz merete: %d\n",charCounter);
         if(isOK(message)) return TRUE;
         return FALSE;
}


char *make_message(int hour,int block_id,int data){     //küldendő sztring előűllítása

    char *send =(char *)malloc(sizeof(char) *BUFFER_SIZE);
    char *sendata= (char *)malloc(sizeof(char)* 100);//data to send 
    char * header = "POST /gsm/process.php HTTP/1.1\r\nHost:roller.ttk.unideb.hu\r\nAccept:text/html\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:";

    sprintf(sendata,"station_id=%d&password=szelmero&hour=%d&block_id=%d&data=%d\r\n",STATION_ID,hour,block_id,data);
    dprintf("\nMAKE_MESSAGE: Content-lengh: %d\n",strlen(sendata)-2);
    sprintf(send,"%s%d\r\n\r\n%s",header,strlen(sendata)-2,sendata);//azért, mert a \r\n a szerveré
    dprintf("\nMAKE_MESSAGE:Kiirando adatok: %s",send);
  /*  system("pause");
    exit(1);*/
    return send;
     
    }
    
  int connected(HANDLE hCom){ // van-e még kapcsolat?
      char *resp;
      writeCommand("AT+CIPSTATUS\r",hCom);
      resp = readResponse(hCom);
      if(strcmp(resp,"8 CONNECT OK") == 0)
        return 1;
      return 0;      
  }

#ifndef mikro
HANDLE initComPort(char *pcCommPort){           //soros port inicializalasa
       dprintf("Serial port configuration is started!\n");
       DCB dcb;
       HANDLE hCom;
       BOOL fSuccess;
       COMMTIMEOUTS cto;
       
       hCom = CreateFile( pcCommPort,
                     GENERIC_READ | GENERIC_WRITE,
                     0,    // comm devices must be opened w/exclusive-access
                     NULL, // no security attributes
                     OPEN_EXISTING, // comm devices must use OPEN_EXISTING
                     0,    // not overlapped I/O
                     NULL  // hTemplate must be NULL for comm devices
                     );

       if (hCom == INVALID_HANDLE_VALUE) {
      // Handle the error.
       dprintf ("CreateFile failed with error %d.\n", GetLastError());
       system("pause");
       exit (1);
       }

  // We will build on the current configuration, and skip setting the size
  // of the input and output buffers with SetupComm.

        fSuccess = GetCommState(hCom, &dcb);

     if (!fSuccess) {
      // Handle the error.
         dprintf ("GetCommState failed with error %d.\n", GetLastError());
         system("pause");
         exit (2);
         }

  // Fill in the DCB: baud=9,600 bps, 8 data bits, no parity, and 1 stop bit.

     dcb.BaudRate = CBR_9600;     // set the baud rate
     dcb.ByteSize = 8;             // data size, xmit, and rcv
     dcb.Parity = NOPARITY;        // no parity bit
     dcb.StopBits = ONESTOPBIT;    // one stop bit

     fSuccess = SetCommState(hCom, &dcb);

     if (!fSuccess) {
      // Handle the error.
       dprintf ("SetCommState failed with error %d.\n", GetLastError());
       exit (3);
       }
       
      fSuccess = GetCommTimeouts (hCom, &cto);
      
      if (!fSuccess) {
      // Handle the error.
       dprintf ("GetCommTimeouts failed with error %d.\n", GetLastError());
       exit (4);
       }

       cto.ReadIntervalTimeout = 50;
       cto.ReadTotalTimeoutConstant = 50;
       cto.ReadTotalTimeoutMultiplier = 10;
       cto.WriteTotalTimeoutConstant = 50;
       cto.WriteTotalTimeoutMultiplier = 10;
       fSuccess = SetCommTimeouts (hCom, &cto);
     
      if (!fSuccess) {
      // Handle the error.
       dprintf ("SetCommTimeouts failed with error %d.\n", GetLastError());
       exit (5);
       }
          
     dprintf ("Serial port %s successfully reconfigured.\n", pcCommPort);
     return hCom;	 

}
#endif
