any mbed board with 1 Harware uart for SIM800 and SIM900 MQTT

Dependents:   Nucleo_mqtt_sim800_final _serial_farfan

GSM_MQTT.cpp

Committer:
rcele_85
Date:
2018-04-17
Revision:
0:e7957e1745cb

File content as of revision 0:e7957e1745cb:

/* =========================================================================================
*                     GSM_MQTT == MQTT CLIENT LIBRARY FOR GPRS MODEM
* SUPPORTED GPRS MODEM ==> SIM800, SIM900, SIM300
* SUPPORTED MBED HARDWARE ==> Any hardware with two Hardware Serial port and 1 timer
*
* Developed By : Ravi Butani
* Prof. Marwadi University, Rajkkot-INDIA
* Contact: ravi_butani@yahoo.com
*
* License : This library released under CC-BY-SA 4.0 license
* https://creativecommons.org/licenses/by-sa/4.0/legalcode.txt
*
* This library is derived from Arduino MQTT Client for SIM800 at 
* https://github.com/elementzonline/SIM800_MQTT
*============================================================================================*/


#include "GSM_MQTT.h"
#include "mbed.h"
#include <stdint.h>
#include <string>
#define ESP_RXBUF_LEN 300

volatile char esp_buf[ESP_RXBUF_LEN]; // Circular Buffer for Serial Receive As MODSERIAL not supported in GRPeach 
volatile uint32_t  esp_pos = 0, esp_por = 0, esp_ok = 0, esp_head = 0; // Variable used for hold head and tail of Circular Buffer

Timer timer800;
extern uint8_t GSM_Response;

extern string MQTT_HOST;// = "test.mosquitto.org";
extern string MQTT_PORT;// = "1883";
extern Serial SerialDBG;
extern Serial Serial800;
extern GSM_MQTT MQTT;
uint8_t GSM_Response = 0;
unsigned long previousMillis = 0;
//char inputString[UART_BUFFER_LENGTH];         // a string to hold incoming data
bool stringComplete = false;  // whether the string is complete



// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART returns how many chars available to read <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
int Serial800_available(void)
{
    return ((ESP_RXBUF_LEN + esp_pos - esp_por) % ESP_RXBUF_LEN);    
}


// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART returns read one char <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
char Serial800_read(void)
{
    char c = esp_buf[esp_por];
    esp_por = (esp_por + 1)% ESP_RXBUF_LEN;
    return(c);
}

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART Flush receive Buffer <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
void Serial800_flush(void)
{
    esp_pos = 0; 
    esp_por = 0;   
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART Receive CallBack(ISR) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
void Serial800_callback() {
    esp_buf[esp_pos] = Serial800.getc();
    esp_pos = (esp_pos+1)% ESP_RXBUF_LEN;
}
void serialEvent();

GSM_MQTT::GSM_MQTT(unsigned long KeepAlive)
{
  _KeepAliveTimeOut = KeepAlive;
}

void GSM_MQTT::begin(void)
{
    TCP_Flag = false;
    GSM_ReplyFlag;
    pingFlag = false;
    tcpATerrorcount = 0;
    MQTT_Flag = false;
    ConnectionAcknowledgement = NO_ACKNOWLEDGEMENT ;
    PublishIndex = 0;
    TopicLength = 0;
    MessageLength = 0;
    MessageFlag = false;
    modemStatus = 0;
    index = 0;
    length = 0;
    lengthLocal = 0;
    _LastMessaseID = 0;
    _ProtocolVersion = 3;
    _PingPrevMillis = 0;
    _tcpStatus = 0;
    _tcpStatusPrev = 0;
    _KeepAliveTimeOut;
  SerialDBG.baud(9600);
  Serial800.baud(9600);
  Serial800.attach(&Serial800_callback);
  Serial800.printf("AT\r\n");
  timer800.start();
  wait(1);
  _tcpInit();
}
char GSM_MQTT::_sendAT(char *command, unsigned long waitms)
{

  unsigned long PrevMillis = timer800.read_ms();
  strcpy(reply, "none");
  GSM_Response = 0;
  Serial800.printf("%s",command);
  unsigned long currentMillis = timer800.read_ms();
  //  SerialDBG.println(PrevMillis);
  //  SerialDBG.println(currentMillis);
  while ( (GSM_Response == 0) && ((currentMillis - PrevMillis) < waitms) )
  {
    //    delay(1);
    serialEvent();
    currentMillis = timer800.read_ms();
  }
  return GSM_Response;
}
char GSM_MQTT::sendATreply(char *command, char *replystr, unsigned long waitms)
{
  strcpy(reply, replystr);
  unsigned long PrevMillis = timer800.read_ms();
  GSM_ReplyFlag = 0;
  Serial800.printf("%s",command);
  unsigned long currentMillis =timer800.read_ms();

  //  SerialDBG.println(PrevMillis);
  //  SerialDBG.println(currentMillis);
  while ( (GSM_ReplyFlag == 0) && ((currentMillis - PrevMillis) < waitms) )
  {
    //    delay(1);
    serialEvent();
    currentMillis = timer800.read_ms();
  }
  return GSM_ReplyFlag;
}
void GSM_MQTT::_tcpInit(void)
{
  switch (modemStatus)
  {
    case 0:
      {
        wait(1);
        Serial800.printf("+++");
        wait(0.5);
        if (_sendAT("AT\r\n", 5000) == 1)
        {
          modemStatus = 1;
        }
        else
        {
          modemStatus = 0;
          break;
        }
      }
    case 1:
      {
        if (_sendAT("ATE1\r\n", 2000) == 1)
        {
          modemStatus = 2;
        }
        else
        {
          modemStatus = 1;
          break;
        }
      }
    case 2:
      {
        if (sendATreply("AT+CREG?\r\n", "0,1", 5000) == 1)
        {
          _sendAT("AT+CIPMUX=0\r\n", 2000);
          _sendAT("AT+CIPMODE=1\r\n", 2000);
          if (sendATreply("AT+CGATT?\r\n", ": 1", 4000) != 1)
          {
            _sendAT("AT+CGATT=1\r\n", 2000);
          }
          modemStatus = 3;
          _tcpStatus = 2;
        }
        else
        {
          modemStatus = 2;
          break;
        }
      }
    case 3:
      {
        if (GSM_ReplyFlag != 7)
        {
          _tcpStatus = sendATreply("AT+CIPSTATUS\r\n", "STATE", 4000);
          if (_tcpStatusPrev == _tcpStatus)
          {
            tcpATerrorcount++;
            if (tcpATerrorcount >= 10)
            {
              tcpATerrorcount = 0;
              _tcpStatus = 7;
            }

          }
          else
          {
            _tcpStatusPrev = _tcpStatus;
            tcpATerrorcount = 0;
          }
        }
        _tcpStatusPrev = _tcpStatus;
        SerialDBG.printf("%d",_tcpStatus);
        switch (_tcpStatus)
        {
          case 2:
            {
              _sendAT("AT+CSTT=\"www\"\r\n", 5000);
              break;
            }
          case 3:
            {
              _sendAT("AT+CIICR\r\n", 5000)  ;
              break;
            }
          case 4:
            {
              sendATreply("AT+CIFSR\r\n", ".", 4000) ;
              break;
            }
          case 5:
            {
              Serial800.printf("AT+CIPSTART=\"TCP\",\"");
              Serial800.printf("%s",MQTT_HOST);
              Serial800.printf("\",\"");
              Serial800.printf("%s",MQTT_PORT);
              if (_sendAT("\"\r\n", 5000) == 1)
              {
                unsigned long PrevMillis = timer800.read_ms();
                unsigned long currentMillis = timer800.read_ms();
                while ( (GSM_Response != 4) && ((currentMillis - PrevMillis) < 20000) )
                {
                  //    delay(1);
                  serialEvent();
                  currentMillis = timer800.read_ms();
                }
              }
              break;
            }
          case 6:
            {
              unsigned long PrevMillis =timer800.read_ms();
              unsigned long currentMillis = timer800.read_ms();
              while ( (GSM_Response != 4) && ((currentMillis - PrevMillis) < 20000) )
              {
                //    delay(1);
                serialEvent();
                currentMillis = timer800.read_ms();
              }
              break;
            }
          case 7:
            {
              sendATreply("AT+CIPSHUT\r\n", "OK", 4000) ;
              modemStatus = 0;
              _tcpStatus = 2;
              break;
            }
        }
      }
  }

}

void GSM_MQTT::_ping(void)
{

  if (pingFlag == true)
  {
    unsigned long currentMillis = timer800.read_ms();
    if ((currentMillis - _PingPrevMillis ) >= _KeepAliveTimeOut * 1000)
    {
      // save the last time you blinked the LED
      _PingPrevMillis = currentMillis;
      Serial800.putc(char(PINGREQ * 16));
      _sendLength(0);
    }
  }
}
void GSM_MQTT::_sendUTFString(char *string1)
{
  int localLength = strlen(string1);
  Serial800.putc(char(localLength / 256));
  Serial800.putc(char(localLength % 256));
  Serial800.printf("%s",string1);
}
void GSM_MQTT::_sendLength(int len)
{
  bool  length_flag = false;
  while (length_flag == false)
  {
    if ((len / 128) > 0)
    {
      Serial800.putc(char(len % 128 + 128));
      len /= 128;
    }
    else
    {
      length_flag = true;
      Serial800.putc(char(len));
    }
  }
}
//void GSM_MQTT::connect(char *ClientIdentifier, char UserNameFlag = 0, char PasswordFlag = 0, char *UserName = "", char *Password = "", char CleanSession = 1, char WillFlag = 0, char WillQoS = 0, char WillRetain = 0, char *WillTopic = "", char *WillMessage = "")
void GSM_MQTT::connect(char *ClientIdentifier, char UserNameFlag, char PasswordFlag, char *UserName, char *Password, char CleanSession, char WillFlag, char WillQoS, char WillRetain, char *WillTopic, char *WillMessage)
{
  //SerialDBG.printf("in connect\r\n");
  ConnectionAcknowledgement = NO_ACKNOWLEDGEMENT ;
  Serial800.putc(char(CONNECT * 16 ));
  char ProtocolName[7] = "MQIsdp";
  int localLength = (2 + strlen(ProtocolName)) + 1 + 3 + (2 + strlen(ClientIdentifier));
  if (WillFlag != 0)
  {
    localLength = localLength + 2 + strlen(WillTopic) + 2 + strlen(WillMessage);
  }
  if (UserNameFlag != 0)
  {
    localLength = localLength + 2 + strlen(UserName);

    if (PasswordFlag != 0)
    {
      localLength = localLength + 2 + strlen(Password);
    }
  }
  _sendLength(localLength);
  _sendUTFString(ProtocolName);
  Serial800.putc(char(_ProtocolVersion));
  Serial800.putc(char(UserNameFlag * User_Name_Flag_Mask + PasswordFlag * Password_Flag_Mask + WillRetain * Will_Retain_Mask + WillQoS * Will_QoS_Scale + WillFlag * Will_Flag_Mask + CleanSession * Clean_Session_Mask));
  Serial800.putc(char(_KeepAliveTimeOut / 256));
  Serial800.putc(char(_KeepAliveTimeOut % 256));
  _sendUTFString(ClientIdentifier);
  if (WillFlag != 0)
  {
    _sendUTFString(WillTopic);
    _sendUTFString(WillMessage);
  }
  if (UserNameFlag != 0)
  {
    _sendUTFString(UserName);
    if (PasswordFlag != 0)
    {
      _sendUTFString(Password);
    }
  }
}
void GSM_MQTT::publish( char *Topic, char *Message, char DUP, char Qos, char RETAIN, unsigned int MessageID)
{
  Serial800.putc(char(PUBLISH * 16 + DUP * DUP_Mask + Qos * QoS_Scale + RETAIN));
  int localLength = (2 + strlen(Topic));
  if (Qos > 0)
  {
    localLength += 2;
  }
  localLength += strlen(Message);
  _sendLength(localLength);
  _sendUTFString(Topic);
  if (Qos > 0)
  {
    Serial800.putc(char(MessageID / 256));
    Serial800.putc(char(MessageID % 256));
  }
  Serial800.printf("%s",Message);
}
void GSM_MQTT::publishACK(unsigned int MessageID)
{
  Serial800.putc(char(PUBACK * 16));
  _sendLength(2);
  Serial800.putc(char(MessageID / 256));
  Serial800.putc(char(MessageID % 256));
}
void GSM_MQTT::publishREC(unsigned int MessageID)
{
  Serial800.putc(char(PUBREC * 16));
  _sendLength(2);
  Serial800.putc(char(MessageID / 256));
  Serial800.putc(char(MessageID % 256));
}
void GSM_MQTT::publishREL(char DUP, unsigned int MessageID)
{
  Serial800.putc(char(PUBREL * 16 + DUP * DUP_Mask + 1 * QoS_Scale));
  _sendLength(2);
  Serial800.putc(char(MessageID / 256));
  Serial800.putc(char(MessageID % 256));
}

void GSM_MQTT::publishCOMP(unsigned int MessageID)
{
  Serial800.putc(char(PUBCOMP * 16));
  _sendLength(2);
  Serial800.putc(char(MessageID / 256));
  Serial800.putc(char(MessageID % 256));
}
void GSM_MQTT::subscribe(char *SubTopic, char DUP, unsigned int MessageID, char SubQoS)
{
  Serial800.putc(char(SUBSCRIBE * 16 + DUP * DUP_Mask + 1 * QoS_Scale));
  int localLength = 2 + (2 + strlen(SubTopic)) + 1;
  _sendLength(localLength);
  Serial800.putc(char(MessageID / 256));
  Serial800.putc(char(MessageID % 256));
  _sendUTFString(SubTopic);
  Serial800.putc(SubQoS);

}
void GSM_MQTT::unsubscribe( char *SubTopic, char DUP, unsigned int MessageID)
{
  Serial800.putc(char(UNSUBSCRIBE * 16 + DUP * DUP_Mask + 1 * QoS_Scale));
  int localLength = (2 + strlen(SubTopic)) + 2;
  _sendLength(localLength);

  Serial800.putc(char(MessageID / 256));
  Serial800.putc(char(MessageID % 256));

  _sendUTFString(SubTopic);
}
void GSM_MQTT::disconnect(void)
{
  Serial800.putc(char(DISCONNECT * 16));
  _sendLength(0);
  pingFlag = false;
}
//Messages
const char CONNECTMessage[] = "Client request to connect to Server\r\n";
const char CONNACKMessage[]  = "Connect Acknowledgment\r\n";
const char PUBLISHMessage[]   = "Publish message\r\n";
const char PUBACKMessage[]  = "Publish Acknowledgment\r\n";
const char PUBRECMessage[]  = "Publish Received (assured delivery part 1)\r\n";
const char PUBRELMessage[]  = "Publish Release (assured delivery part 2)\r\n";
const char PUBCOMPMessage[]   = "Publish Complete (assured delivery part 3)\r\n";
const char SUBSCRIBEMessage[]   = "Client Subscribe request\r\n";
const char SUBACKMessage[]  = "Subscribe Acknowledgment\r\n";
const char UNSUBSCRIBEMessage[]   = "Client Unsubscribe request\r\n";
const char UNSUBACKMessage[]   = "Unsubscribe Acknowledgment\r\n";
const char PINGREQMessage[]  = "PING Request\r\n";
const char PINGRESPMessage[]  = "PING Response\r\n";
const char DISCONNECTMessage[]  = "Client is Disconnecting\r\n";

void GSM_MQTT::printMessageType(uint8_t Message)
{
  switch (Message)
  {
    case CONNECT:
      {
        SerialDBG.printf("%s",CONNECTMessage);
        break;
      }
    case CONNACK:
      {
        SerialDBG.printf("%s",CONNACKMessage);
        break;
      }
    case PUBLISH:
      {
        SerialDBG.printf("%s",PUBLISHMessage);
        break;
      }
    case PUBACK:
      {
        SerialDBG.printf("%s",PUBACKMessage);
        break;
      }
    case  PUBREC:
      {
        SerialDBG.printf("%s",PUBRECMessage);
        break;
      }
    case PUBREL:
      {
        SerialDBG.printf("%s",PUBRELMessage);
        break;
      }
    case PUBCOMP:
      {
        SerialDBG.printf("%s",PUBCOMPMessage);
        break;
      }
    case SUBSCRIBE:
      {
        SerialDBG.printf("%s",SUBSCRIBEMessage);
        break;
      }
    case SUBACK:
      {
        SerialDBG.printf("%s",SUBACKMessage);
        break;
      }
    case UNSUBSCRIBE:
      {
        SerialDBG.printf("%s",UNSUBSCRIBEMessage);
        break;
      }
    case UNSUBACK:
      {
        SerialDBG.printf("%s",UNSUBACKMessage);
        break;
      }
    case PINGREQ:
      {
        SerialDBG.printf("%s",PINGREQMessage);
        break;
      }
    case PINGRESP:
      {
        SerialDBG.printf("%s",PINGRESPMessage);
        break;
      }
    case DISCONNECT:
      {
        SerialDBG.printf("%s",DISCONNECTMessage);
        break;
      }
  }
}

//Connect Ack
const char ConnectAck0[]   = "Connection Accepted\r\n";
const char ConnectAck1[]   = "Connection Refused: unacceptable protocol version\r\n";
const char ConnectAck2[]   = "Connection Refused: identifier rejected\r\n";
const char ConnectAck3[]   = "Connection Refused: server unavailable\r\n";
const char ConnectAck4[]   = "Connection Refused: bad user name or password\r\n";
const char ConnectAck5[]   = "Connection Refused: not authorized\r\n";
void GSM_MQTT::printConnectAck(uint8_t Ack)
{
  switch (Ack)
  {
    case 0:
      {
        SerialDBG.printf("%s",ConnectAck0);
        break;
      }
    case 1:
      {
        SerialDBG.printf("%s",ConnectAck1);
        break;
      }
    case 2:
      {
        SerialDBG.printf("%s",ConnectAck2);
        break;
      }
    case 3:
      {
        SerialDBG.printf("%s",ConnectAck3);
        break;
      }
    case 4:
      {
        SerialDBG.printf("%s",ConnectAck4);
        break;
      }
    case 5:
      {
        SerialDBG.printf("%s",ConnectAck5);
        break;
      }
  }
}
unsigned int GSM_MQTT::_generateMessageID(void)
{
  if (_LastMessaseID < 65535)
  {
    return ++_LastMessaseID;
  }
  else
  {
    _LastMessaseID = 0;
    return _LastMessaseID;
  }
}
void GSM_MQTT::processing(void)
{
  serialEvent();
  if (TCP_Flag == false)
  {
    MQTT_Flag = false;
    _tcpInit();
  }
  _ping();
}
bool GSM_MQTT::available(void)
{
  return MQTT_Flag;
}
void serialEvent()
{
//SerialDBG.printf("in serevent\r\n");
  while (Serial800_available())
  {
    char inChar = (char)Serial800_read();
    if (MQTT.TCP_Flag == false)
    {
      if (MQTT.index < 200)
      {
        MQTT.inputString[MQTT.index++] = inChar;
      }
      if (inChar == '\n')
      {
        MQTT.inputString[MQTT.index] = 0;
        stringComplete = true;
        SerialDBG.printf("%s",MQTT.inputString);
        if (strstr(MQTT.inputString, MQTT.reply) != NULL)
        {
          MQTT.GSM_ReplyFlag = 1;
          if (strstr(MQTT.inputString, " INITIAL") != 0)
          {
            MQTT.GSM_ReplyFlag = 2; //
          }
          else if (strstr(MQTT.inputString, " START") != 0)
          {
            MQTT.GSM_ReplyFlag = 3; //
          }
          else if (strstr(MQTT.inputString, "IP CONFIG") != 0)
          {
            wait(0.0000010);
            MQTT.GSM_ReplyFlag = 4;
          }
          else if (strstr(MQTT.inputString, " GPRSACT") != 0)
          {
            MQTT.GSM_ReplyFlag = 4; //
          }
          else if ((strstr(MQTT.inputString, " STATUS") != 0) || (strstr(MQTT.inputString, "TCP CLOSED") != 0))
          {
            MQTT.GSM_ReplyFlag = 5; //
          }
          else if (strstr(MQTT.inputString, " TCP CONNECTING") != 0)
          {
            MQTT.GSM_ReplyFlag = 6; //
          }
          else if ((strstr(MQTT.inputString, " CONNECT OK") != 0) || (strstr(MQTT.inputString, "CONNECT FAIL") != NULL) || (strstr(MQTT.inputString, "PDP DEACT") != 0))
          {
            MQTT.GSM_ReplyFlag = 7;
          }
        }
        else if (strstr(MQTT.inputString, "OK") != NULL)
        {
          GSM_Response = 1;
        }
        else if (strstr(MQTT.inputString, "ERROR") != NULL)
        {
          GSM_Response = 2;
        }
        else if (strstr(MQTT.inputString, ".") != NULL)
        {
          GSM_Response = 3;
        }
        else if (strstr(MQTT.inputString, "CONNECT FAIL") != NULL)
        {
          GSM_Response = 5;
        }
        else if (strstr(MQTT.inputString, "CONNECT") != NULL)
        {
          GSM_Response = 4;
          MQTT.TCP_Flag = true;
          SerialDBG.printf("MQTT.TCP_Flag = True\r\n");
          //SerialDBG.printf("going to auto connect\r\n");
          MQTT.AutoConnect();
          //SerialDBG.printf("out of auto connect\r\n");
          MQTT.pingFlag = true;
          MQTT.tcpATerrorcount = 0;
        }
        else if (strstr(MQTT.inputString, "CLOSED") != NULL)
        {
          GSM_Response = 4;
          MQTT.TCP_Flag = false;
          MQTT.MQTT_Flag = false;
        }
        MQTT.index = 0;
        MQTT.inputString[0] = 0;
      }
    }
    else
    {
      uint8_t ReceivedMessageType = (inChar / 16) & 0x0F;
      uint8_t DUP = (inChar & DUP_Mask) / DUP_Mask;
      uint8_t QoS = (inChar & QoS_Mask) / QoS_Scale;
      uint8_t RETAIN = (inChar & RETAIN_Mask);
      if ((ReceivedMessageType >= CONNECT) && (ReceivedMessageType <= DISCONNECT))
      {
        bool NextLengthByte = true;
        MQTT.length = 0;
        MQTT.lengthLocal = 0;
        uint32_t multiplier=1;
        wait(0.002);
        char Cchar = inChar;
        while ( (NextLengthByte == true) && (MQTT.TCP_Flag == true))
        {
          if (Serial800_available()>0)
          {
            inChar = (char)Serial800_read();
            SerialDBG.printf("%d\r\n",inChar);
            if ((((Cchar & 0xFF) == 'C') && ((inChar & 0xFF) == 'L') && (MQTT.length == 0)) || (((Cchar & 0xFF) == '+') && ((inChar & 0xFF) == 'P') && (MQTT.length == 0)))
            {
              MQTT.index = 0;
              MQTT.inputString[MQTT.index++] = Cchar;
              MQTT.inputString[MQTT.index++] = inChar;
              MQTT.TCP_Flag = false;
              MQTT.MQTT_Flag = false;
              MQTT.pingFlag = false;
              SerialDBG.printf("Disconnecting\r\n");
            }
            else
            {
              if ((inChar & 128) == 128)
              {
                MQTT.length += (inChar & 127) *  multiplier;
                multiplier *= 128;
                SerialDBG.printf("More\r\n");
              }
              else
              {
                NextLengthByte = false;
                MQTT.length += (inChar & 127) *  multiplier;
                multiplier *= 128;
              }
            }
          }
        }
        MQTT.lengthLocal = MQTT.length;
        SerialDBG.printf("%d\r\n",MQTT.length);
        if (MQTT.TCP_Flag == true)
        {
          MQTT.printMessageType(ReceivedMessageType);
          MQTT.index = 0L;
          uint32_t a = 0;
          while ((MQTT.length-- > 0) && (Serial800_available()>0))
          {
            MQTT.inputString[uint32_t(MQTT.index++)] = (char)Serial800_read();

            wait(0.001);

          }
          SerialDBG.printf("\r\n");
          if (ReceivedMessageType == CONNACK)
          {
            MQTT.ConnectionAcknowledgement = MQTT.inputString[0] * 256 + MQTT.inputString[1];
            if (MQTT.ConnectionAcknowledgement == 0)
            {
              MQTT.MQTT_Flag = true;
              MQTT.OnConnect();

            }

            MQTT.printConnectAck(MQTT.ConnectionAcknowledgement);
            // MQTT.OnConnect();
          }
          else if (ReceivedMessageType == PUBLISH)
          {
            uint32_t TopicLength = (MQTT.inputString[0]) * 256 + (MQTT.inputString[1]);
            SerialDBG.printf("Topic : '");
            MQTT.PublishIndex = 0;
            for (uint32_t iter = 2; iter < TopicLength + 2; iter++)
            {
              SerialDBG.putc(MQTT.inputString[iter]);
              MQTT.Topic[MQTT.PublishIndex++] = MQTT.inputString[iter];
            }
            MQTT.Topic[MQTT.PublishIndex] = 0;
            SerialDBG.printf("' Message :'");
            MQTT.TopicLength = MQTT.PublishIndex;

            MQTT.PublishIndex = 0;
            uint32_t MessageSTART = TopicLength + 2UL;
            int MessageID = 0;
            if (QoS != 0)
            {
              MessageSTART += 2;
              MessageID = MQTT.inputString[TopicLength + 2UL] * 256 + MQTT.inputString[TopicLength + 3UL];
            }
            for (uint32_t iter = (MessageSTART); iter < (MQTT.lengthLocal); iter++)
            {
              SerialDBG.putc(MQTT.inputString[iter]);
              MQTT.Message[MQTT.PublishIndex++] = MQTT.inputString[iter];
            }
            MQTT.Message[MQTT.PublishIndex] = 0;
            SerialDBG.printf("'\r\n");
            MQTT.MessageLength = MQTT.PublishIndex;
            if (QoS == 1)
            {
              MQTT.publishACK(MessageID);
            }
            else if (QoS == 2)
            {
              MQTT.publishREC(MessageID);
            }
            MQTT.OnMessage(MQTT.Topic, MQTT.TopicLength, MQTT.Message, MQTT.MessageLength);
            MQTT.MessageFlag = true;
          }
          else if (ReceivedMessageType == PUBREC)
          {
            SerialDBG.printf("Message ID :");
            MQTT.publishREL(0, MQTT.inputString[0] * 256 + MQTT.inputString[1]) ;
            SerialDBG.printf("%d",MQTT.inputString[0] * 256 + MQTT.inputString[1]) ;

          }
          else if (ReceivedMessageType == PUBREL)
          {
            SerialDBG.printf("Message ID :");
            MQTT.publishCOMP(MQTT.inputString[0] * 256 + MQTT.inputString[1]) ;
            SerialDBG.printf("%d\r\n",MQTT.inputString[0] * 256 + MQTT.inputString[1]) ;

          }
          else if ((ReceivedMessageType == PUBACK) || (ReceivedMessageType == PUBCOMP) || (ReceivedMessageType == SUBACK) || (ReceivedMessageType == UNSUBACK))
          {
            SerialDBG.printf("Message ID :");
            SerialDBG.printf("%d\r\n",MQTT.inputString[0] * 256 + MQTT.inputString[1]) ;
          }
          else if (ReceivedMessageType == PINGREQ)
          {
            MQTT.TCP_Flag = false;
            MQTT.pingFlag = false;
            SerialDBG.printf("Disconnecting\r\n");
            MQTT.sendATreply("AT+CIPSHUT\r\n", ".", 4000) ;
            MQTT.modemStatus = 0;
          }
        }
      }
      else if ((inChar == 13) || (inChar == 10))
      {
      }
      else
      {
        SerialDBG.printf("Received :Unknown Message Type :");
        SerialDBG.printf("%d",inChar);
      }
    }
  }
}