  /*######################################################################################  
 ##########################################################################################
## ######################################################## ####################          ##
## ########  #######   ###      ## ########    ######   ### ####### ########  ###      ## ##
## ###    ## ###    #  ####    ### ###    ##  ###   ##  ### ###     ###    ## ####    ### ##
## ###   ### ###    ## #######  ## ###   ### ###     ## ### ###     ###   ### #######  ## ##
## #######   ######### ### ###  ## ########  ###     ## ### ####### #######   ### ###  ## ##
## ###   ### ###    ## ###  ##  ## ###   ### ###     ## ### ###     ###   ### ###  ##  ## ##
## ###    ## ###    ## ###      ## ###    ##  ###   ##  ### ###     ###    ## ###      ## ##
## ###    ## ###    ## ###      ## ########    ######   ### ####### ###    ## ###      ## ##
## #################################################### ### ############################# ##
############################################################################################
##### CURRENT / ramboTerm 2.2_ino / 04-04-2020                                            ##
##### ramboTerm: CLI Tool-set for fire alarm interfacing and communications.              ##
##### Matthew Stroble / matthewstroble@gmail.com / firealarmhackery.com                   ##
 ##                                                                                      ##
  ######################################################################################*/


#include <SPI.h>
#include <SD.h>
#include "Wire.h"
#include "EEPROM.h"

#include "rTerm.h"

char rTerm::sigStrength(){

  for(int i=0; i<3; i++){
    rTerm::csq[i] = char('\0');
  }

  Serial1.println("AT+CSQ");

  delay(20);

  while(Serial1.available()){

    if(char(Serial1.read()) == char(':') && char(Serial1.peek()) == char(32)){

      Serial1.read(); // Burn through the SPACE character
      
      for(int i=0; i<2; i++){
        
        if(isDigit(char(Serial1.peek()))){

          rTerm::csq[i] = char(Serial1.read());

        }
        
      }

      Serial.print(F("CSQ: ")); Serial.println(rTerm::csq); delay(10);

      return rTerm::csq;

    }
    
  }
    
}

// -- GSM RX With Parse Options --

  bool rTerm::gsmRx(int rxParse){
  
    delay(50);
    
    if(Serial1.available()){
      
      rTerm::loopIndex = 0;
      
      while(Serial1.available()){
        
        if(!rxParse){
          Serial.write(Serial1.read());
        }

        if(rxParse == 0){
          Serial.write(Serial1.read());
        }
        
        if(rxParse == 1){
          
          char inChar = char(Serial1.read());
    
          if(inChar == char(Serial1.peek())){
    
            if(isCMD(inChar)){
    
              char cmdBuff[15];
              Serial1.readBytesUntil(char(';'), cmdBuff, 13);           
              cmdBuff[strlen(cmdBuff)] = char('\0');
      
              rTerm::cmd(cmdBuff);
              
              return true;
          
            }
            
          }
          
        }

        if(rxParse == 2){

          char inChar = char(Serial1.read());

          if(inChar == char(10) && char(Serial1.peek()) == char('O')){

            Serial.print(inChar);

            for(int i=0; i<Serial1.available(); i++){
              Serial.write(Serial1.read());
            }
            
            return true;
        
          }else{

            Serial.print(inChar);
            
          }
          
        }
        
      }
    
    }else{
      return false;
    }
    
  }

bool rTerm::smsTx(char inData[120]){

  if(rTerm::smsEN > 0){

    delay(100);
    
    Serial1.println(F("AT+CMGF=1")); delay(100);
    
    rTerm::gsmRx(0);
    
    Serial1.print(F("AT+CMGS=\"+01"));

    for(int i=0; i<10; i++){
      Serial1.write(EEPROM.read(rTerm::destIndex+i));
    }
    
    Serial1.println(F("\"")); delay(10);
    
    rTerm::gsmRx(0);

    Serial1.print(inData);
      
    delay(10);
    
    Serial1.print(char(26));
    
    long timeout = millis();

    while(millis() - timeout < 3500){

      if(rTerm::gsmRx(2)){
        // GSM Returned OK
        return true;
      }

    }

    return false;
      
  }else{

    return false;
    
  }
  
}

void rTerm::procLogFCP(){

  if(rTerm::logIndexFCP > rTerm::procIndexFCP){
    
    char logPath[15];
    char logName[5];
    itoa(rTerm::procIndexFCP, logName, 10);
    strcpy(logPath, "/fcp/");
    strcat(logPath, logName);
    strcat(logPath, ".log");
    logPath[strlen(logPath)] = char('\0');
    
    File fcpLog = SD.open(logPath, FILE_READ);
  
    if(!fcpLog){
      
      Serial.print(F("Unable to open file path: ")); Serial.println(logPath); delay(10);
      return;
      
    }else{

      char _buff[160];
      strcpy(_buff, "fcp(");
      strcat(_buff, logName);
      strcat(_buff, "): ");
      int c = strlen(_buff);
      
      while(fcpLog.available() && c < 158){

        if(strlen(_buff) > 150){ break; }
        
        char inChar = char(fcpLog.read());

        if(inChar == char(32) && inChar == char(fcpLog.peek())){
          // Skip whitespace  
        }else if(inChar == char(13)){
          // Skip CR Chars
        }else if(inChar == char(10)){
          _buff[c] = char(' '); c++;
          _buff[c] = char('\0');
        }else if(isAlphaNumeric(inChar) || inChar == char(32) || isPunct(inChar)){
          _buff[c] = inChar; c++;
          _buff[c] = char('\0');
        }else{
          // Skip all other eronious chars.
        }
      
      }

      fcpLog.close(); delay(10);
  
      rTerm::smsTx(_buff); delay(200);

      for(int i=0; i<160; i++){
        _buff[i] = char('\0');
      }

      rTerm::procIndexFCP++;
      EEPROM.put(183, int(rTerm::procIndexFCP)); delay(100);

    }

  }
  
}

void rTerm::procLogCID(){

  if(rTerm::logIndexCID > rTerm::procIndexCID){

    char logPath[18];
    char logName[5];
    
    itoa(rTerm::procIndexCID, logName, 10);
    strcpy(logPath, "/cid/");
    strcat(logPath, logName);
    strcat(logPath, ".log");
    
    File cidEvent = SD.open(logPath, FILE_READ); delay(10);
    
    if(!cidEvent){
      
      Serial.print(F("Unable to open: ")); Serial.println(logPath); delay(20);
      return;
      
    }else{

      char _buff[40];
      int cx=0;

      while(cidEvent.available()){
        if(cx < 40){
          _buff[cx] = cidEvent.read(); cx++;
          _buff[cx] = char('\0');
        }else{
          break;
        }
      }
      
      cidEvent.close(); delay(20);

      //Serial.println(_buff); delay(20);
      
      rTerm::smsTx(_buff); delay(200);

      for(int i=0; i<40; i++){
        _buff[i] = char('\0');
      }
      
      rTerm::procIndexCID++;
      
      EEPROM.put(189, int(rTerm::procIndexCID)); delay(100);
      
    }

  }
  
}
