#include <stdio.h>
#include <string.h>

#include "FreeRTOS.h"
#include "freerotsTask.h"
#include "task.h"

#include "pDebug.h"
#include "upUartParse.h"
#include "FM_GPIO.h"
#include "FM_ADC.h"
#include "queueUart.h"




/* 读取寄存器，最大起始位 */
#define maxStartReadResAddr 10
/* 读取寄存器，最大长度 */
#define maxReadResAddrLen 20

/* 写入寄存器，最大起始位 */
#define maxStartWriteResAddr 10
/* 写入寄存器，最大长度 */
#define maxWriteResAddrLen 20

/* 单次读取配置文件最大个数 */
#define maxReadCfgLen 80

/* 单次写入配置文件最大字节 */
#define maxDistributionCfgLen 230

/* 2秒的节拍数 */
#define tick_2S (configTICK_RATE_HZ * 2)
/* 1分钟的节拍数 */
#define tick_1M (configTICK_RATE_HZ * 60)


/* 功能码 */
typedef enum {
   SL_Function_Code_Read_Register           =   0x30,   /* 读寄存器数据 */
   SL_Function_Code_Write_Register          =   0x10,   /* 写寄存器数据 */
   SL_Function_Code_Distribution_Profile    =   0xD0,   /* 配置文件下发 */
   SL_Function_Code_Read_Profile            =   0xD1,   /* 配置文件读取 */
}SL_MsgFunctionCode;

/* 寄存器地址 */
typedef enum {
    GW_Register_WorkCurrent         = 0x0000,
    GW_Register_WorkVoltage         = 0x0001,
    GW_Register_Temperature         = 0x0002,
    GW_Register_Port1_Power         = 0x0003,
    GW_Register_Port2_Power         = 0x0004,
    GW_Register_Port3_Power         = 0x0005,
    GW_Register_Port4_Power         = 0x0006,
    GW_Register_Port5_Power         = 0x0007,
    GW_Register_Port6_Power         = 0x0008,
    GW_Register_Port7_Power         = 0x0009,
    GW_Register_Port8_Power         = 0x000A,
    GW_Register_Port9_Power         = 0x000B,
}SL_GateWay_MsgRegister;

/* 配置文件数据类型表 */
typedef enum {
    /* (1字节)对智能模块通信波特率(00H：不使用该串口,01H：4800;02H：9600;03H：19200;04H：38400;05H：57600;06H：115200)  */
    Upward_UART_Communication_Baud_Rate     = 0x0001,
    J1_485_Communication_Baud_Rate          = 0x0002,
    J2_485_Communication_Baud_Rate          = 0x0003,
    J3_485_Communication_Baud_Rate          = 0x0004,
    J4_485_Communication_Baud_Rate          = 0x0005,
    J5_0_485_Communication_Baud_Rate        = 0x0006,
}gateWayCfgFileType;

/* 状态机 */
typedef enum {
    wait                        = 0,    /* 串口状态机初始状态 */
    startFlagGW,                        /* 接收到帧头 */
    functionCodeGW,                     /* 接收到功能码 */
    readRegStartAddressGW,              /* 接收到读取寄存器起始地址 */
    readRegStartNumberGW,               /* 接收到读取寄存器个数 */
    crcCheckBitGW,                      /* 接收到校验位 */
    endFlagGW,                          /* 接收到帧尾 */
    writeRegStartAddressGW,             /* 接收到写入寄存器起始地址 */
    writeRegStartNumberGW,              /* 接收到写入寄存器个数 */
    cfgFramesNumGW,                     /* 接收到配置文件帧数 */
    cfgLengthGW,                        /* 接收到配置文件长度 */
    readCfgLengthGW,                    /* 接收到读取配置文件长度 */
    startFlagSL,                        /* 接收到帧头 */
    portSL,                             /* 接收到端口号 */
    lengthSL,                           /* 接收到数据包的长度 */
    endFlagSL,                          /* 接收到帧尾 */
} uartStateMachine;


// /* 计时参数，1min后没解析整个配置文件，丢掉当前数据 */
// static uint32_t gw485CfgTime = 0;

/* 计时参数，2秒后没解析出一帧数据，丢掉当前数据 */
static uint32_t gw485RxTime = 0;

/* 储存gw485数据 */
static uint8_t gw485RxBuffer[1100];
static uint16_t gw485RxBufferIndex = 0;

/* 状态机状态机变量 */
static uartStateMachine state = wait;
/* 帧长度 */
static uint16_t frameLength = 0;

static void stateMachine(device_handle device);

/* 状态机函数 */
static uint8_t analysisWait(void);
static uint8_t analysisStartFlagGW(void);
static uint8_t analysisFunctionCodeGW(void);
static uint8_t analysisReadRegStartAddressGW(void);
static uint8_t analysisReadRegStartNumberGW(void);
static uint8_t analysisCrcCheckBitGW(void);
static uint8_t analysisEndFlagGW(device_handle device);
static uint8_t analysisWriteRegStartAddressGW(void);
static uint8_t analysisWriteRegStartNumberGW(void);
static uint8_t analysisCfgFramesNumGW(void);
static uint8_t analysisCfgLengthGW(void);
static uint8_t analysisReadCfgLengthGW(void);
static uint8_t analysisStartFlagSL(void);
static uint8_t analysisPortSL(void);
static uint8_t analysisLengthSL(void);
static uint8_t analysisEndFlagSL(void);




static void GW_MsgProcFunc_Read_Register(device_handle device,uint8_t *buff, uint16_t buffLen);
static void GW_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen);
static void GW_MsgProcFunc_Distribution_Profile(device_handle device, void *pMsg, uint32_t MsgLen);
static void GW_MsgProcFunc_Read_Profile(device_handle device, void *pMsg, uint32_t MsgLen);












/* 寄存器处理表 */
typedef uint16_t (*RegProcFunc)(void*);
typedef struct _SL_RegProcTable{
    uint32_t     regId;
    RegProcFunc  pRegProc;
}SL_RegProcTable;

/* 寄存器解析 */
static uint16_t ReadRegisterWorkCurrent(void *pMsg);
static uint16_t ReadRegisterWorkVoltage(void *pMsg);
static uint16_t ReadRegisterTemperature(void *pMsg);
static uint16_t ReadRegisterPort1_Power(void *pMsg);
static uint16_t ReadRegisterPort2_Power(void *pMsg);
static uint16_t ReadRegisterPort3_Power(void *pMsg);
static uint16_t ReadRegisterPort4_Power(void *pMsg);
static uint16_t ReadRegisterPort5_Power(void *pMsg);
static uint16_t ReadRegisterPort6_Power(void *pMsg);
static uint16_t ReadRegisterPort7_Power(void *pMsg);
static uint16_t ReadRegisterPort8_Power(void *pMsg);
static uint16_t ReadRegisterPort9_Power(void *pMsg);
static uint16_t WriteRegisterPort1_Power(void *pMsg);
static uint16_t WriteRegisterPort2_Power(void *pMsg);
static uint16_t WriteRegisterPort3_Power(void *pMsg);
static uint16_t WriteRegisterPort4_Power(void *pMsg);
static uint16_t WriteRegisterPort5_Power(void *pMsg);
static uint16_t WriteRegisterPort6_Power(void *pMsg);
static uint16_t WriteRegisterPort7_Power(void *pMsg);
static uint16_t WriteRegisterPort8_Power(void *pMsg);
static uint16_t WriteRegisterPort9_Power(void *pMsg);

/* 读取寄存器处理表 */
SL_RegProcTable g_RegTblR[] =
{    
    {GW_Register_WorkCurrent,    ReadRegisterWorkCurrent},
    {GW_Register_WorkVoltage,    ReadRegisterWorkVoltage},
    {GW_Register_Temperature,    ReadRegisterTemperature},
    {GW_Register_Port1_Power,    ReadRegisterPort1_Power},
    {GW_Register_Port2_Power,    ReadRegisterPort2_Power},
    {GW_Register_Port3_Power,    ReadRegisterPort3_Power},
    {GW_Register_Port4_Power,    ReadRegisterPort4_Power},
    {GW_Register_Port5_Power,    ReadRegisterPort5_Power},
    {GW_Register_Port6_Power,    ReadRegisterPort6_Power},
    {GW_Register_Port7_Power,    ReadRegisterPort7_Power},
    {GW_Register_Port8_Power,    ReadRegisterPort8_Power},
    {GW_Register_Port9_Power,    ReadRegisterPort9_Power},
};

/* 写入寄存器处理表 */
SL_RegProcTable g_RegTblW[] =
{
    {GW_Register_Port1_Power,    WriteRegisterPort1_Power},
    {GW_Register_Port2_Power,    WriteRegisterPort2_Power},
    {GW_Register_Port3_Power,    WriteRegisterPort3_Power},
    {GW_Register_Port4_Power,    WriteRegisterPort4_Power},
    {GW_Register_Port5_Power,    WriteRegisterPort5_Power},
    {GW_Register_Port6_Power,    WriteRegisterPort6_Power},
    {GW_Register_Port7_Power,    WriteRegisterPort7_Power},
    {GW_Register_Port8_Power,    WriteRegisterPort8_Power},
    {GW_Register_Port9_Power,    WriteRegisterPort9_Power},
};

/**
  * @brief  读取工作电流寄存器
  * @param
  * @retval
  */
uint16_t ReadRegisterWorkCurrent(void *pMsg)
{
    return 0;
}

/**
  * @brief  读取工作电压寄存器
  * @param
  * @retval
  */
uint16_t ReadRegisterWorkVoltage(void *pMsg)
{
    return 0;
}

/**
  * @brief  读取温度寄存器
  * @param
  * @retval
  */
uint16_t ReadRegisterTemperature(void *pMsg)
{
    return 0;
}

/**
  * @brief  读取端口1电源状态
  * @param
  * @retval
  */
uint16_t ReadRegisterPort1_Power(void *pMsg)
{
    return readPwrCtrlState(J1_PwrCtrl);
}

/**
  * @brief  读取端口2电源状态
  * @param
  * @retval
  */
uint16_t ReadRegisterPort2_Power(void *pMsg)
{
    return readPwrCtrlState(J2_PwrCtrl);
}

/**
  * @brief  读取端口3电源状态
  * @param
  * @retval
  */
uint16_t ReadRegisterPort3_Power(void *pMsg)
{
    return readPwrCtrlState(J3_PwrCtrl);
}

/**
  * @brief  读取端口4电源状态
  * @param
  * @retval
  */
uint16_t ReadRegisterPort4_Power(void *pMsg)
{
    return readPwrCtrlState(J4_PwrCtrl);
}

/**
  * @brief  读取端口5电源状态
  * @param
  * @retval
  */
uint16_t ReadRegisterPort5_Power(void *pMsg)
{
    return readPwrCtrlState(J5_PwrCtrl);
}

/**
  * @brief  读取端口6电源状态
  * @param
  * @retval
  */
uint16_t ReadRegisterPort6_Power(void *pMsg)
{
    return readPwrCtrlState(J6_PwrCtrl);
}

/**
  * @brief  读取端口7电源状态
  * @param
  * @retval
  */
uint16_t ReadRegisterPort7_Power(void *pMsg)
{
    return readPwrCtrlState(J7_PwrCtrl);
}

/**
  * @brief  读取端口8电源状态
  * @param
  * @retval
  */
uint16_t ReadRegisterPort8_Power(void *pMsg)
{
    return readPwrCtrlState(J8_PwrCtrl);
}

/**
  * @brief  读取端口9电源状态
  * @param
  * @retval
  */
uint16_t ReadRegisterPort9_Power(void *pMsg)
{
    return readPwrCtrlState(J9_PwrCtrl);
}

/**
  * @brief  设置端口1电源状态
  * @param
  * @retval
  */
uint16_t WriteRegisterPort1_Power(void *pMsg)
{
    writePwrCtrlState(J1_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg));
    return 0;
}

/**
  * @brief  设置端口2电源状态
  * @param
  * @retval
  */
uint16_t WriteRegisterPort2_Power(void *pMsg)
{
    writePwrCtrlState(J2_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg));
    return 0;
}

/**
  * @brief  设置端口3电源状态
  * @param
  * @retval
  */
uint16_t WriteRegisterPort3_Power(void *pMsg)
{
    writePwrCtrlState(J3_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg));
    return 0;
}

/**
  * @brief  设置端口4电源状态
  * @param
  * @retval
  */
uint16_t WriteRegisterPort4_Power(void *pMsg)
{
    writePwrCtrlState(J4_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg));
    return 0;
}

/**
  * @brief  设置端口5电源状态
  * @param
  * @retval
  */
uint16_t WriteRegisterPort5_Power(void *pMsg)
{
    writePwrCtrlState(J5_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg));
    return 0;
}

/**
  * @brief  设置端口6电源状态
  * @param
  * @retval
  */
uint16_t WriteRegisterPort6_Power(void *pMsg)
{
    writePwrCtrlState(J6_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg));
    return 0;
}

/**
  * @brief  设置端口7电源状态
  * @param
  * @retval
  */
uint16_t WriteRegisterPort7_Power(void *pMsg)
{
    writePwrCtrlState(J7_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg));
    return 0;
}

/**
  * @brief  设置端口8电源状态
  * @param
  * @retval
  */
uint16_t WriteRegisterPort8_Power(void *pMsg)
{
    writePwrCtrlState(J8_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg));
    return 0;
}

/**
  * @brief  设置端口9电源状态
  * @param
  * @retval
  */
uint16_t WriteRegisterPort9_Power(void *pMsg)
{
    writePwrCtrlState(J9_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg));
    return 0;
}


/**
  * @brief  状态 wait
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define waitMaxLen 2
uint8_t analysisWait(void)
{
    if (gw485RxBufferIndex >= 2) {
        /* 透传数据帧包头 */
        if (gw485RxBuffer[0] == 'S' && gw485RxBuffer[1] == 'L') {
            // log_info("startFlagSL\n");
            state = startFlagSL;
            return TRUE;
        }

        /* 数据帧包头 */
        else if (gw485RxBuffer[0] == 'G' && gw485RxBuffer[1] == 'W') {
            state = startFlagGW;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < waitMaxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 startFlagGW
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
uint8_t analysisStartFlagGW(void)
{
    if (gw485RxBuffer[2] == SL_Function_Code_Read_Register
        || gw485RxBuffer[2] == SL_Function_Code_Write_Register
        || gw485RxBuffer[2] == SL_Function_Code_Distribution_Profile
        || gw485RxBuffer[2] == SL_Function_Code_Read_Profile) {
            state = functionCodeGW;
            return TRUE;
    }

    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 functionCodeGW
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define functionCodeGWMaxLen 5
uint8_t analysisFunctionCodeGW(void)
{
    if (gw485RxBufferIndex >= 5 && gw485RxBuffer[2] == SL_Function_Code_Read_Register) {
        /* 读取寄存器起始地址 */
        uint16_t startResAddr = ((gw485RxBuffer[3] << 8) | gw485RxBuffer[4]);
        if (startResAddr < maxStartReadResAddr) {
            frameLength = 10;
            state = readRegStartAddressGW;
            return TRUE;
        }
    }
    
    if (gw485RxBufferIndex >= 5 && gw485RxBuffer[2] == SL_Function_Code_Write_Register) {
        /* 写入寄存器起始地址 */
        uint16_t startResAddr = ((gw485RxBuffer[3] << 8) | gw485RxBuffer[4]);
        if (startResAddr < maxStartWriteResAddr) {
            state = writeRegStartAddressGW;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex >= 5 && gw485RxBuffer[2] == SL_Function_Code_Write_Register) {
        /* 写入寄存器起始地址 */
        uint16_t startResAddr = ((gw485RxBuffer[3] << 8) | gw485RxBuffer[4]);
        if (startResAddr < maxStartWriteResAddr) {
            state = writeRegStartAddressGW;
            return TRUE;
        }
    }

    /* 解析配置文件下发帧数 */
    if ((gw485RxBufferIndex >= 5) && (gw485RxBuffer[2] == SL_Function_Code_Distribution_Profile)) {
        if (gw485RxBuffer[3] <= gw485RxBuffer[4]) {
            state = cfgFramesNumGW;
            return TRUE;
        }        
    }

    /* 解析配置文件读取内容的长度 */
    if ((gw485RxBufferIndex >= 5) && (gw485RxBuffer[2] == SL_Function_Code_Read_Profile)) {
        uint32_t tempCfgLen = 0;
        tempCfgLen = (gw485RxBuffer[3] << 8) | gw485RxBuffer[4];

        if (tempCfgLen < maxReadCfgLen && tempCfgLen > 0) {
            state = readCfgLengthGW;
            frameLength = 8 + tempCfgLen;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < functionCodeGWMaxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 readRegStartAddressGW
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define ReadRegStartAddressGWMaxLen 7
uint8_t analysisReadRegStartAddressGW(void)
{
    if (gw485RxBufferIndex >= 7) {
        /* 读取寄存器起始地址 */
        uint16_t resAddrLen = ((gw485RxBuffer[5] << 8) | gw485RxBuffer[6]);
        if (resAddrLen < maxReadResAddrLen) {
            state = readRegStartNumberGW;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < functionCodeGWMaxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 readRegStartNumberGW
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define ReadRegStartNumberMaxLen 9
uint8_t analysisReadRegStartNumberGW(void)
{
    /* crc校验 */
    if (gw485RxBufferIndex >= ReadRegStartNumberMaxLen) {
        uint16_t tempCrc = 0;
        tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2];

        if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) {
            state = crcCheckBitGW;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < ReadRegStartNumberMaxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**     
  * @brief  状态 crcCheckBitGW
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
uint8_t analysisCrcCheckBitGW(void)
{
    /* 结束标志校验校验 */
    if (gw485RxBufferIndex == frameLength) {
        if (gw485RxBuffer[frameLength - 1] == 0x16) {
            state = endFlagSL;
            return TRUE;
        }
    }

    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 endFlagGW
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
uint8_t analysisEndFlagGW(device_handle device)
{
    /* 数据为读取寄存器 */
    if (gw485RxBuffer[2] == SL_Function_Code_Read_Register) {
        GW_MsgProcFunc_Read_Register(device, gw485RxBuffer, frameLength);
    }

    /* 数据为写入寄存器 */
    if (gw485RxBuffer[2] == SL_Function_Code_Write_Register) {
        GW_MsgProcFunc_Write_Register(device, gw485RxBuffer, frameLength);
    }

    /* 数据为下发配置文件 */
    else if (gw485RxBuffer[9] == SL_Function_Code_Distribution_Profile) {
        GW_MsgProcFunc_Distribution_Profile(device, gw485RxBuffer, frameLength);
    }

    /* 数据为读取配置文件 */
    else if (gw485RxBuffer[9] == SL_Function_Code_Read_Profile) {
        GW_MsgProcFunc_Read_Profile(device, gw485RxBuffer, frameLength);
    }

    //清零buff
    state = wait;
    gw485RxBufferIndex = 0;
    return 1;
}

/**
  * @brief  状态 writeRegStartAddressGW
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define WriteRegStartAddressGWMaxLen 7
uint8_t analysisWriteRegStartAddressGW(void)
{
    if (gw485RxBufferIndex >= 7) {
        /* 写入寄存器起始地址 */
        uint16_t resAddrLen = ((gw485RxBuffer[5] << 8) | gw485RxBuffer[6]);
        if (resAddrLen < maxReadResAddrLen) {
            frameLength = 10 + 2 * resAddrLen;
            state = readRegStartNumberGW;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < WriteRegStartAddressGWMaxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 writeRegStartNumberGW
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define WriteRegStartNumberGWMaxLen (frameLength - 1)
uint8_t analysisWriteRegStartNumberGW(void)
{
    /* crc校验 */
    if (gw485RxBufferIndex >= WriteRegStartNumberGWMaxLen) {
        uint16_t tempCrc = 0;
        tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2];

        if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) {
            state = crcCheckBitGW;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < WriteRegStartNumberGWMaxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 cfgFramesNumGW
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define CfgFramesNumGWMaxLen 7
uint8_t analysisCfgFramesNumGW(void)
{
    /* 解析下发配置文件数据内容长度 */
    if (gw485RxBufferIndex >= CfgFramesNumGWMaxLen) {
        uint32_t tempLen = 0;
        tempLen = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13];

        if (tempLen > 0 && tempLen <= maxDistributionCfgLen) {
            state = cfgLengthGW;
            frameLength = 10 + tempLen;
            // log_error("cfgFramesNumSL error : tempLen = %d \n", tempLen);
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < CfgFramesNumGWMaxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 cfgLengthGW
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define CfgLengthGWMaxLen (frameLength - 1)
uint8_t analysisCfgLengthGW(void)
{
    /* crc校验 */
    if (gw485RxBufferIndex >= CfgLengthGWMaxLen) {
        uint16_t tempCrc = 0;
        tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2];

        if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) {
            state = crcCheckBitGW;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < CfgLengthGWMaxLen) {
        return FALSE;
    }

    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define ReadCfgLengthGWMaxLen (frameLength - 1)
uint8_t analysisReadCfgLengthGW(void)
{
    /* crc校验 */
    if (gw485RxBufferIndex >= ReadCfgLengthGWMaxLen) {
        uint16_t tempCrc = 0;
        tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2];

        if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) {
            state = crcCheckBitGW;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < ReadCfgLengthGWMaxLen) {
        return FALSE;
    }

    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 startFlagSL
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
uint8_t analysisStartFlagSL(void)
{
    /* 校验端口号 */
    if (gw485RxBuffer[2] < 10 && gw485RxBuffer[2] >= 0) {
        // log_info("portSL\n");
        state = portSL;
        return TRUE;
    }

    // log_error("portSL %d \n", gw485RxBuffer[2]);
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 portSL
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define PortSLMaxLen 5
uint8_t analysisPortSL(void)
{
    /* 解析数据包的度 */
    if (gw485RxBufferIndex >= PortSLMaxLen) {
        uint32_t tempLen = 0;
        tempLen = (gw485RxBuffer[3] << 8) | gw485RxBuffer[4];

        if (tempLen > 0 && tempLen <= 1024) {
            // log_info("lengthSL\n");
            state = lengthSL;
            frameLength = 6 + tempLen;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < PortSLMaxLen) {
        return FALSE;
    }
    
    // log_error("lengthSL %d \n", (gw485RxBuffer[3] << 8) | gw485RxBuffer[4]);

    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 lengthSL
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define LengthSLMaxLen frameLength
uint8_t analysisLengthSL(void)
{
    /* 解析帧尾 */
    if (gw485RxBufferIndex >= LengthSLMaxLen) {
        if (gw485RxBuffer[LengthSLMaxLen - 1] == 0x17) {
            // log_info("endFlagSL\n");
            state = endFlagSL;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < LengthSLMaxLen) {
        return FALSE;
    }
    // log_info("endFlagSL %d\n", gw485RxBuffer[LengthSLMaxLen - 1]);

    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 endFlagSL
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
uint8_t analysisEndFlagSL(void)
{
    uint32_t tempLen = 0;
    tempLen = (gw485RxBuffer[3] << 8) | gw485RxBuffer[4];

    /* 对于不同通端口，传输的结构体不同 */
    uint8_t *Buff;
    if (gw485RxBuffer[2] > 0 && gw485RxBuffer[2] < 5) {
        Buff = (uint8_t *)pvPortMalloc(tempLen + queueUartSendInfoSize);
        queueUartSendInfo *sendBuff = (queueUartSendInfo *)Buff;
        sendBuff->length = tempLen + 1;
        sendBuff->data = Buff + queueUartSendInfoSize;
        strlcpy((char *)sendBuff->data, (char *)&gw485RxBuffer[5], tempLen + 1);
    }
    else {
        Buff = (uint8_t *)pvPortMalloc(tempLen + queueTimeShareSendInfoSize);
        queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff;
        sendBuff->length = tempLen + 1;
        sendBuff->data = Buff + queueTimeShareSendInfoSize;
        strlcpy((char *)sendBuff->data, (char *)&gw485RxBuffer[5], tempLen + 1);
    }


    /* 通过不同的端口将数据发送到不同的地方 */
    if (gw485RxBuffer[2] == 1) {
        if (uxQueueSpacesAvailable(J1_485_Queue)) {
            xQueueSend(J1_485_Queue, &Buff, 10);
        }
    }
    else if (gw485RxBuffer[2] == 2) {
        if (uxQueueSpacesAvailable(J2_485_Queue)) {
            xQueueSend(J2_485_Queue, &Buff, 10);    
        }
    }
    else if (gw485RxBuffer[2] == 3) {
        if (uxQueueSpacesAvailable(J3_485_Queue)) {
            xQueueSend(J3_485_Queue, &Buff, 10);    
        }
    }
    else if (gw485RxBuffer[2] == 4) {
        if (uxQueueSpacesAvailable(J4_485_Queue)) {
            xQueueSend(J4_485_Queue, &Buff, 10);    
        }
    }
    else if (gw485RxBuffer[2] == 5) {
        queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff;
        sendBuff->connectPort = connectJ5;
        if (uxQueueSpacesAvailable(J5_0_485_Queue)) {
            xQueueSend(J5_0_485_Queue, &Buff, 10);    
        }
    }
    else if (gw485RxBuffer[2] == 6) {
        queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff;
        sendBuff->connectPort = connectJ6;
        if (uxQueueSpacesAvailable(J5_0_485_Queue)) {
            xQueueSend(J5_0_485_Queue, &Buff, 10);    
        }
    }
    else if (gw485RxBuffer[2] == 7) {
        queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff;
        sendBuff->connectPort = connectJ7;
        if (uxQueueSpacesAvailable(J5_0_485_Queue)) {
            xQueueSend(J5_0_485_Queue, &Buff, 10);    
        }
    }
    else if (gw485RxBuffer[2] == 8) {
        queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff;
        sendBuff->connectPort = connectJ8;
        if (uxQueueSpacesAvailable(J5_0_485_Queue)) {
            xQueueSend(J5_0_485_Queue, &Buff, 10);    
        }
    }
    else if (gw485RxBuffer[2] == 9) {
        queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff;
        sendBuff->connectPort = connectJ9;
        if (uxQueueSpacesAvailable(J5_0_485_Queue)) {
            xQueueSend(J5_0_485_Queue, &Buff, 10);    
        }
    }
    else if (gw485RxBuffer[2] == 0) {
        queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff;
        sendBuff->connectPort = connectJ0;
        if (uxQueueSpacesAvailable(J5_0_485_Queue)) {
            xQueueSend(J5_0_485_Queue, &Buff, 10);    
        }
    }

    //清零buff
    state = wait;
    gw485RxBufferIndex = 0;
    return 1;
}

/**
  * @brief  读取寄存器
  * @param
  * @retval
  */
void GW_MsgProcFunc_Read_Register(device_handle device,uint8_t *buff, uint16_t buffLen)
{
    uint16_t Start_Address_16 = (gw485RxBuffer[3] << 8) | gw485RxBuffer[4];
    uint16_t Register_Number_16 = (gw485RxBuffer[5] << 8) | gw485RxBuffer[6];

    /* 读取数据 */
    uint16_t reply_Data_Content[maxReadResAddrLen] = {0};
    for ( uint16_t pos = 0;  pos < Register_Number_16; pos++) {
        for (uint16_t var = 0; var < sizeof(g_RegTblR) / sizeof(SL_RegProcTable); var++) {
            if (g_RegTblR[var].regId == (Start_Address_16 + pos)) {
                reply_Data_Content[pos] = g_RegTblR[var].pRegProc(NULL);
            }
        }
    }
    
    /* 初始化发送内存 */
    uint8_t *Buff = (uint8_t *)pvPortMalloc(8 + 2 * Register_Number_16 + queueUartSendInfoSize);
    queueUartSendInfo *sendBuff = (queueUartSendInfo *)Buff;
    sendBuff->length = 8 + 2 * Register_Number_16;
    sendBuff->data = Buff + sizeof(queueUartSendInfo);

    uint8_t *replay_pack = sendBuff->data;
    /* 起始标志 */
    *(replay_pack)      =  'G';
    *(replay_pack + 1)  =  'W';
    
    /* 功能码 */
    replay_pack += 2;
    *replay_pack = SL_Function_Code_Read_Register;

    /* 回复字节数长度 */
    replay_pack += 1;
    *replay_pack = (uint8_t)((Register_Number_16 * 2) >> 8);
    *(replay_pack + 1) = (uint8_t)(Register_Number_16 * 2);

    /* 回复数据内容 */
    replay_pack += 2;
    for (uint8_t var = 0; var < Register_Number_16 * 2; var++) {
        if (0 == (var & 0x01)) {
            *(replay_pack + var) = (uint8_t)(reply_Data_Content[var / 2] >> 8);
        } else {
            *(replay_pack + var) = (uint8_t)(reply_Data_Content[var / 2]);
        }
    }

    /* 校验位 */
    replay_pack += Register_Number_16 * 2;
    uint16_t packLen = 2 + 1 + 2 + Register_Number_16 * 2 + 3;
    uint16_t crc_temp = checkModebusCrc(sendBuff->data, packLen - 3);
    *replay_pack = (uint8_t)(crc_temp >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)crc_temp;

    /* 结束标志 */
    replay_pack += 1;
    *replay_pack = 0x16;

    /* 队列中有空间，则将发送数据 */
    if (uxQueueSpacesAvailable(upward_uart_Queue)) {
        xQueueSend(upward_uart_Queue, &Buff, 10);    
    }
}

/**
  * @brief  写入寄存器
  * @param
  * @retval
  */
void GW_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen)
{
    uint16_t Register_Start_Address = (gw485RxBuffer[3] << 8) | gw485RxBuffer[4];
    uint16_t Register_Number = (gw485RxBuffer[5] << 8) | gw485RxBuffer[6];

    /* 将指令中的数据读取出来 */
    uint16_t content[maxWriteResAddrLen] = {0};
    for (uint16_t var = 0; var < Register_Number; var++) {
        content[var] = gw485RxBuffer[14 + 2 * var] << 8 | gw485RxBuffer[14 + 2 * var + 1];
    }

    /* 将数据写入到寄存器中 */
    for ( uint16_t pos = 0;  pos < Register_Number; pos++) {
        for (uint16_t i = 0; i < sizeof(g_RegTblW) / sizeof(SL_RegProcTable); i++) {
            // debug_printf("g_RegTblW[i].regId : %x \n", g_RegTblW[i].regId);
            // debug_printf("Register_Start_Address : %x \n", (Register_Start_Address + pos));
            if (g_RegTblW[i].regId == (Register_Start_Address + pos)) {
                g_RegTblW[i].pRegProc(&content[pos]);
            }
        }
    }
}

/**
  * @brief  下发配置文件
  * @param
  * @retval
  */
void GW_MsgProcFunc_Distribution_Profile(device_handle device, void *pMsg, uint32_t MsgLen)
{
    log_info("in GW_MsgProcFunc_Distribution_Profile\n");
}

/**
  * @brief  读取配置文件
  * @param
  * @retval
  */
void GW_MsgProcFunc_Read_Profile(device_handle device, void *pMsg, uint32_t MsgLen)
{
    log_info("in GW_MsgProcFunc_Read_Profile\n");
}

/**
  * @brief  状态机函数
  * @param 
  * @retval 
  */
void stateMachine(device_handle device)
{
    if (state == wait) {
        if (analysisWait() == TRUE) {
            gw485RxTime = xTaskGetTickCount();
        }
    }

    else if (state == startFlagGW) {
        analysisStartFlagGW();
    }

    else if (state == functionCodeGW) {
        analysisFunctionCodeGW();
    }

    else if (state == readRegStartAddressGW) {
        analysisReadRegStartAddressGW();
    }

    else if (state == readRegStartNumberGW) {
        analysisReadRegStartNumberGW();
    }

    else if (state == crcCheckBitGW) {
        analysisCrcCheckBitGW();
    }

    else if (state == endFlagGW) {
        analysisEndFlagGW(device);
    }

    else if (state == writeRegStartAddressGW) {
        analysisWriteRegStartAddressGW();
    }

    else if (state == writeRegStartNumberGW) {
        analysisWriteRegStartNumberGW();
    }

    else if (state == cfgFramesNumGW) {
        analysisCfgFramesNumGW();
    }

    else if (state == cfgLengthGW) {
        analysisCfgLengthGW();
    }

    else if (state == readCfgLengthGW) {
        analysisReadCfgLengthGW();
    }

    else if (state == startFlagSL) {
        analysisStartFlagSL();
    }

    else if (state == portSL) {
        analysisPortSL();
    }

    else if (state == lengthSL) {
        analysisLengthSL();
    }

    else if (state == endFlagSL) {
        analysisEndFlagSL();
    }
}


/**
  * @brief  modbus的crc校验
  * @param  *arr_buff   需要校验的数据
  *         len         数据长度
  * @retval crc         校验的结果
  */
uint16_t checkModebusCrc(uint8_t *arr_buff, uint8_t len)
{
    uint16_t crc = 0xFFFF;
    uint16_t i, j;
    for (j = 0; j < len; ++j) {
        crc = crc ^ (*arr_buff++);
        for (i = 0; i < 8; ++i) {
            if ((crc&0x0001) > 0) {
                crc = crc >> 1;
                crc = crc ^ 0xa001;
            }
            else {
                crc = crc >> 1;
            }
        }
    }
    return crc;
}

/**
  * @brief  得到两次获取节拍的差值
  * @param  lastTick  上次获取的节拍值
  * @retval
  */
uint32_t getTickDiff(uint32_t lastTick)
{
    int64_t temp;
    temp = xTaskGetTickCount() - lastTick;

    /* 节拍值超过最大值后重新计数 */
    if (temp < 0) {
        temp = portMAX_DELAY - lastTick + xTaskGetTickCount();
    }
    
    return temp;
}

/**
  * @brief  解析智能模块发送来的数据
  * @param  device 用于接收智能模块发送来的数据的串口设备
  * @retval
  */
void upwardUartDataAnalysis(device_handle device)
{
    /* 每次函数最多执行10ms */
    static uint32_t tickstart = 0U;
    tickstart = xTaskGetTickCount();

    /* 2S未解析出来一帧数据，将数据清零 */
    if (getTickDiff(gw485RxTime) >= tick_2S) {
        gw485RxTime = xTaskGetTickCount();
        gw485RxBufferIndex = 0;
        state = wait;
    }

    while (uart_dev_char_present(device) == 1 && ((xTaskGetTickCount() - tickstart) < 5)) {
        gw485RxBuffer[gw485RxBufferIndex++] = uart_dev_in_char(device);
        stateMachine(device);
    }

    if (uart_dev_char_present(device) != 1 && state != wait) {        
        stateMachine(device);
    }
}
