  /*######################################################################################  
 ##########################################################################################
## ######################################################## ####################          ##
## ########  #######   ###      ## ########    ######   ### ####### ########  ###      ## ##
## ###    ## ###    #  ####    ### ###    ##  ###   ##  ### ###     ###    ## ####    ### ##
## ###   ### ###    ## #######  ## ###   ### ###     ## ### ###     ###   ### #######  ## ##
## #######   ######### ### ###  ## ########  ###     ## ### ####### #######   ### ###  ## ##
## ###   ### ###    ## ###  ##  ## ###   ### ###     ## ### ###     ###   ### ###  ##  ## ##
## ###    ## ###    ## ###      ## ###    ##  ###   ##  ### ###     ###    ## ###      ## ##
## ###    ## ###    ## ###      ## ########    ######   ### ####### ###    ## ###      ## ##
## #################################################### ### ############################# ##
############################################################################################
##### 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"

bool rTerm::isCMD(char inChar){

  for(int i=0; i<10; i++){
                 
    if(inChar == char(EEPROM.read(80+i))){
      return true;
    }
    
  }

  return false;

}

bool rTerm::cmd(char cmdBuff[16]){

  char _buff[80];
  
  if(cmdBuff[0] == char('!')){

    switch(cmdBuff[1]){

      case 'V':

        char _S[6];
        dtostrf(vBatt(),5,2,_S);
        
        strcpy(_buff, "Battery Voltage: ");
        strcat(_buff, _S);
        strcat(_buff, "vdc");
        
        Serial.println(_buff);
        
        rTerm::smsTx(_buff);
        
        for(int i=0; i<80; i++){ _buff[i] = char('\0'); }
        for(int i=0; i<6; i++){ _S[i] = char('\0'); }
        
      break;

      case 'M':

        Serial.println(F("Resetting EEPROM Data"));

        if(rTerm::memReset()){
          delay(500);
          rTerm::smsTx("EEPROM Data Reset");
        }else{
          delay(500);
          rTerm::smsTx("Unable to reset EEPROM Data :( ");
        }
        
      break;  

      case '?':
        
        Serial.println(F("Read EEPROM Data"));

        rTerm::memRead();
        
        rTerm::smsTx("Read EEPROM Config");
        
      break;
      
      case '0':

        Serial.println(F("Setting opMode to 0"));

        rTerm::opMode = 0;
        EEPROM.put(1, int(0));
        
        rTerm::smsTx("Setting opMode to 0");
        
      break;

      case '1':

        Serial.println(F("Setting opMode to 1"));

        rTerm::opMode = 1;
        EEPROM.put(1, int(1));
        
        rTerm::smsTx("Setting opMode to 1");
        
      break;

      case '2':

        Serial.println(F("Setting opMode to 2"));

        rTerm::opMode = 2;
        EEPROM.put(1, int(2));
        
        rTerm::smsTx("Setting opMode to 2");
        
      break;

      case '3':

        Serial.println(F("Setting opMode to 3"));

        rTerm::opMode = 3;
        EEPROM.put(1, int(3));
        
        rTerm::smsTx("Setting opMode to 3");
        
      break;

      case '4':

        Serial.println(F("Setting opMode to 4"));

        rTerm::opMode = 4;
        EEPROM.put(1, int(4));
        
        rTerm::smsTx("Setting opMode to 4");
        
      break;
        
    }
    
  }else if(cmdBuff[0] == char('#')){
    
    switch(cmdBuff[1]){

      case '>':
      
        // -- Enable SMS Notification --
          rTerm::smsEN = 1;
          EEPROM.put(7, int(1));
        
          Serial.println(F("SMS Notification Enabled."));
          rTerm::smsTx("SMS Notification Enabled.");

      break;

      case '<':
        
        // -- Disable SMS Notification --
          rTerm::smsEN = 0;
          EEPROM.write(7, int(0));

          Serial.println(F("SMS Notification Disabled."));
        
      break;

      case '0':
        
        // -- UPDATE destIndex to 0 --
          EEPROM.put(4, int(120));
          rTerm::destIndex = 120;
          
          strcpy(_buff, "destIndex updated / telNum: ");
          
          for(int i=0; i<10; i++){
            _buff[i+28] = char(EEPROM.read(rTerm::destIndex+i));
          }

          _buff[strlen(_buff)+1] = char('\0');
          
          Serial.println(_buff); delay(10);
          
          rTerm::smsTx(_buff);
  
          for(int i=0; i<80; i++){
            _buff[i] = char('\0');
          }

      break;
      
      case '1':

        // -- UPDATE destIndex to 1 --
          EEPROM.put(4, int(131));
          rTerm::destIndex = 131;
          
          strcpy(_buff, "destIndex updated / telNum: ");
          
          for(int i=0; i<10; i++){
            _buff[i+28] = char(EEPROM.read(rTerm::destIndex+i));
          }

          _buff[strlen(_buff)+1] = char('\0');
          
          Serial.println(_buff); delay(10);
          
          rTerm::smsTx(_buff);
  
          for(int i=0; i<80; i++){
            _buff[i] = char('\0');
          }

      break;

      case '2':
        
        // -- UPDATE destIndex to 2 --
          EEPROM.put(4, int(142));
          rTerm::destIndex = 142;
          
          strcpy(_buff, "destIndex updated / telNum: ");
          
          for(int i=0; i<10; i++){
            _buff[i+28] = char(EEPROM.read(rTerm::destIndex+i));
          }

          _buff[strlen(_buff)+1] = char('\0');
          
          Serial.println(_buff); delay(10);
          
          rTerm::smsTx(_buff);
  
          for(int i=0; i<80; i++){
            _buff[i] = char('\0');
          }
        
      break;
      
      case 'S':

        // -- Get GSM Signal Strength --
          rTerm::sigStrength();
          
        // -- Sending sigStrength SMS Response --
          strcpy(_buff, "Signal Quality/CSQ: ");
          strcat(_buff, rTerm::csq);
  
          Serial.println(_buff); delay(10);
          rTerm::smsTx(_buff);
  
          for(int i=0; i<80; i++){
            _buff[i] = char('\0');
          }

      break;
        
    }
    
  }else if(cmdBuff[0] == char('$')){

    switch(cmdBuff[1]){

      case '>': 
        // -- ENABLE FCP SMS EVENT NOTIFICATION --
          rTerm::procIndexFCP = rTerm::logIndexFCP;
          rTerm::smsFCP = 1;
  
          EEPROM.put(183, int(rTerm::procIndexFCP)); delay(10); // GSM EVENT INDEX
          EEPROM.put(192, int(1)); delay(10); // FCP SMS ENABLE
          
          Serial.println(F("smsFCP ENABLED")); delay(20);

          if(!rTerm::smsTx("smsFCP ENABLED")){
              Serial.println(F("cmd->smsTx(\"smsFCP ENABLED\") Timed Out"));
          }

      break;

      case '<':
        
        // -- FCP SMS NOTIFICATION SETTINGS --
          
          rTerm::smsFCP = 0;
  
          EEPROM.put(192, int(0)); // FCP SMS ENABLE
  
          Serial.println(F("smsFCP DISABLED")); delay(10);
          rTerm::smsTx("smsFCP DISABLED");

      break;

      case '^':

          strcpy(_buff, "/fcp/");
          char tempName[5];
          itoa(rTerm::logIndexFCP-1, tempName, 10);
          strcat(_buff, tempName);
          strcat(_buff, ".log");
          _buff[strlen(_buff)] = char('\0');

          rTerm::dumpLog(_buff); delay(100);

          for(int i=0; i<80; i++){
            _buff[i] = char('\0');
          }

          for(int i=0; i<5; i++){
            tempName[i] = char('\0');
          }

      break;

      case '~':
        
        // -- UPDATE lineIndex --
          EEPROM.put(15, int(cmdBuff[2]-48));
          rTerm::lineIndex = cmdBuff[2]-48;
          
          strcpy(_buff, "lineIndex->: ");
          
          _buff[13] = cmdBuff[2];
          
          _buff[14] = char('\0');
          
          Serial.println(_buff); delay(10);
          
          rTerm::smsTx(_buff);
  
          for(int i=0; i<80; i++){
            _buff[i] = char('\0');
          }
        
      break;

      case 'L':

        // -- Dump all the fcpLog files to the serial terminal. --
          rTerm::dumpLogsFCP();
          Serial.println(F("rt_cmd->dumpLogsFCP()"));
        
      break;

      case 'l':

        // -- Delete all logs and reset eventIndex. --
          rTerm::flushLogsFCP();
        
      break;

      case 'A':

        if(cmdBuff[2] == char('F')){
          Serial2.print(F("A 0")); delay(10); Serial2.print(char(13)); delay(250);
          Serial2.print(F("A 1")); delay(10); Serial2.print(char(13)); delay(250);
          rTerm::smsTx("fcpFCI -> Acknowledge");
        }else if(cmdBuff[2] == char('N')){
          Serial2.print(F("~L")); Serial2.print(char(13)); delay(250);
          rTerm::smsTx("fcpNotifier -> Acknowledge");
        }
        

      break;

      case 'R':

        if(cmdBuff[2] == char('F')){
          Serial2.print(F("R ")); Serial2.print(char(13)); delay(250);
          rTerm::smsTx("fcpFCI -> Reset");
        }else if(cmdBuff[2] == char('N')){
          Serial2.print(F("~N")); Serial2.print(char(13)); delay(250);
          rTerm::smsTx("fcpNotifier -> Reset");
        }
        
      break;

      case 'S':

        if(cmdBuff[2] == char('F')){
          Serial2.print(F("S")); Serial2.print(char(13)); delay(250);  
          rTerm::smsTx("fcpFCI -> Silence");
        }else if(cmdBuff[2] == char('N')){
          Serial2.print(F("~M")); Serial2.print(char(13)); delay(250);
          rTerm::smsTx("fcpNotifier -> Silence");
        }
        
      break;

    }

  }else if(cmdBuff[0] == char('~')){
    switch(cmdBuff[1]){
      
      case 'L':
        
        Serial.println(F("Dump CID Logs"));

        rTerm::dumpLogsCID(); delay(100);
        
        rTerm::smsTx("Dump CID Logs"); delay(100);
        
      break;

      case 'l':
        
        Serial.println(F("Flush CID Logs"));

        rTerm::flushLogsCID(); delay(100);
        
        rTerm::smsTx("FLush CID Logs"); delay(100);
        
      break;

      
      
    }

  }else if(cmdBuff[0] == char('%')){
    int c=0;
    
    _buff[c] = char('/'); c++;
    _buff[c] = char('f'); c++;
    _buff[c] = char('c'); c++;
    _buff[c] = char('p'); c++;
    _buff[c] = char('/'); c++;
    
    for(int i=1; i<5; i++){
      if(isDigit(cmdBuff[i])){
        _buff[c] = cmdBuff[i];
        c++;
      }
    }

    _buff[c] = char('.'); c++;
    _buff[c] = char('l'); c++;
    _buff[c] = char('o'); c++;
    _buff[c] = char('g'); c++;
    _buff[c] = char('\0');
    
    rTerm::dumpLog(_buff);

    c=0;
    
    for(int i=0; i<80; i++){
      _buff[i] = char('\0');
    }

  }else if(cmdBuff[0] == char('*')){

    int c=0;
    
    _buff[c] = char('/'); c++;
    _buff[c] = char('c'); c++;
    _buff[c] = char('i'); c++;
    _buff[c] = char('d'); c++;
    _buff[c] = char('/'); c++;
    
    for(int i=1; i<5; i++){
      if(isDigit(cmdBuff[i])){
        _buff[c] = cmdBuff[i];
        c++;
      }
    }

    _buff[c] = char('.'); c++;
    _buff[c] = char('l'); c++;
    _buff[c] = char('o'); c++;
    _buff[c] = char('g'); c++;
    _buff[c] = char('\0');
    
    rTerm::dumpLog(_buff);

    c=0;
    
    for(int i=0; i<80; i++){
      _buff[i] = char('\0');
    }

  }else if(cmdBuff[0] == char('<')){

  // -- FCI E3 PANEL COMMAND TO DISABLE DEVICES --
  /*
   *  DD          0        1          1          1             1          7
   *  CMD        LOOP   DEV TYPE   ADDRESS    DISABLE         NODE     ELEMENTS
   */
    int c=0;
    
    //<N1L1M33
    // -- Loop(4) Type(5) Address(6-8) Node(2)
    //         (0)S=83 (1)M=77 (2)N=76
    
    if(isDigit(cmdBuff[2]) && isDigit(cmdBuff[4]) && isDigit(cmdBuff[6])){
      
      _buff[c] = char('D'); c++;
      _buff[c] = char('D'); c++;
      _buff[c] = char(' '); c++;
      _buff[c] = cmdBuff[4]-1; c++;
      _buff[c] = char(' '); c++;
      
      if(cmdBuff[5] == char('S')){
        _buff[c] = char('0'); c++;
      }else if(cmdBuff[5] == char('M')){
        _buff[c] = char('1'); c++;
      }else if(cmdBuff[5] == char('N')){
        _buff[c] = char('2'); c++;
      }else{
        _buff[c] = char('1'); c++;
      }

      _buff[c] = char(' '); c++;
      
      _buff[c] = cmdBuff[6]; c++; // 1st digit of address

      if(isDigit(cmdBuff[7])){ _buff[c] = cmdBuff[7]; c++; } // 2nd digit of address
      
      if(isDigit(cmdBuff[8])){ _buff[c] = cmdBuff[8]; c++; } // 3rd digit of address

      _buff[c] = char(' '); c++;
      
      _buff[c] = char('1'); c++; // DISABLE = 1

      _buff[c] = char(' '); c++;
      
      _buff[c] = cmdBuff[2]; c++;

      _buff[c] = char(' '); c++;
      
      _buff[c] = char('7');  c++; // ELEMENTS 7 = ALL

      _buff[c] = char('\r'); c++;
      
      _buff[c] = char('\0');

      Serial2.print(_buff); delay(20);
      rTerm::smsTx("cmd->fcp Disable SENS/MOD/NAC"); delay(100);

      for(int i=0; i<80; i++){
        _buff[i] = char('\0');
      }
      
    }else{
      rTerm::smsTx("Received invalid disable command"); delay(100);
      for(int i=0; i<80; i++){
        _buff[i] = char('\0');
      }
    }
    

  }else if(cmdBuff[0] == char('>')){

  // -- FCI E3 PANEL COMMAND TO DISABLE DEVICES --
  /*
   *  DD          0        1          1          1             1          7
   *  CMD        LOOP   DEV TYPE   ADDRESS    DISABLE         NODE     ELEMENTS
   */
    int c=0;
    
    //<N1L1M33
    // -- Loop(4) Type(5) Address(6-8) Node(2)
    //         (0)S=83 (1)M=77 (2)N=76
    
    if(isDigit(cmdBuff[2]) && isDigit(cmdBuff[4]) && isDigit(cmdBuff[6])){
      
      _buff[c] = char('D'); c++;
      _buff[c] = char('D'); c++;
      _buff[c] = char(' '); c++;
      _buff[c] = cmdBuff[4]-1; c++;
      _buff[c] = char(' '); c++;
      
      if(cmdBuff[5] == char('S')){
        _buff[c] = char('0'); c++;
      }else if(cmdBuff[5] == char('M')){
        _buff[c] = char('1'); c++;
      }else if(cmdBuff[5] == char('N')){
        _buff[c] = char('2'); c++;
      }else{
        _buff[c] = char('1'); c++;
      }

      _buff[c] = char(' '); c++;
      
      _buff[c] = cmdBuff[6]; c++; // 1st digit of address

      if(isDigit(cmdBuff[7])){ _buff[c] = cmdBuff[7]; c++; } // 2nd digit of address
      
      if(isDigit(cmdBuff[8])){ _buff[c] = cmdBuff[8]; c++; } // 3rd digit of address

      _buff[c] = char(' '); c++;
      
      _buff[c] = char('0'); c++; // ENABLE = 0 DISABLE = 1

      _buff[c] = char(' '); c++;
      
      _buff[c] = cmdBuff[2]; c++;

      _buff[c] = char(' '); c++;
      
      _buff[c] = char('7');  c++; // ELEMENTS 7 = ALL

      _buff[c] = char('\r'); c++;
      
      _buff[c] = char('\0');

      Serial2.print(_buff); delay(20);
      rTerm::smsTx("cmd->fcp Enable SENS/MOD/NAC"); delay(100);

      for(int i=0; i<80; i++){
        _buff[i] = char('\0');
      }
      
    }else{
      rTerm::smsTx("Received invalid disable command"); delay(100);
      for(int i=0; i<80; i++){
        _buff[i] = char('\0');
      }
    }
    

  }
  
}
