#include "SIM7080GInterface.h"
#include "BoardCfg.h"
#include "timer.h"
#include "Uart.h"
#include "Syslog.h"
#include "WiFiCtrl.h"
#include "ATCmdInterpreter.h"
#include "ProtocolDefs.h"
#include "NetworkProtocol.h"

static BYTE mActivateNetworkCmd[] = "AT+CNACT=0,1\r";
static BYTE mDisconnectNetworkCmd[] = "AT+CNACT=0,0\r";
static BYTE mCheckAPNConnectionCmd[] = "AT+CNACT?\r";
static BYTE mConnectToMasterCmd[] = "AT+CAOPEN=0,0,\"TCP\",\"grosgin.myftp.org\",2182\r";
static BYTE mDisconnectFromMasterCmd[] = "AT+CACLOSE=0\r";
static BYTE mReceiveDataCmd[] = "AT+CARECV=0,100\r";

char mMasterTxBuffer[MAX_MESSAGE_SIZE];
int mMasterTxSize;

int mLTEModuleSMState;
int mLTEModuleOperationSMState;
int mLTEModuleOperationSMSubState;
int mNbCmdCharsReceived;
char mATCmd[LTE_MODULE_MAX_CMD_LENGTH];
bool mIsPassthroughEnabled;
bool mModuleSerialDebugEnabled;
bool mPICSerialDebugEnabled;
int mCurrentCmd;
bool mIsInitializing;
int mNbMasterReconnectCount;

bool mMasterConnected;
bool mMasterSocketError;
bool mAPNConnected;

void InitLTEModule()
{
    mLTEModuleSMState = LTE_MODULE_SM_INIT_STATE;
    mLTEModuleOperationSMState = LTE_MODULE_OPERATION_INIT_STATE;
    mLTEModuleOperationSMSubState = LTE_MODULE_OPERATION_NOMINAL_SUBSTATE;    
    mNbCmdCharsReceived = 0;
    mIsPassthroughEnabled = false;
    mModuleSerialDebugEnabled = false;
    mPICSerialDebugEnabled = false;
    mCurrentCmd = LTE_MODULE_NO_CMD;
    mIsInitializing = true;
    mNbMasterReconnectCount = 0;
    mMasterSocketError = false;
    
    mMasterConnected = false;
    mAPNConnected = false;
}
int LTEModuleReset()
{
    InitLTEModule();
    return RET_OK;
}

void LTEModuleSM(int SMEvent)
{
    switch(mLTEModuleSMState)
    {
        case LTE_MODULE_SM_INIT_STATE:
        {
//            LORA_MODULE_RELAY_PIN = 1;
            TimerStart(LTE_MODULE_TIMER,LTE_MODULE_POWERUP_TIMEOUT);
            mLTEModuleSMState = LTE_MODULE_SM_RESET_STATE;
            break;
        }
        case LTE_MODULE_SM_RESET_STATE:
        {
            if(IsTimerExpired(LTE_MODULE_TIMER) == true)
            {
//                LORA_MODULE_RELAY_PIN = 0;
//                LTE_MODULE_PWR_PIN = 0;
                TimerStart(LTE_MODULE_TIMER,LTE_MODULE_POWERUP_TIMEOUT);
                mLTEModuleSMState = LTE_MODULE_SM_POWERUP_STATE;
            }
            break;
        }
        case LTE_MODULE_SM_POWERUP_STATE:
        {
            if(IsTimerExpired(LTE_MODULE_TIMER) == true)
            {
//                LTE_MODULE_PWR_PIN = 1;
                TimerStart(LTE_MODULE_TIMER,LTE_MODULE_WAIT_INIT_TIMEOUT);
                mLTEModuleSMState = LTE_MODULE_SM_WAIT_RDY_STATE;
                TimerStart(LTE_COMM_TIMER, LTE_MODULE_MAX_COMM_TIMEOUT);
            }
            break;
        }
        case LTE_MODULE_SM_WAIT_RDY_STATE:
        {
            if(SMEvent == LTE_MODULE_RX_RDY_EVENT)
            {
                mLTEModuleSMState = LTE_MODULE_SM_SETECHOOFF_STATE;
            }
            else if(SMEvent == LTE_MODULE_SM_TICK_EVENT)
            {
                if(IsTimerExpired(LTE_COMM_TIMER) == true)
                {
                    LTEModuleReset();
                }
            }
            break;
        }
        case LTE_MODULE_SM_SETECHOOFF_STATE:
        {
            char Cmd[5] = {'A','T','E','0','\r'};
            //UartTransmitData(LTE_IF_UART_PORT,Cmd,5);
            SendDataToLteModule(Cmd,5);
            TimerStart(LTE_MODULE_TIMER,LTE_MODULE_POWERUP_TIMEOUT);
            mLTEModuleSMState = LTE_MODULE_SM_DELAY_STATE;
            break;
        }
        case LTE_MODULE_SM_SETAPN_STATE:
        {
            char Cmd[10] = {'A','T','+','C','G','N','A','P','N','\r'};
            //UartTransmitData(LTE_IF_UART_PORT,Cmd,10);
            SendDataToLteModule(Cmd,10);
            TimerStart(LTE_MODULE_TIMER,LTE_MODULE_POWERUP_TIMEOUT);
            mLTEModuleSMState = LTE_MODULE_SM_DELAY_STATE;
            break;
        }
        case LTE_MODULE_SM_DELAY_STATE:
        {
            if(IsTimerExpired(LTE_MODULE_TIMER) == true)
            {
                mLTEModuleSMState = LTE_MODULE_SM_RUN_STATE;
            }
            break;
        }
        case LTE_MODULE_SM_RUN_STATE:
        {
            if(SMEvent == LTE_MODULE_ENTER_PASSTHROUGH_EVENT)
            {
                mLTEModuleSMState = LTE_MODULE_SM_PASSTHROUGH_STATE;
                SyslogNewString("LTE Module entering passthrough mode...");
            }
            if(SMEvent == LTE_MODULE_SM_TICK_EVENT)
            {
                LTEModuleOperationSM(LTE_MODULE_OP_TICK_EVENT);
            }
            
            break;
        }
        case LTE_MODULE_SM_PASSTHROUGH_STATE:
        {
            if(SMEvent == LTE_MODULE_EXIT_PASSTHROUGH_EVENT)
            {
                SyslogNewString("LTE Module exiting passthrough mode...");
                mLTEModuleSMState = LTE_MODULE_SM_RUN_STATE;  
            }
            break;
        }
    }
}

void TickLTEModule()
{
    LTEModuleSM(LTE_MODULE_SM_TICK_EVENT);
}


void LTEModuleNewData(unsigned char Data)
{
    if(mIsPassthroughEnabled == true)
    {
        SyslogNewByte(Data);
        //        SendSyslogByte(Data);
        return;
    }
    
    if(mModuleSerialDebugEnabled == true)
    {
        SyslogNewByte(Data);
    }
    
    if(Data == '\n')    //ignore line feeds
        return;
    
    if(Data != '\r')
    {
        if(mLTEModuleOperationSMState == LTE_MODULE_OPERATION_SENDING_DATA_STATE && Data == '>')
        {
            LTESendMasterBufferToModule();
        }
        else if(mNbCmdCharsReceived < LTE_MODULE_MAX_CMD_LENGTH)
        {
            mATCmd[mNbCmdCharsReceived] = Data;
            mNbCmdCharsReceived++;
        }
        else
        {
            //error...
            mNbCmdCharsReceived = 0;
        }
    }
    else
    {
        if(mNbCmdCharsReceived != 0)    //New Command received
        {
            
            if(mLTEModuleSMState == LTE_MODULE_SM_WAIT_RDY_STATE)
            {
                if(mATCmd[0] == 'R' && mATCmd[1] == 'D' && mATCmd[2] == 'Y')
                {
                    LTEModuleSM(LTE_MODULE_RX_RDY_EVENT);
                }
            }
            else if(mLTEModuleSMState == LTE_MODULE_SM_RUN_STATE)
            {
                AnalyzeNewATString(mATCmd,mNbCmdCharsReceived,mCurrentCmd);
                mNbCmdCharsReceived = mNbCmdCharsReceived;
            }
            
            mNbCmdCharsReceived = 0;
        }
        
    }
}

void LTEEnterSerialPassthrough()
{
    LTEModuleSM(LTE_MODULE_ENTER_PASSTHROUGH_EVENT);
    mIsPassthroughEnabled = true;
    SyslogSetLTEPassthrough(true);
    mPICSerialDebugEnabled = false;
    mModuleSerialDebugEnabled = false;
}
void LTEExitSerialPassthrough()
{
    LTEModuleSM(LTE_MODULE_EXIT_PASSTHROUGH_EVENT);
    mIsPassthroughEnabled = false;
    SyslogSetLTEPassthrough(false);
}

void LTEFwdPassthroughData(char Data)
{
    if(mIsPassthroughEnabled == true)
    {
        UartTransmitData(LTE_IF_UART_PORT,&Data,1);
    }
    
}

int LTEEnableSerialDebug(bool EnModule, bool EnPic)
{
    if(EnModule == true)
    {
        if(mIsPassthroughEnabled == true)
        {
            return RET_ERROR;
        }
        mModuleSerialDebugEnabled = true;
    }
    else
    {
        mModuleSerialDebugEnabled = false;
    }
    
    if(EnPic == true)
    {
        if(mIsPassthroughEnabled == true)
        {
            return RET_ERROR;
        }
        
        mPICSerialDebugEnabled = true;
    }
    else
    {
        mPICSerialDebugEnabled = false;
    }
    
    return RET_OK;
}

void SendDataToLteModule(char *Data, int Size)
{
    
    if(mPICSerialDebugEnabled)
    {
        char *ptr = Data;
        int i;
        for(i = 0; i < Size; i++)
        {
            SyslogNewByte(*ptr++);
        }
    }
    UartTransmitData(LTE_IF_UART_PORT,Data,Size);
}

void LTECmdResponseReceived(int Cmd, int Result)
{
    switch(Cmd)
    {
        case LTE_MODULE_NO_CMD:
        {
            break;
        }
        case LTE_MODULE_CONNECT_APN_CMD:
        {
            if(Result == LTE_MODULE_RESULT_OK)
            {
                LTEModuleOperationSM(LTE_MODULE_OP_APN_CONN_OK_EVENT);
            }
            else if(Result == LTE_MODULE_RESULT_ERROR)
            {
                LTEModuleOperationSM(LTE_MODULE_OP_APN_CONN_FAILED_EVENT);
            }
            break;
        }
        case LTE_MODULE_DISCONNECT_APN_CMD:
        {
            
            break;
        }
        case LTE_MODULE_CHECK_APN_CONNECTION_CMD:
        {
            if(Result == LTE_MODULE_RESULT_OK)
            {
                if(mAPNConnected == true)
                {
                    LTEModuleOperationSM(LTE_MODULE_OP_APN_CONNECTED_EVENT);
                }
                else
                {
                    LTEModuleOperationSM(LTE_MODULE_OP_APN_DISCONNECTED_EVENT);
                }
            }
            else if(Result == LTE_MODULE_RESULT_ERROR)
            {
                LTEModuleOperationSM(LTE_MODULE_OP_APN_CONN_FAILED_EVENT);
            }
            break;
        }
        case LTE_MODULE_CONNECT_TO_MASTER_CMD:
        {
            if(Result == LTE_MODULE_RESULT_OK)
            {
                if(mMasterConnected == true)
                {
                    LTEModuleOperationSM(LTE_MODULE_OP_SERVER_CONNECTED_EVENT);
                }
                else
                {
                    LTEModuleOperationSM(LTE_MODULE_OP_SERVER_DISCONNECTED_EVENT);
                }
            }
            else if(Result == LTE_MODULE_RESULT_ERROR)
            {
                LTEModuleOperationSM(LTE_MODULE_OP_SERVER_CONN_FAILED_EVENT);
            }
            
            break;
        }
        case LTE_MODULE_DISCONNECT_FROM_MASTER_CMD:
        {
            if(Result == LTE_MODULE_RESULT_OK)
            {
                LTEModuleOperationSM(LTE_MODULE_OP_SERVER_DISCONNECTED_EVENT);
            }
            else if(Result == LTE_MODULE_RESULT_ERROR)
            {
                LTEModuleOperationSM(LTE_MODULE_OP_SERVER_DISCONNECTED_EVENT);
            }
            break;
        }
        case LTE_MODULE_CHECK_MASTER_CONNECTION_CMD:
        {
            if(Result == LTE_MODULE_RESULT_OK)
            {
                
            }
            else if(Result == LTE_MODULE_RESULT_ERROR)
            {
                
            }
            break;
        }
        case LTE_MODULE_RX_DATA_CMD:
        {
            if(Result == LTE_MODULE_RESULT_OK)
            {
                //This case is managed by LTEModuleDataReceived()
            }
            else if(Result == LTE_MODULE_RESULT_ERROR)
            {
                LTEModuleOperationSM(LTE_MODULE_OP_MASTER_DATA_RECEIVED_EVENT);
            }
            break;
        }
        case LTE_MODULE_TX_DATA_CMD:
        {
            if(Result == LTE_MODULE_RESULT_OK)
            {
                LTEModuleOperationSM(LTE_MODULE_OP_MASTER_DATA_SENT_EVENT);
            }
            else if(Result == LTE_MODULE_RESULT_ERROR)
            {
                //TODO: Manage a TX error...
                LTEModuleOperationSM(LTE_MODULE_OP_MASTER_DATA_SENT_EVENT);
            }
            break;
        }
    }
}
void LTEModuleAPNConnectionStatus(int Status)
{
    if(Status == LTE_MODULE_APN_CONNECTED)
    {
        mAPNConnected = true;
        //  SyslogNewString("APN connected\n");
    }
    else
    {
        mAPNConnected = false;
        // SyslogNewString("APN disconnected\n");
    }
}
void LTEModuleMasterConnectionStatus(int Status)
{
    if(Status == LTE_MODULE_MASTER_CONNECTED)
    {
        mMasterConnected = true;
        //  SyslogNewString("Master connected\n");
    }
    else if(Status == LTE_MODULE_MASTER_SOCKET_ERROR)
    {
        mMasterConnected = false;
        mMasterSocketError = true;
        //    SyslogNewString("Master socket error\n");
    }
    else
    {
        mMasterConnected = false;
        //   SyslogNewString("Master disconnected\n");
    }
}


void LTEModuleOperationSM(int OperationEvent)
{
    switch(mLTEModuleOperationSMState)
    {
        case LTE_MODULE_OPERATION_INIT_STATE:
        {
            mIsInitializing = true;
            //Send the request to connect module APN
            LTESendCommandToModule(LTE_MODULE_CONNECT_APN_CMD);
            mLTEModuleOperationSMState = LTE_MODULE_OPERATION_WAIT_CONNECT_APN_STATE;
            
            break;
        }
        case LTE_MODULE_OPERATION_WAIT_CONNECT_APN_STATE:
        {
            if(OperationEvent == LTE_MODULE_OP_APN_CONN_OK_EVENT)
            {
                //Send the request to confirm the state of the connection
                
                LTESendCommandToModule(LTE_MODULE_CHECK_APN_CONNECTION_CMD);
                mLTEModuleOperationSMState = LTE_MODULE_OPERATION_CHECK_APN_STATE;
            }
            else if(OperationEvent == LTE_MODULE_OP_APN_CONN_FAILED_EVENT)
            {
                //TODO: What do we do??
                LTEModuleReset();   //Something's wrong... reset the module.
            }
            else if(OperationEvent == LTE_MODULE_OP_TICK_EVENT)
            {
                if(IsTimerExpired(LTE_COMM_TIMER) == true)
                {
                    LTEModuleReset();
                }
            }
            
            break;
        }
        case LTE_MODULE_OPERATION_CHECK_APN_STATE:
        {  
            if(OperationEvent == LTE_MODULE_OP_APN_CONNECTED_EVENT)
            {
                if(mIsInitializing == true) //The first time, try to connect the server immediately
                {
                    mIsInitializing = false;
                    //Send the request to connect to Mastercontroller
                    LTESendCommandToModule(LTE_MODULE_CONNECT_TO_MASTER_CMD);
                    mLTEModuleOperationSMState = LTE_MODULE_OPERATION_WAIT_CONNECT_SERVER_STATE;
                }
                else
                {
                    mCurrentCmd = LTE_MODULE_NO_CMD;
                    mLTEModuleOperationSMState = LTE_MODULE_OPERATION_STANDBY_STATE;
                }
            }
            else if(OperationEvent == LTE_MODULE_OP_APN_DISCONNECTED_EVENT)
            {
                //Let the main loop retry later...
                mCurrentCmd = LTE_MODULE_NO_CMD;
                mLTEModuleOperationSMState = LTE_MODULE_OPERATION_STANDBY_STATE;
            }
            else if(OperationEvent == LTE_MODULE_OP_TICK_EVENT)
            {
                if(IsTimerExpired(LTE_COMM_TIMER) == true)
                {
                    LTEModuleReset();
                }
            }
            break;
        }
        case LTE_MODULE_OPERATION_WAIT_CONNECT_SERVER_STATE:
        {
            if(OperationEvent == LTE_MODULE_OP_SERVER_CONNECTED_EVENT)
            {
                mCurrentCmd = LTE_MODULE_NO_CMD;
                mLTEModuleOperationSMState = LTE_MODULE_OPERATION_STANDBY_STATE;
                TimerStart(LTE_MODULE_TIMER,LTE_MODULE_CONNECTION_CHECK_TIMEOUT);
            }
            else if(OperationEvent == LTE_MODULE_OP_SERVER_DISCONNECTED_EVENT)
            {
                mCurrentCmd = LTE_MODULE_NO_CMD;
                mLTEModuleOperationSMState = LTE_MODULE_OPERATION_STANDBY_STATE;
                TimerStart(LTE_MODULE_TIMER,LTE_MODULE_CONNECTION_CHECK_TIMEOUT);
                
            }
            else if(OperationEvent == LTE_MODULE_OP_SERVER_CONN_FAILED_EVENT)
            {
                //TODO: Should we reset the module instead?
                mCurrentCmd = LTE_MODULE_NO_CMD;
                mLTEModuleOperationSMState = LTE_MODULE_OPERATION_STANDBY_STATE;
                TimerStart(LTE_MODULE_TIMER,LTE_MODULE_CONNECTION_CHECK_TIMEOUT);
            }
            else if(OperationEvent == LTE_MODULE_OP_TICK_EVENT)
            {
                if(IsTimerExpired(LTE_COMM_TIMER) == true)
                {
                    LTEModuleReset();
                }
            }
            break;
        }
        case LTE_MODULE_OPERATION_WAIT_DISCONNECT_SERVER_STATE:
        {
            if(OperationEvent == LTE_MODULE_OP_SERVER_DISCONNECTED_EVENT)
            {
                //Always reconnect after a forced disconnection..
                mLTEModuleOperationSMState = LTE_MODULE_OPERATION_WAIT_CONNECT_SERVER_STATE;
                LTESendCommandToModule(LTE_MODULE_CONNECT_TO_MASTER_CMD);
            }
            else if(OperationEvent == LTE_MODULE_OP_TICK_EVENT)
            {
                if(IsTimerExpired(LTE_COMM_TIMER) == true)
                {
                    LTEModuleReset();
                }
            }
            break;
        }
        case LTE_MODULE_OPERATION_STANDBY_STATE:
        {
            if(OperationEvent == LTE_MODULE_OP_TICK_EVENT)
            {
                if(IsTimerRunning(LTE_COMM_TIMER) == true)
                {
                    TimerStop(LTE_COMM_TIMER);
                }
                switch(mLTEModuleOperationSMSubState)
                {
                    case LTE_MODULE_OPERATION_NOMINAL_SUBSTATE:
                    {
                        if(IsTimerExpired(LTE_MODULE_TIMER) == true)
                        {
                            if(mMasterConnected == true)    //All is good for now...
                            {
                                char tmp[] = "Ca marche\n\r";
                                mNbMasterReconnectCount = 0;
                                TimerStart(LTE_MODULE_TIMER,LTE_MODULE_CONNECTION_CHECK_TIMEOUT);
                            }
                            else
                            {
                                //Master connection is lost... try to reconnect.
                                if(mNbMasterReconnectCount < LTE_MODULE_MAX_MASTER_CONNECT_RETRY)
                                {
                                    mNbMasterReconnectCount++;
                                    mLTEModuleOperationSMSubState = LTE_MODULE_OPERATION_RECONNECT_MASTER_SUBSTATE;
                                    mLTEModuleOperationSMState = LTE_MODULE_OPERATION_WAIT_DISCONNECT_SERVER_STATE;
                                    LTESendCommandToModule(LTE_MODULE_DISCONNECT_FROM_MASTER_CMD); //Always disconnect before reconnecting...
                                    //    SyslogNewString("Master reconnection attempt\n");
                                }
                                else    //We tried 10 times, check the APN
                                {
                                    mLTEModuleOperationSMState = LTE_MODULE_OPERATION_CHECK_APN_STATE;
                                    mLTEModuleOperationSMSubState = LTE_MODULE_OPERATION_CHECK_APN_SUBSTATE;
                                    LTESendCommandToModule(LTE_MODULE_CHECK_APN_CONNECTION_CMD);
                                    mNbMasterReconnectCount = 0;
                                    // SyslogNewString("Master reconnection attempt count reached.. checking APN\n");
                                }
                            }
                        }
                        break;
                    }
                    case LTE_MODULE_OPERATION_RECONNECT_MASTER_SUBSTATE:
                    {
                        mLTEModuleOperationSMSubState = LTE_MODULE_OPERATION_NOMINAL_SUBSTATE;
                        //TODO: check for SOCKET ERROR result code and reset APN directly here?
                        //                        if(mMasterSocketError == true)
                        //                        {
                        //                            mMasterSocketError = false;
                        //                            mLTEModuleOperationSMState = LTE_MODULE_OPERATION_CHECK_APN_STATE;
                        //                            mLTEModuleOperationSMSubState = LTE_MODULE_OPERATION_CHECK_APN_SUBSTATE;
                        //                            LTESendCommandToModule(LTE_MODULE_CHECK_APN_CONNECTION_CMD);
                        //                            mNbMasterReconnectCount = 0;                            
                        //                        }
                        break;
                    }
                    case LTE_MODULE_OPERATION_CHECK_APN_SUBSTATE:
                    {
                        if(mAPNConnected == true)
                        {
                            mLTEModuleOperationSMSubState = LTE_MODULE_OPERATION_NOMINAL_SUBSTATE;
                        }
                        else    //APN is disconnected.. try reconnecting.
                        {
                            mLTEModuleOperationSMState = LTE_MODULE_OPERATION_WAIT_CONNECT_APN_STATE;
                            mLTEModuleOperationSMSubState = LTE_MODULE_OPERATION_RECONNECT_APN_SUBSTATE;
                            LTESendCommandToModule(LTE_MODULE_CONNECT_APN_CMD);
                        }
                        break;
                    }
                    case LTE_MODULE_OPERATION_RECONNECT_APN_SUBSTATE:
                    {
                        mLTEModuleOperationSMSubState = LTE_MODULE_OPERATION_NOMINAL_SUBSTATE;
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
            }
            else if(OperationEvent == LTE_MODULE_OP_MASTER_DATA_READY_EVENT)
            {
                LTESendCommandToModule(LTE_MODULE_RX_DATA_CMD);
                mLTEModuleOperationSMState = LTE_MODULE_OPERATION_WAIT_FOR_DATA_STATE;
            }
            else if(OperationEvent == LTE_MODULE_OP_MASTER_SEND_DATA_REQUEST_EVENT)
            {
                if(mMasterConnected == true)
                {
                    LTESendCommandToModule(LTE_MODULE_TX_DATA_CMD);
                    mLTEModuleOperationSMState = LTE_MODULE_OPERATION_SENDING_DATA_STATE;
                }
            }
            break;
        }
        case LTE_MODULE_OPERATION_WAIT_FOR_DATA_STATE:
        {
            if(OperationEvent == LTE_MODULE_OP_MASTER_DATA_RECEIVED_EVENT)
            {
                mCurrentCmd = LTE_MODULE_NO_CMD;
                mLTEModuleOperationSMState = LTE_MODULE_OPERATION_STANDBY_STATE;
            }
            else if(OperationEvent == LTE_MODULE_OP_TICK_EVENT)
            {
                if(IsTimerExpired(LTE_COMM_TIMER) == true)
                {
                    LTEModuleReset();
                }
            }
            
            break;
        }
        case LTE_MODULE_OPERATION_SENDING_DATA_STATE:
        {
            if(OperationEvent == LTE_MODULE_OP_TICK_EVENT)
            {
                if(IsTimerExpired(LTE_COMM_TIMER) == true)
                {
                    LTEModuleReset();
                }
            }
            else if(OperationEvent == LTE_MODULE_OP_MASTER_DATA_SENT_EVENT)
            {
                mCurrentCmd = LTE_MODULE_NO_CMD;
                mLTEModuleOperationSMState = LTE_MODULE_OPERATION_STANDBY_STATE;
            }
            break;
        }
    }
}


void LTEModuleNewDataReady()
{
    LTEModuleOperationSM(LTE_MODULE_OP_MASTER_DATA_READY_EVENT);
}
void LTEModuleDataReceived(char *Data, int Size)
{
    LTEModuleOperationSM(LTE_MODULE_OP_MASTER_DATA_RECEIVED_EVENT);
    int i;
    for(i = 0; i < Size; i++)
    {
        ProtocolAnalyzeNewData(Data[i], NETWORK_PROTOCOL_USER_LTE);
    }
}

int LTESendCommandToModule(int Cmd)
{
    switch(Cmd)
    {
        
        TimerStart(LTE_COMM_TIMER,LTE_MODULE_MAX_COMM_TIMEOUT);
        case LTE_MODULE_CONNECT_APN_CMD:
        {
            mCurrentCmd = LTE_MODULE_CONNECT_APN_CMD;
            SendDataToLteModule(mActivateNetworkCmd,strlen(mActivateNetworkCmd));
            break;
        }
        case LTE_MODULE_DISCONNECT_APN_CMD:
        {
            mCurrentCmd = LTE_MODULE_DISCONNECT_APN_CMD;
            SendDataToLteModule(mDisconnectNetworkCmd,strlen(mDisconnectNetworkCmd));
            break;
        }
        case LTE_MODULE_CONNECT_TO_MASTER_CMD:
        {
            mCurrentCmd = LTE_MODULE_CONNECT_TO_MASTER_CMD;
            SendDataToLteModule(mConnectToMasterCmd,strlen(mConnectToMasterCmd));
            break;
        }
        case LTE_MODULE_DISCONNECT_FROM_MASTER_CMD:
        {
            mCurrentCmd = LTE_MODULE_DISCONNECT_FROM_MASTER_CMD;
            SendDataToLteModule(mDisconnectFromMasterCmd,strlen(mDisconnectFromMasterCmd));
            break;
        }
        case LTE_MODULE_RX_DATA_CMD:
        {
            mCurrentCmd = LTE_MODULE_RX_DATA_CMD;
            SendDataToLteModule(mReceiveDataCmd,strlen(mReceiveDataCmd));
            break;
        }
        case LTE_MODULE_TX_DATA_CMD:
        {
            char Cmd[25];
            sprintf(Cmd,"AT+CASEND=0,%d\r",mMasterTxSize);
            mCurrentCmd = LTE_MODULE_TX_DATA_CMD;
            SendDataToLteModule(Cmd,strlen(Cmd));
            break;
        }
        case LTE_MODULE_CHECK_APN_CONNECTION_CMD:
        {
            mCurrentCmd = LTE_MODULE_CHECK_APN_CONNECTION_CMD;
            SendDataToLteModule(mCheckAPNConnectionCmd,strlen(mCheckAPNConnectionCmd));
            break;
        }
        case LTE_MODULE_CHECK_MASTER_CONNECTION_CMD:
        {
            break;
        }
        case LTE_MODULE_NO_CMD:
        default:
        {
            TimerStop(LTE_COMM_TIMER);
            mCurrentCmd = LTE_MODULE_NO_CMD;
            return RET_ERROR;
            break;
        }
        
    }
    return RET_OK;
}

void LTEModuleMasterCtrlCommStatus(bool Offline)
{
    if(Offline == true)
    {
        mMasterConnected = false;
    }
    //    else
    //        mMasterConnected = true;
}

//This is the function to call from outside to send data to the server
int LTESendDataToMaster(char *Buffer, int Size)
{
//    LTE_MODULE_TX_LED_PIN = LED_ON;
    if(Size > MAX_MESSAGE_SIZE)
    {
        return RET_ERROR;
    }
    if(mMasterConnected == false)
    {
        return RET_ERROR;
    }
    
    memcpy(mMasterTxBuffer,Buffer,Size);
    mMasterTxSize = Size;
    LTEModuleOperationSM(LTE_MODULE_OP_MASTER_SEND_DATA_REQUEST_EVENT);
    return RET_OK;
}

//The module is ready... send the payload so it can transmit it to the master
int LTESendMasterBufferToModule()
{
    SendDataToLteModule(mMasterTxBuffer,mMasterTxSize);
//    LTE_MODULE_TX_LED_PIN = LED_OFF;
    return RET_OK;
}

bool LTEModuleIsMasterConnected()
{
    return mMasterConnected;
}