#include "svc_ir_protocol.h"
#include "../../bat/svc/svc_bat.h"
#include "../../log/svc/svc_log.h"
#include "../../com/svc/svc_com.h"
#include "../../flash/svc/svc_flash.h"
#include "../../timer/svc/svc_timer.h"
#include "../../cloud/svc/svc_cloud.h"
#include "../../cloud/svc/svc_cloud_protocol.h"
#include "../../util/util_data.h"
#include "../../util/util_crc.h"

#include "../../ota/svc/svc_ota.h"

#include "../../util/util_time.h"
#include "../../rtc/svc/svc_rtc.h"
#include "../../ir/svc/svc_ir_uart.h"
#include "../../nb/svc/svc_nb_core.h"
#include "../../pulse/svc/svc_pulse_protocol.h"
#include "../../pulse/svc/svc_pulse.h"
#include "../../iwdg/bsp/bsp_iwdg.h"
S_Ir_Data s_ir_data;

static void Svc_Ir_Parse_Cmd_Code(gw_u8 *data, gw_u16 len);
static void Svc_Cmd41_Query_Special_Para(gw_u8 *data, gw_u16 len);
static void Svc_Cmd42_Query_Normal_Para(gw_u8 *data, gw_u16 len);
static void Svc_Cmd81_Set_Special_Para(gw_u8 *data, gw_u16 len);
static void Svc_Cmd82_Set_Normal_Para(gw_u8 *data, gw_u16 len);
static void Svc_CmdC0_Operate(gw_u8 *data, gw_u16 len);
static void Svc_CmdC1_Query_History_Data(gw_u8 *data, gw_u16 len);
static void Svc_CmdC3_Maitain(gw_u8 *data, gw_u16 len);
static void Svc_Cmd43_Query_Pulse_Para(gw_u8 *data, gw_u16 len);
static void Svc_Cmd83_Set_Pulse_Para(gw_u8 *data, gw_u16 len);
static void Svc_CmdA0_Issue_Ota(gw_u8 *data, gw_u16 len);
static void Svc_CmdA1_Request_Ota(gw_u8 *data, gw_u16 len);
static void Svc_CmdA2_Request_Ota_Data(gw_u8 *data, gw_u16 len);

static void Svc_Ir_Func0003_Network_Info(gw_u8 *data);
static void Svc_Ir_Func0004_Product_Id(gw_u8 *data);
static void Svc_Ir_Func0007_Inform_Key(gw_u8 *data);
static void Svc_Ir_Func0002_Meter_Info(gw_u8 *data);
static void Svc_Ir_Func0006_Device_Time(gw_u8 *data);
static void Svc_Ir_Func000A_Work_Mode(gw_u8 *data);
static void Svc_Ir_Func1001_Power_State(gw_u8 *data);
static void Svc_Ir_Func1120_Usage_Info(gw_u8 *data);
static void Svc_Ir_Func1420_Reportcycle(gw_u8 *data);
static void Svc_Ir_Func1423_Inform_Reliable_Info(gw_u8 *data);
static void Svc_Ir_Func1424_Err_Flow(gw_u8 *data);
static void Svc_Ir_Func1425_Normal_Para_Info(gw_u8 *data);
static void Svc_Ir_Func1C01_Sync_DialNum(gw_u8 *data);
static void Svc_Ir_Func1C02_Clear_The_Fault(gw_u8 *data);
static void Svc_Ir_Func1151_Realtime_Usage(gw_u8 *data);
static void Svc_Ir_Func1502_Query_Usage(gw_u8 *data);
static void Svc_Ir_Func1504_Query_Usage(gw_u8 *data);
static void Svc_Ir_Creat_Func1C01(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Func1141_Dense_Usage_Info(gw_u8 *data);
static void Svc_Ir_Func1608_Meter_State(gw_u8 *data);
static void Svc_Ir_Func1609_Time_Period_Event(gw_u8 *data);
static void Svc_Ir_Func160A_Lateset_Event(gw_u8 *data);

static void Svc_Ir_Func3001_Pulse_Info(gw_u8 *data);
static void Svc_Ir_Func3002_Pulse_Baudrate(gw_u8 *data);
static void Svc_Ir_Func3003_Pulse_WorkMode(gw_u8 *data);
static void Svc_Ir_Func3004_Pulse_Time_Calibrate(gw_u8 *data);
static void Svc_Ir_Func3005_Pulse_Runtime(gw_u8 *data);
static void Svc_Ir_Func3010_Pulse_Pipe_Para(gw_u8 *data);
static void Svc_Ir_Func3010_Pulse_Pipe_Para(gw_u8 *data);
static void Svc_Ir_Func3011_Pulse_Start_Flow(gw_u8 *data);
static void Svc_Ir_Func3012_Pulse_Zero(gw_u8 *data);
static void Svc_Ir_Func3013_Pulse_Correct_Para(gw_u8 *data);
static void Svc_Ir_Func3014_Pulse_ZeroMode(gw_u8 *data);
static void Svc_Ir_Func30A0_Pulse_Day_Historical(gw_u8 *data);
static void Svc_Ir_Func30A1_Pulse_Month_Historical(gw_u8 *data);
static void Svc_Ir_Func302A_Pulse_Clear_Codata(gw_u8 *data);
static void Svc_Ir_Func302C_Pulse_Clear_All_Data(gw_u8 *data);
// static void Svc_Ir_Func30A2_Pulse_Pulse_Debug_Enable(gw_u8 *data);

static E_Result_State Svc_Creat_Ir_Frame(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Head_Field(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Data_Field(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Check_Field(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_User_Data(S_Ir_Data *ps_ir_data);

static void Svc_Ir_Creat_Cmd41(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Cmd42(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_CmdC1(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_CmdC3(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_CmdA1(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_CmdA2(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Cmd43(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Cmd83(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func0003(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func0007(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func0004(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func0002(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func0006(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1001(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1120(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1420(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1423(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1424(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1425(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1151(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1502(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1504(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1141(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1608(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func1609(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func160A(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func3001(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func3002(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func3003(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func3005(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func3010(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func3011(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func3012(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func3013(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func3014(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func30A0(S_Ir_Data *ps_ir_data);
static void Svc_Ir_Creat_Func30A1(S_Ir_Data *ps_ir_data);

static void Svc_Pulse_Cmd41_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result);
static void Svc_Pulse_Cmd42_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result);
static void Svc_Pulse_Cmd81_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result);
static void Svc_Pulse_Cmd82_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result);
static void Svc_Pulse_CmdC1_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result);
static void Svc_Pulse_CmdC3_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result);

/**************************************接收数据解析******************************************/
void Svc_Ir_Protocol_Parse(uint8_t *data, uint16_t len)
{
    if (len < IR_PROTOCOL_MIN_LEN) // 保证数据长度要大于协议的最短长度 ! ! !
    {
        Svc_Log_Printf(LOG_ERROR, "%s : incorrect data len", __FUNCTION__);
        return;
    }
    gw_u32 u32LeadCode;
    u32LeadCode = ((data[0] & 0x000000FF) << 24 | (data[1] & 0x000000FF) << 16 | (data[2] & 0x000000FF) << 8 | (data[3] & 0x000000FF));
    if (u32LeadCode != MAIN_LEAD_CODE)
    {
        Svc_Log_Printf(LOG_ERROR, "%s : lead code error", __FUNCTION__);
        return;
    }
    if ((data[4] != IR_FRAME_HEAD) || (data[len - 1]) != IR_FRAME_TAIL)
    {
        Svc_Log_Printf(LOG_ERROR, "%s : incomplete data frame", __FUNCTION__);
        return;
    }
    S_Flash_Data *ps_flash_data;
    S_Flash_Device_Security *s_security;
    ps_flash_data = Svc_Flash_Get_Data();
    s_security = &ps_flash_data->s_security;
    uint16_t s16OutLen;
    s16OutLen = Get_Original_Data(&data[4], len - 4, data);
    uint16_t index = 0;
    if (data[index] == IR_PROTOCOL_VER)
    {
        index++;
        uint16_t u16DataLen;
        u16DataLen = ((data[index] & 0x00FF) << 8) | (0x00FF & data[index + 1]); // 数据长度
        index = index + 2;
        // 长度校验
        uint16_t u16LenIndex = index;
        if ((u16LenIndex + u16DataLen + 2) != s16OutLen)
        {
            Svc_Log_Printf(LOG_ERROR, "%s : data len err", __FUNCTION__);
            return;
        }
        // crc校验
        uint16_t u16Crc;
        u16Crc = ((data[s16OutLen - 2] & 0x00FF) << 8) | (0x00FF & data[s16OutLen - 1]);
        uint16_t u16CalCrc;
        u16CalCrc = Util_Crc16(&data[u16LenIndex], u16DataLen);
        if (u16Crc != u16CalCrc)
        {
            Svc_Log_Printf(LOG_ERROR, "%s : crc16 check error:crc(0x%04X),cal_crc(0x%04X)", __FUNCTION__, u16Crc, u16CalCrc);
            return;
        }
        // //序列号校验
        uint8_t pu8ProductId[16] = {0}; // 实际的序列号
        uint8_t pu8ProductIdx[16];      // 接收到的序列号
        uint8_t u8IdLen;
        u8IdLen = sizeof(s_security->pu8MeterNum);
        if (u8IdLen > 16)
        {
            return;
        }
        memcpy(pu8ProductId, &s_security->product_id, u8IdLen); // 序列号不足16位的在末尾补0
        memcpy(pu8ProductIdx, &data[index], 16);
        index = index + 16;
        uint8_t pu80[16] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
        if ((data[index] == 0x41) && (data[index + 1] == 0x00) && (data[index + 2] == 0x04))
        {
            if ((memcmp(pu8ProductIdx, pu80, 16)) != 0) // 命令为读取产品序列号时,需要比对接收到的序列号为AA
            {
                return;
            }
        }
        else
        {
            if ((memcmp(pu8ProductId, pu8ProductIdx, 16)) != 0) // 其他命令需比对序列号 //上位机ASCLL格式
            {
                Svc_Log_Printf(LOG_ERROR, " product id error", __FUNCTION__);
                return;
            }
        }
        Svc_Ir_Set_Keep_Alive_Time(IR_OPEN_TIME); // 一旦接收到数据就置20s
        // 根据命令码解析数据
        Svc_Ir_Parse_Cmd_Code(&data[index], u16DataLen - 16);
    }
    else
    {
        Svc_Log_Printf(LOG_ERROR, "%s : protocol version error", __FUNCTION__);
        return;
    }
}

/**
 * @name: 根据命令码解析数据
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_Ir_Parse_Cmd_Code(gw_u8 *data, gw_u16 len)
{
    gw_u8 cmd;
    cmd = data[0];
    Svc_Log_Printf(LOG_INFO, "%s->cmd:0x%02X", __FUNCTION__, cmd);
    switch (cmd)
    {
    case CMD_41_QUERY_SPECIAL_PARA:
        Svc_Cmd41_Query_Special_Para(data, len);
        break;
    case CMD_42_QUERY_NORMAL_PARA:
        Svc_Cmd42_Query_Normal_Para(data, len);
        break;
    case CMD_81_SET_SPECIAL_PARA:
        Svc_Cmd81_Set_Special_Para(data, len);
        break;
    case CMD_82_SET_NORMAL_PARA:
        Svc_Cmd82_Set_Normal_Para(data, len);
        break;
    case CMD_C0_OPERATE:
        Svc_CmdC0_Operate(data, len);
        break;
    case CMD_C1_QUERY_HISTORY_DATA:
        Svc_CmdC1_Query_History_Data(data, len);
        break;
    case CMD_C3_MAINTAIN:
        Svc_CmdC3_Maitain(data, len);
        break;
    case CMD_43_QUERY_PULSE_PARA:
        Svc_Cmd43_Query_Pulse_Para(data, len);
        break;
    case CMD_83_SET_PULSE_PARA:
        Svc_Cmd83_Set_Pulse_Para(data, len);
        break;
    case CMD_A0_ISSUE_OTA:
        Svc_CmdA0_Issue_Ota(data, len);
        break;
    case CMD_A1_REQUEST_OTA:
        Svc_CmdA1_Request_Ota(data, len);
        break;
    case CMD_A2_REQUEST_OTA_DATA:
        Svc_CmdA2_Request_Ota_Data(data, len);
        break;
    default:
        break;
    }
}

/*************************************命令码解析******************************************/
/**
 * @name:查询设备特殊参数
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_Cmd41_Query_Special_Para(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Ir_Protocol_Send_Cmd(CMD_41_QUERY_SPECIAL_PARA, IR_ERROR, COMM_03_ERROR_PARA_FORMAT);
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    gw_u16 u16FuncCode = ((data[1] & 0x00FF) << 8) | (0x00FF & data[2]);
    switch (u16FuncCode)
    {
    case IR_0003_NETWORK_INFO:
        Svc_Ir_Func0003_Network_Info(data);
        break;
    case IR_0004_PRODUCT_ID:
        Svc_Ir_Func0004_Product_Id(data);
        break;
    case IR_0007_INFORM_KEY:
        Svc_Ir_Func0007_Inform_Key(data);
        break;
    case IR_000A_WORK_MODE:
        Svc_Ir_Func000A_Work_Mode(data);
        break;
    default:
        Svc_Ir_Protocol_Send_Cmd(CMD_41_QUERY_SPECIAL_PARA, IR_ERROR, COMM_04_ERROR_CMD_NO_SUPPORT);
        break;
    }
}

/**
 * @name:查询设备普通参数
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_Cmd42_Query_Normal_Para(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Ir_Protocol_Send_Cmd(CMD_42_QUERY_NORMAL_PARA, IR_ERROR, COMM_03_ERROR_PARA_FORMAT);
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    gw_u16 u16FuncCode = ((data[1] & 0x00FF) << 8) | (0x00FF & data[2]);
    switch (u16FuncCode)
    {
    case IR_0002_METER_INFO:
        Svc_Ir_Func0002_Meter_Info(data);
        break;
    case IR_0006_DEVICE_TIME:
        Svc_Ir_Func0006_Device_Time(data);
        break;
    case IR_1001_POWER_STATE:
        Svc_Ir_Func1001_Power_State(data);
        break;
    case IR_1120_USAGE_INFO:
        Svc_Ir_Func1120_Usage_Info(data);
        break;
    case IR_1420_REPORTCYCLE:
        Svc_Ir_Func1420_Reportcycle(data);
        break;
    case IR_1423_INFORM_RELIABLE_INFO:
        Svc_Ir_Func1423_Inform_Reliable_Info(data);
        break;
    case IR_1424_ERR_FLOW:
        Svc_Ir_Func1424_Err_Flow(data);
        break;
    case IR_1425_NORMAL_PARA_INFO:
        Svc_Ir_Func1425_Normal_Para_Info(data);
        break;
    default:
        Svc_Ir_Protocol_Send_Cmd(CMD_42_QUERY_NORMAL_PARA, IR_ERROR, COMM_04_ERROR_CMD_NO_SUPPORT);
        break;
    }
}

/**
 * @name:设置设备特殊参数
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_Cmd81_Set_Special_Para(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Ir_Protocol_Send_Cmd(CMD_81_SET_SPECIAL_PARA, IR_ERROR, COMM_03_ERROR_PARA_FORMAT);
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    gw_u16 u16FuncCode = ((data[1] & 0x00FF) << 8) | (0x00FF & data[2]);
    switch (u16FuncCode)
    {
    case IR_0003_NETWORK_INFO:
        Svc_Ir_Func0003_Network_Info(data);
        break;
    case IR_0004_PRODUCT_ID:
        Svc_Ir_Func0004_Product_Id(data);
        break;
    case IR_000A_WORK_MODE:
        Svc_Ir_Func000A_Work_Mode(data);
        break;
    default:
        Svc_Ir_Protocol_Send_Cmd(CMD_81_SET_SPECIAL_PARA, IR_ERROR, COMM_04_ERROR_CMD_NO_SUPPORT);
        break;
    }
}

/**
 * @name:设置设备普通参数
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_Cmd82_Set_Normal_Para(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Ir_Protocol_Send_Cmd(CMD_82_SET_NORMAL_PARA, IR_ERROR, COMM_03_ERROR_PARA_FORMAT);
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    gw_u16 u16FuncCode = ((data[1] & 0x00FF) << 8) | (0x00FF & data[2]);
    switch (u16FuncCode)
    {
    case IR_0006_DEVICE_TIME:
        Svc_Ir_Func0006_Device_Time(data);
        break;
    case IR_1420_REPORTCYCLE:
        Svc_Ir_Func1420_Reportcycle(data);
        break;
    case IR_1423_INFORM_RELIABLE_INFO:
        Svc_Ir_Func1423_Inform_Reliable_Info(data);
        break;
    case IR_1424_ERR_FLOW:
        Svc_Ir_Func1424_Err_Flow(data);
        break;
    case IR_1425_NORMAL_PARA_INFO:
        Svc_Ir_Func1425_Normal_Para_Info(data);
        break;
    default:
        Svc_Ir_Protocol_Send_Cmd(CMD_82_SET_NORMAL_PARA, IR_ERROR, COMM_04_ERROR_CMD_NO_SUPPORT);
        break;
    }
}

/**
 * @name:业务操作
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_CmdC0_Operate(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Ir_Protocol_Send_Cmd(CMD_C0_OPERATE, IR_ERROR, COMM_03_ERROR_PARA_FORMAT);
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    gw_u16 u16FuncCode = ((data[1] & 0x00FF) << 8) | (0x00FF & data[2]);
    switch (u16FuncCode)
    {
    case IR_1C01_SYNC_DIAL_NUM:
        Svc_Ir_Func1C01_Sync_DialNum(data);
        break;
    case IR_1C02_CLEAR_THE_FAULT:
        Svc_Ir_Func1C02_Clear_The_Fault(data);
        break;
    default:
        Svc_Ir_Protocol_Send_Cmd(CMD_C0_OPERATE, IR_ERROR, COMM_04_ERROR_CMD_NO_SUPPORT);
        break;
    }
}

/**
 * @name:查询历史数据
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_CmdC1_Query_History_Data(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Ir_Protocol_Send_Cmd(CMD_C1_QUERY_HISTORY_DATA, IR_ERROR, COMM_03_ERROR_PARA_FORMAT);
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    gw_u16 u16FuncCode = ((data[1] & 0x00FF) << 8) | (0x00FF & data[2]);
    switch (u16FuncCode)
    {
    case IR_1151_REALTIME_USAGE_INFO:
        Svc_Ir_Func1151_Realtime_Usage(data);
        break;
    case IR_1502_QUERY_USAGE:
        Svc_Ir_Func1502_Query_Usage(data);
        break;
    case IR_1504_QUERY_USAGE:
        Svc_Ir_Func1504_Query_Usage(data);
        break;
    default:
        Svc_Ir_Protocol_Send_Cmd(CMD_C1_QUERY_HISTORY_DATA, IR_ERROR, COMM_04_ERROR_CMD_NO_SUPPORT);
        break;
    }
}

/**
 * @name:运维操作
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_CmdC3_Maitain(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Ir_Protocol_Send_Cmd(CMD_C3_MAINTAIN, IR_ERROR, COMM_03_ERROR_PARA_FORMAT);
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    gw_u16 u16FuncCode = ((data[1] & 0x00FF) << 8) | (0x00FF & data[2]);
    switch (u16FuncCode)
    {
    case IR_1141_DENSE_USAGE_INFO:
        Svc_Ir_Func1141_Dense_Usage_Info(data);
        break;
    case IR_1608_METER_STATE:
        Svc_Ir_Func1608_Meter_State(data);
        break;
    case IR_1609_TIME_PERIOD_EVENT:
        Svc_Ir_Func1609_Time_Period_Event(data);
        break;
    case IR_160A_LATESET_EVENT_LOG:
        Svc_Ir_Func160A_Lateset_Event(data);
        break;
    default:
        Svc_Ir_Protocol_Send_Cmd(CMD_C3_MAINTAIN, IR_ERROR, COMM_04_ERROR_CMD_NO_SUPPORT);
        break;
    }
}

/**
 * @name:查询计量模组参数
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_Cmd43_Query_Pulse_Para(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_ERROR, COMM_03_ERROR_PARA_FORMAT);
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    gw_u16 u16FuncCode = ((data[1] & 0x00FF) << 8) | (0x00FF & data[2]);
    switch (u16FuncCode)
    {
    case IR_3001_PULSE_INFO:
        Svc_Ir_Func3001_Pulse_Info(data);
        break;
    case IR_3002_PULSE_BAUDRATE:
        Svc_Ir_Func3002_Pulse_Baudrate(data);
        break;
    case IR_3003_PULSE_WORKMODE:
        Svc_Ir_Func3003_Pulse_WorkMode(data);
        break;
    case IR_3005_PULSE_RUNTIME:
        Svc_Ir_Func3005_Pulse_Runtime(data);
        break;
    case IR_3010_PULSE_PIPE_PARA:
        Svc_Ir_Func3010_Pulse_Pipe_Para(data);
        break;
    case IR_3011_PULSE_START_FLOW:
        Svc_Ir_Func3011_Pulse_Start_Flow(data);
        break;
    case IR_3012_PULSE_ZERO:
        Svc_Ir_Func3012_Pulse_Zero(data);
        break;
    case IR_3013_PULSE_CORRECT_PARA:
        Svc_Ir_Func3013_Pulse_Correct_Para(data);
        break;
    case IR_30A0_PULSE_DAY_HISTORICAL:
        Svc_Ir_Func30A0_Pulse_Day_Historical(data);
        break;
    case IR_30A1_PULSE_MONTH_HISTORICAL:
        Svc_Ir_Func30A1_Pulse_Month_Historical(data);
        break;
    default:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_ERROR, COMM_04_ERROR_CMD_NO_SUPPORT);
        break;
    }
}

/**
 * @name:设置计量模组参数
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_Cmd83_Set_Pulse_Para(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_ERROR, COMM_03_ERROR_PARA_FORMAT);
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    gw_u16 u16FuncCode = ((data[1] & 0x00FF) << 8) | (0x00FF & data[2]);
    switch (u16FuncCode)
    {
    case IR_3002_PULSE_BAUDRATE:
        Svc_Ir_Func3002_Pulse_Baudrate(data);
        break;
    case IR_3003_PULSE_WORKMODE:
        Svc_Ir_Func3003_Pulse_WorkMode(data);
        break;
    case IR_3004_PULSE_TIME_CALIBRATE:
        Svc_Ir_Func3004_Pulse_Time_Calibrate(data);
        break;
    case IR_3010_PULSE_PIPE_PARA:
        Svc_Ir_Func3010_Pulse_Pipe_Para(data);
        break;
    case IR_3011_PULSE_START_FLOW:
        Svc_Ir_Func3011_Pulse_Start_Flow(data);
        break;
    case IR_3013_PULSE_CORRECT_PARA:
        Svc_Ir_Func3013_Pulse_Correct_Para(data);
        break;
    case IR_3014_PULSE_ZEROMODE:
        Svc_Ir_Func3014_Pulse_ZeroMode(data);
        break;
    case IR_302A_PULSE_CLEAR_CODATA:
        Svc_Ir_Func302A_Pulse_Clear_Codata(data);
        break;
    case IR_302C_PULSE_CLEAR_ALL_DATA:
        Svc_Ir_Func302C_Pulse_Clear_All_Data(data);
        break;
    // case IR_30A2_PULSE_DEBUG_ENABLE:
    //     Svc_Ir_Func30A2_Pulse_Pulse_Debug_Enable(data);
    //     break;
    default:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_ERROR, COMM_04_ERROR_CMD_NO_SUPPORT);
        break;
    }
}

/**
 * @name:服务器下发设备 OTA 升级
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_CmdA0_Issue_Ota(gw_u8 *data, gw_u16 len)
{ /*data[0]命令码*/
    if (len < 3)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    Svc_Ota_Clear_Event(E_OTA_EVENT_REQUEST_OTA);
    Svc_Ota_Clear_Event(E_OTA_EVENT_REQUEST_OTA_DATA);
    S_Ota *s_ota;
    s_ota = Svc_Ota_Get_Data();
    S_Flash_Data *ps_flash_data;
    ps_flash_data = Svc_Flash_Get_Data();
    gw_u8 u8index = 1;
    gw_u8 version[2];
    version[0] = data[u8index];
    version[1] = data[u8index + 1];
    u8index = u8index + 2;
    if ((version[0] == ps_flash_data->s_security.main_version) && (version[1] == ps_flash_data->s_security.sub_version)) // 版本无变化不升级
    {
        Svc_Ir_Protocol_Send_Cmd(CMD_A0_ISSUE_OTA, IR_OTA_REQURST_DATA, COMM_02_ERROR_PARA);
        return;
    }
    memcpy(s_ota->s_para.u8softversion, version, 2); // 新软件版本号
    /*固件长度*/
    s_ota->s_para.u32FirmwareLen = (data[u8index] & 0x000000FF) << 24 | (data[u8index + 1] & 0x000000FF) << 16 | (data[u8index + 2] & 0x000000FF) << 8 | (data[u8index + 3] & 0x000000FF);
    u8index = u8index + 4;
    memcpy(s_ota->s_para.u8Md5, &data[u8index], 16); // 固件MD5
    u8index += 16;
    Svc_Ir_Protocol_Send_Cmd(CMD_A0_ISSUE_OTA, IR_OTA_REQURST_DATA, COMM_00_NORMAL);
    Svc_Timer_Delay_Ms(500); // 此处延时是为了配合OTA上位机收发机制
    Svc_Ota_Post_Event(E_OTA_EVENT_REQUEST_OTA);
}

/**
 * @name:表计请求 OTA 升级
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_CmdA1_Request_Ota(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    gw_u8 u8index = 1;
    Svc_Ota_Clear_Event(E_OTA_EVENT_REQUEST_OTA_DATA);
    S_Ota *s_ota;
    s_ota = Svc_Ota_Get_Data();
    E_Comm_Result e_com_result;
    e_com_result = (E_Comm_Result)data[u8index];
    u8index++;
    if (e_com_result == COMM_00_NORMAL)
    {
        memcpy(s_ota->s_para.u8softversion, &data[u8index], 2);
        u8index += 2;
        s_ota->s_para.u32FirmwareLen = (data[u8index] & 0x000000FF) << 24 | (data[u8index + 1] & 0x000000FF) << 16 | (data[u8index + 2] & 0x000000FF) << 8 | (data[u8index + 3] & 0x000000FF);
        u8index = u8index + 4;
        memcpy(s_ota->s_para.u8Md5, &data[u8index], 16);
        Svc_Ota_Post_Event(E_OTA_EVENT_REQUEST_OTA_DATA);
        s_ota->startflag = 1;
        Save_Firmware_Para();
        Svc_Timer_Delay_Ms(50); // 此处延时是为了配合OTA上位机收发机制
    }
    Svc_Ota_Clear_Event(E_OTA_EVENT_REQUEST_OTA);
}

/**
 * @name:表计请求 OTA 固件数据
 * @param {gw_u8*} data
 * @param {gw_u16} len
 * @return {*}
 * @note:
 */
static void Svc_CmdA2_Request_Ota_Data(gw_u8 *data, gw_u16 len)
{
    if (len < 3)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->no function code", __FUNCTION__);
        return;
    }
    S_Ota *s_ota;
    s_ota = Svc_Ota_Get_Data();
    gw_u8 u8index = 1;
    E_Comm_Result e_com_result;
    e_com_result = (E_Comm_Result)data[u8index];
    u8index++;
    s_ota->u32OtaStartAddr = (data[u8index] & 0x000000FF) << 24 | (data[u8index + 1] & 0x000000FF) << 16 | (data[u8index + 2] & 0x000000FF) << 8 | (data[u8index + 3] & 0x000000FF);
    u8index = u8index + 4;
    s_ota->u32OtaEndAddr = (data[u8index] & 0x000000FF) << 24 | (data[u8index + 1] & 0x000000FF) << 16 | (data[u8index + 2] & 0x000000FF) << 8 | (data[u8index + 3] & 0x000000FF);
    u8index = u8index + 4;
    Svc_Ota_Clear_Event(E_OTA_EVENT_REQUEST_OTA_DATA);
    if (e_com_result == COMM_00_NORMAL)
    {
        if (s_ota->u32RemainLen <= OTA_PACKGE_SIZE)
        {
            memcpy(s_ota->buff, &data[u8index], s_ota->u32RemainLen);
            u8index = u8index + s_ota->u32RemainLen;
            s_ota->u16Crc = (data[u8index] & 0x00FF) << 8 | (data[u8index + 1] & 0x00FF);
            Svc_Ota_Write_Firmware(s_ota->buff, s_ota->u16PackNum, s_ota->u32RemainLen);
            // if (Svc_Ota_Write_Firmware(s_ota->buff, s_ota->u16PackNum, s_ota->u32RemainLen) == E_STATE_ERROR)
            //     Svc_Ota_Post_Event(E_OTA_EVENT_REQUEST_OTA_DATA);
        }
        else
        {
            memcpy(s_ota->buff, &data[u8index], OTA_PACKGE_SIZE);
            u8index = u8index + OTA_PACKGE_SIZE;
            s_ota->u16Crc = (data[u8index] & 0x00FF) << 8 | (data[u8index + 1] & 0x00FF);
            Svc_Ota_Write_Firmware(s_ota->buff, s_ota->u16PackNum, OTA_PACKGE_SIZE);
            // if (Svc_Ota_Write_Firmware(s_ota->buff, s_ota->u16PackNum, OTA_PACKGE_SIZE) == E_STATE_ERROR)
            //     Svc_Ota_Post_Event(E_OTA_EVENT_REQUEST_OTA_DATA);
        }
        Svc_Timer_Delay_Ms(100);
        // if (s_ota->u8Err > 5)
        // {
        //     Svc_Ota_Clear_Event(E_OTA_EVENT_REQUEST_OTA_DATA);
        // }
        // return;
    }
    // s_ota->u8Err++;
    // if (s_ota->u8Err > 5)
    // {
    //     Svc_Ota_Clear_Event(E_OTA_EVENT_REQUEST_OTA_DATA);
    // }
    // Svc_Ota_Post_Event(E_OTA_EVENT_REQUEST_OTA_DATA);
}

/**************************************功能片段解析***************************************/
/**
 * @brief: 功能片段0003-网络信息
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func0003_Network_Info(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    gw_u16 u16len;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;

    S_Flash_Data *ps_flash_data;
    S_Flash_Nb_Info *s_nb_info;
    ps_flash_data = Svc_Flash_Get_Data();
    s_nb_info = &ps_flash_data->s_para.s_nb_info;

    if (cmd_code == CMD_81_SET_SPECIAL_PARA)
    {
        if (data[u8index] == 0x01)
        {
            u8index++;
            u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
            u8index += 2;
            if (u16len < 11)
            {
                comm_result = COMM_03_ERROR_PARA_FORMAT;
            }
            else
            {
                gw_u8 ServerIp[32];
                gw_u8 Apn[32];
                gw_u16 u16Port;

                memcpy(ServerIp, s_nb_info->pu8ServerIp, 32); // 防止存储失败内存被修改

                memset((char *)&s_nb_info->pu8ServerIp, 0, 32);
                u16Port = ((data[u8index + 4] & 0x00FF) << 8) | (0x00FF & data[u8index + 5]);
                sprintf((char *)&s_nb_info->pu8ServerIp, "%d.%d.%d.%d,%u", data[u8index], data[u8index + 1], data[u8index + 2], data[u8index + 3], u16Port);
                u8index += 6;

                gw_u8 apn_len;
                apn_len = s_nb_info->apn_len;
                memcpy(Apn, s_nb_info->pu8Apn, apn_len);

                memset((char *)&s_nb_info->pu8Apn, 0, 32);
                memcpy(s_nb_info->pu8Apn, &data[u8index + 1], data[u8index]);
                u8index += data[u8index] + 1;

                if (Svc_Flash_Write_Device_Para(&ps_flash_data->s_para) == E_STATE_ERROR)
                {                                                 // flash异常，无法写入
                    memcpy(s_nb_info->pu8ServerIp, ServerIp, 32); // 存储失败，回退
                    memcpy(s_nb_info->pu8Apn, Apn, apn_len);
                    s_nb_info->apn_len = apn_len;

                    comm_result = COMM_FF_ERROR_SYS;
                }
            }
        }
        else
        {
            comm_result = COMM_02_ERROR_PARA;
        }
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段0004-表号
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func0004_Product_Id(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    gw_u16 u16len;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;

    S_Flash_Data *ps_flash_data;
    S_Flash_Device_Security *s_security;
    ps_flash_data = Svc_Flash_Get_Data();
    s_security = &ps_flash_data->s_security;

    if (cmd_code == CMD_81_SET_SPECIAL_PARA)
    {
        if (data[u8index] == 0x01)
        {
            u8index++;
            u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
            u8index += 2;
            if (u16len != 0x0010)
            {
                comm_result = COMM_03_ERROR_PARA_FORMAT;
            }
            else
            {
                gw_u8 u8product_id[16]; // 防止存储失败内存被修改
                memcpy(u8product_id, s_security->product_id, 16);
                memcpy(s_security->product_id, &data[u8index], 16);
                u8index += 16;
                if (Svc_Flash_Write_Device_Security(&ps_flash_data->s_security) == E_STATE_ERROR)
                {                                                     // flash异常，无法写入
                    memcpy(s_security->product_id, u8product_id, 16); // 存储失败，回退成原来的产品序列号
                    comm_result = COMM_FF_ERROR_SYS;
                }
                memcpy(s_security->pu8MeterNum, s_security->product_id, 16);
                Svc_Flash_Get_UploadTime(ps_flash_data->s_para.pu8DayUploadTime);
            }
        }
        else
        {
            comm_result = COMM_02_ERROR_PARA;
        }
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段0007-密钥
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func0007_Inform_Key(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (cmd_code != CMD_41_QUERY_SPECIAL_PARA)
    {
        comm_result = COMM_04_ERROR_CMD_NO_SUPPORT;
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段000A-操作模式
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func000A_Work_Mode(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    gw_u16 u16len;
    S_Flash_Data *ps_flash_data;
    ps_flash_data = Svc_Flash_Get_Data();
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    if (cmd_code == CMD_81_SET_SPECIAL_PARA)
    {
        if (data[u8index] == 0x01)
        {
            u8index++;
            u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
            u8index += 2;
            if (u16len != 0x0001)
            {
                comm_result = COMM_03_ERROR_PARA_FORMAT;
            }
            else
            {
                ps_flash_data->s_other.e_work_mode = (E_MASTER_WORK_Mode)data[u8index];
                u8index++;

                if (ps_flash_data->s_other.e_work_mode == E_Mode_Calibration) //检定模式需要同步更改模组为校准工作模式
                {
                    ps_pulse->s_pulse_para.ePulseMode = E_Pulse_Mode_Calibra;
                    Svc_Pulse_Protocol_Send_Cmd(CMD_81_SET_DEVICE_INFO, FUNC_03_WORK_MODE);
                }
                else if(ps_flash_data->s_other.e_work_mode == E_Mode_Delivery) //交付模式需要同步模组为休眠模式
                {
                    ps_pulse->s_pulse_para.ePulseMode = E_Pulse_Mode_Sleep;
                    Svc_Pulse_Protocol_Send_Cmd(CMD_81_SET_DEVICE_INFO, FUNC_03_WORK_MODE);
                }
            }
        }
        else
        {
            comm_result = COMM_02_ERROR_PARA;
        }
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段0002-表计信息
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func0002_Meter_Info(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (cmd_code != CMD_42_QUERY_NORMAL_PARA)
    {
        comm_result = COMM_04_ERROR_CMD_NO_SUPPORT;
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段0006-表计时间
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func0006_Device_Time(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    gw_u16 u16len;
    gw_u8 pu8CurTime[6];
    gw_u32 u32Timestamp;

    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (cmd_code == CMD_82_SET_NORMAL_PARA)
    {
        if (data[u8index] == 0x01)
        {
            u8index++;
            u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
            u8index += 2;
            if (u16len != 0x0006)
            {
                comm_result = COMM_03_ERROR_PARA_FORMAT;
            }
            else
            {
                memcpy(pu8CurTime, &data[u8index], 6);
                if (Util_Time_ValidateTime(pu8CurTime))
                {
                    u32Timestamp = Util_Time_Date_To_Timestamp(pu8CurTime);
                    Svc_Cloud_Time_Calibrate(u32Timestamp);
                }
                else
                {
                    comm_result = COMM_02_ERROR_PARA;
                }
            }
        }
        else
        {
            comm_result = COMM_02_ERROR_PARA;
        }
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1001-电源状态
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1001_Power_State(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (cmd_code != CMD_42_QUERY_NORMAL_PARA)
    {
        comm_result = COMM_04_ERROR_CMD_NO_SUPPORT;
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1120-总用量信息
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1120_Usage_Info(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (cmd_code != CMD_42_QUERY_NORMAL_PARA)
    {
        comm_result = COMM_04_ERROR_CMD_NO_SUPPORT;
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1420-上报周期
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1420_Reportcycle(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    gw_u16 u16len;
    gw_s16 upload_cycle;

    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();

    gw_u32 cycle = ps_flash->s_para.u32CommCycle;
    gw_u8 uptime_en = ps_flash->s_para.u8DayUptimeEnable;
    gw_u8 dayuptime[3];
    memcpy(dayuptime, ps_flash->s_para.pu8DayUploadTime, 3);

    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (cmd_code == CMD_82_SET_NORMAL_PARA)
    {
        if (data[u8index] == 0x01)
        {
            u8index++;
            u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
            u8index += 2;
            if (u16len != 0x0005)
            {
                comm_result = COMM_03_ERROR_PARA_FORMAT;
            }
            else
            {
                upload_cycle = ((data[u8index] & 0x00FF) << 8) | (data[u8index + 1] & 0x00FF);
                u8index += 2;
                if (upload_cycle < 5)
                { // 设置为不上报
                    ps_flash->s_para.u32CommCycle = 0;
                    ps_flash->s_para.u8DayUptimeEnable = 1;
                }
                else if ((upload_cycle >= 5) && (upload_cycle < 1440)) // 若间隔<一天，还未采集的数据填充 0，“日上报时间”参数无效
                {
                    ps_flash->s_para.u8DayUptimeEnable = 0;
                    ps_flash->s_para.u32CommCycle = upload_cycle;
                    memcpy(ps_flash->s_para.pu8DayUploadTime, &data[u8index], 3);
                }
                else if (upload_cycle == 1440) // 间隔=一天，按日上报时间
                {
                    ps_flash->s_para.u8DayUptimeEnable = 0;
                    ps_flash->s_para.u32CommCycle = upload_cycle;
                    memcpy(ps_flash->s_para.pu8DayUploadTime, &data[u8index], 3);
                }
                else if (upload_cycle > 1440)
                {
                    if (upload_cycle % 1440 != 0) // 间隔>一天，间隔只能是天的整数倍，数据分多次上传，上报时间点为“日上报时间”
                    {
                        ps_flash->s_para.u8DayUptimeEnable = 0;
                        ps_flash->s_para.u32CommCycle = upload_cycle;
                        memcpy(ps_flash->s_para.pu8DayUploadTime, &data[u8index], 3);
                    }
                    else
                    {
                        comm_result = COMM_02_ERROR_PARA;
                    }
                }
                if (Svc_Flash_Write_Device_Para(&ps_flash->s_para) == E_STATE_ERROR)
                {
                    comm_result = COMM_FF_ERROR_SYS;
                    ps_flash->s_para.u32CommCycle = cycle;
                    ps_flash->s_para.u8DayUptimeEnable = uptime_en;
                    memcpy(ps_flash->s_para.pu8DayUploadTime, dayuptime, 3);
                }
            }
        }
        else
        {
            comm_result = COMM_02_ERROR_PARA;
        }
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1423-通讯可靠机制配置
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1423_Inform_Reliable_Info(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    gw_u16 u16len;

    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();

    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (cmd_code == CMD_82_SET_NORMAL_PARA)
    {
        if (data[u8index] == 0x01)
        {
            u8index++;
            u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
            u8index += 2;
            if (u16len != 0x0003)
            {
                comm_result = COMM_03_ERROR_PARA_FORMAT;
            }
            else
            {
                u8index += 2; // 连接失败后重试间隔（20分钟，不可修改）
                if (data[u8index] <= 4)
                { // 连接最大重试次数（0-4次）
                    gw_u8 u8cnt = ps_flash->s_para.u8ReSendCnt;
                    ps_flash->s_para.u8ReSendCnt = data[u8index];
                    if (Svc_Flash_Write_Device_Para(&ps_flash->s_para) == E_STATE_ERROR)
                    {
                        comm_result = COMM_FF_ERROR_SYS;
                        ps_flash->s_para.u8ReSendCnt = u8cnt;
                    }
                }
                else
                {
                    comm_result = COMM_02_ERROR_PARA;
                }
            }
        }
        else
        {
            comm_result = COMM_02_ERROR_PARA;
        }
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1424-异常流量检测配置
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1424_Err_Flow(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    gw_u16 u16len;

    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    S_Flash_Data temp_data;
    memcpy(&temp_data, &ps_flash->s_para, sizeof(S_Flash_Device_Para));

    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (cmd_code == CMD_82_SET_NORMAL_PARA)
    {
        if (data[u8index] == 0x01)
        {
            u8index++;
            u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
            u8index += 2;
            if (u16len != 0x000C)
            {
                comm_result = COMM_03_ERROR_PARA_FORMAT;
            }
            else
            {
                gw_u16 LargeFlowThreshold = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
                if (LargeFlowThreshold < 2000)
                {
                    comm_result = COMM_02_ERROR_PARA;
                }
                else
                {
                    ps_flash->s_para.u16LargeFlowThreshold = LargeFlowThreshold; // 过流分界点
                    u8index += 2;
                    ps_flash->s_para.u16SmallFlowThreshold = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]); // 小流分界点
                    u8index += 2;
                    ps_flash->s_para.u16ReverseFlowThreshold = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]); // 反流分界点
                    u8index += 2;
                    ps_flash->s_para.u16LargeFlowContinue = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]); // 过流持续流量
                    u8index += 2;
                    ps_flash->s_para.u16SmallFlowContinue = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]); // 小流持续流量
                    u8index += 2;
                    ps_flash->s_para.u16ReverseFlowDuration = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]); // 反流持续流量
                    u8index += 2;
                    if (Svc_Flash_Write_Device_Para(&ps_flash->s_para) == E_STATE_ERROR)
                    {
                        comm_result = COMM_FF_ERROR_SYS;
                        memcpy(&ps_flash->s_para, &temp_data, sizeof(S_Flash_Device_Para));
                    }
                }
            }
        }
        else
        {
            comm_result = COMM_02_ERROR_PARA;
        }
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1425-表计基本参数配置
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1425_Normal_Para_Info(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    gw_u16 u16len;

    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();

    gw_u16 low_power1 = ps_flash->s_para.battery1_first_low_voltage_threshold;
    gw_u16 low_power2 = ps_flash->s_para.battery1_second_low_voltage_threshold;

    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (cmd_code == CMD_82_SET_NORMAL_PARA)
    {
        if (data[u8index] == 0x03)
        {
            u8index++;
            u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
            u8index += 2;
            if (u16len != 0x0002)
            {
                comm_result = COMM_03_ERROR_PARA_FORMAT;
            }
            else
            {
                ps_flash->s_para.battery1_first_low_voltage_threshold = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
                u8index += 2;
                ps_flash->s_para.battery1_second_low_voltage_threshold = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
                u8index += 2;
                if (Svc_Flash_Write_Device_Para(&ps_flash->s_para) == E_STATE_ERROR)
                {
                    comm_result = COMM_FF_ERROR_SYS;
                    ps_flash->s_para.battery1_first_low_voltage_threshold = low_power1;
                    ps_flash->s_para.battery1_second_low_voltage_threshold = low_power2;
                }
            }
        }
        else
        {
            comm_result = COMM_02_ERROR_PARA;
        }
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1C01-机电同步
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1C01_Sync_DialNum(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    gw_u16 u16len;

    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (data[u8index] == 0x01)
    {
        u8index++;
        u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        if (u16len != 0x0004)
        {
            comm_result = COMM_03_ERROR_PARA_FORMAT;
            Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
            return;
        }
        else
        {
            ps_pulse->u32BaseUsage = ((data[u8index] & 0x000000FF) << 24 | (data[u8index + 1] & 0x000000FF) << 16 | (data[u8index + 2] & 0x000000FF) << 8 | (data[u8index + 3] & 0x000000FF));
            u8index += 4;
        }
    }
    else
    {
        comm_result = COMM_02_ERROR_PARA;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    Svc_Pulse_Protocol_Send_Cmd(CMD_82_SET_MEASURE_PARA, FUNC_15_SET_USAGE); // 转发给模组，由模组进行存储，模组回复再根据结果码回复上位机
}

/**
 * @brief: 功能片段1C02-清除故障
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1C02_Clear_The_Fault(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    gw_u16 u16len;

    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();

    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;

    if (data[u8index] == 0x01)
    {
        u8index++;
        u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        if (u16len != 0)
        {
            comm_result = COMM_03_ERROR_PARA_FORMAT;
        }
        else
        {
            ps_flash->s_security.s_state.u32device_alarm = 0;
        }
    }
    else
    {
        comm_result = COMM_02_ERROR_PARA;
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1151-查实时流量信息
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1151_Realtime_Usage(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (data[u8index] != 0x01)
    {
        u8index++;
        comm_result = COMM_03_ERROR_PARA_FORMAT;
    }
    else
    {
        gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        if (u16len != 0x0003)
        {
            comm_result = COMM_03_ERROR_PARA_FORMAT;
        }
        else
        {
            memcpy(s_ir_data.pu8QueryDate, &data[u8index], 3);
            u8index += 3;
        }
    }

    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1502-查询 6 个月内日区间明细
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1502_Query_Usage(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    E_Comm_Result comm_result = COMM_00_NORMAL;
    gw_u8 StatrDay[3];
    gw_s32 daydiff;
    if (data[u8index] == 0x01)
    {
        u8index++;
        gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        if (u16len != 0x04)
        {
            comm_result = COMM_03_ERROR_PARA_FORMAT;
        }
        else
        {
            memcpy(StatrDay, &data[u8index], 3);
            u8index += 3;
            daydiff = Util_Time_Diff_Day(ps_cloud->s_manage.pu8CurTime, StatrDay);
            gw_s32 statrdaydiff = Util_Time_Diff_Day(ps_flash->s_para.s_usage_index.pu8StartDate, StatrDay);

            if ((daydiff <= 0) || (statrdaydiff <= 0) || (statrdaydiff < s_ir_data.u8QueryNum))
            {
                Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, COMM_02_ERROR_PARA);
                return;
            }
            s_ir_data.u8QueryNum = data[u8index];
            u8index++;
        }
    }
    else
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
    }
    if (comm_result != COMM_00_NORMAL)
    {
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
    }
    else
    {
        if (s_ir_data.u8QueryNum > 1)
        {
            memcpy(s_ir_data.pu8QueryDate, StatrDay, 3);
            for (gw_u8 i = 1; i < s_ir_data.u8QueryNum; i++) // 一天一包，查几天就几包
            {
                Bsp_Iwdg_Feed(); // 喂狗
                Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
                Util_Time_Cal_Date(StatrDay, i, s_ir_data.pu8QueryDate);
            }
        }
    }
}

/**
 * @brief: 功能片段1504-查询 36 个月内月区间明细
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1504_Query_Usage(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();

    if (data[u8index] == 0x01)
    {
        u8index++;
        gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        if (u16len != 0x03)
        {
            comm_result = COMM_03_ERROR_PARA_FORMAT;
        }
        else
        {
            gw_s32 s32MonthDiff = Util_Time_Diff_Month(ps_cloud->s_manage.pu8CurTime, s_ir_data.pu8QueryDate);
            gw_s32 QueryMonthdiff = Util_Time_Diff_Month(ps_flash->s_para.s_usage_index.u8StartMonth, s_ir_data.pu8QueryDate);
            if ((s32MonthDiff <= 0) || (QueryMonthdiff <= 0) || (QueryMonthdiff < s_ir_data.u8QueryNum))
            {
                Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, COMM_02_ERROR_PARA);
                return;
            }
            memcpy(s_ir_data.pu8QueryDate, &data[u8index], 2);
            u8index += 2;
            s_ir_data.u8QueryNum = data[u8index];
            u8index++;
        }
    }
    else
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1141-密集周期流量信息
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1141_Dense_Usage_Info(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();
    if (data[u8index] == 0x01)
    {
        u8index++;
        gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        if (u16len != 0x03)
        {
            comm_result = COMM_03_ERROR_PARA_FORMAT;
        }
        else
        {
            gw_s32 daydiff = Util_Time_Diff_Day(ps_cloud->s_manage.pu8CurTime, s_ir_data.pu8QueryDate);
            gw_s32 statrdaydiff = Util_Time_Diff_Day(ps_flash->s_para.s_usage_index.pu8StartDate, s_ir_data.pu8QueryDate);

            if ((daydiff <= 0) || (statrdaydiff <= 0) || (statrdaydiff < s_ir_data.u8QueryNum))
            {
                Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, COMM_02_ERROR_PARA);
                return;
            }
            memcpy(s_ir_data.pu8QueryDate, &data[u8index], 3);
            u8index += 3;
        }
    }
    else
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1608-表状态
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1608_Meter_State(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段1609-读时间段事件记录
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func1609_Time_Period_Event(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (data[u8index] == 0x01)
    {
        u8index++;
        gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        if (u16len != 0x0F)
        {
            comm_result = COMM_03_ERROR_PARA_FORMAT;
        }
        else
        {
            s_ir_data.Event = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
            u8index += 2;
            memcpy(s_ir_data.Event_StatrTime, &data[u8index], 6);
            u8index += 6;
            memcpy(s_ir_data.Event_EndTime, &data[u8index], 6);
            u8index += 6;
            s_ir_data.Event_Num = data[u8index];
            u8index++;
        }
    }
    else
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
    }

    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段160A-读最新事件记录
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func160A_Lateset_Event(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    if (data[u8index] == 0x01)
    {
        u8index++;
        gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        if (u16len != 0x03)
        {
            comm_result = COMM_03_ERROR_PARA_FORMAT;
        }
        else
        {
            s_ir_data.Event = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
            u8index += 2;
            s_ir_data.Event_Num = data[u8index];
            u8index++;
        }
    }
    else
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
    }
    Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
}

/**
 * @brief: 功能片段3001-模组设备信息
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func3001_Pulse_Info(gw_u8 *data)
{
    Svc_Pulse_Protocol_Send_Cmd(CMD_41_QUERY_DEVICE_INFO, FUNC_01_METER_INFO);
}

/**
 * @brief: 功能片段3002-模组通信波特率
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func3002_Pulse_Baudrate(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    if (u16len != 0x0002)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_43_QUERY_PULSE_PARA)
    {
        Svc_Pulse_Protocol_Send_Cmd(CMD_41_QUERY_DEVICE_INFO, FUNC_02_COMM_BAUDRATE);
    }
    else if (cmd_code == CMD_83_SET_PULSE_PARA)
    {
        gw_u16 baud;
        baud = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        if ((baud != 2400) || (baud != 4800) || (baud != 9600))
        {
            comm_result = COMM_02_ERROR_PARA;
            Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
            return;
        }
        ps_pulse->s_pulse_para.u16Baudrate = baud;
        Svc_Pulse_Protocol_Send_Cmd(CMD_81_SET_DEVICE_INFO, FUNC_02_COMM_BAUDRATE);
    }
}

/**
 * @brief: 功能片段3003-模组工作模式
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func3003_Pulse_WorkMode(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    if (u16len != 0x0001)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_43_QUERY_PULSE_PARA)
    {
        Svc_Pulse_Protocol_Send_Cmd(CMD_41_QUERY_DEVICE_INFO, FUNC_03_WORK_MODE);
    }
    else if (cmd_code == CMD_83_SET_PULSE_PARA)
    {
        gw_u16 mode;
        mode = data[u8index];
        u8index++;
        if (mode > 0x05)
        {
            comm_result = COMM_02_ERROR_PARA;
            Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
            return;
        }
        ps_pulse->s_pulse_para.ePulseMode = (E_Pulse_Mode)mode;
        Svc_Pulse_Protocol_Send_Cmd(CMD_81_SET_DEVICE_INFO, FUNC_03_WORK_MODE);
    }
}

/**
 * @brief: 功能片段3004-模组时间校准
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func3004_Pulse_Time_Calibrate(gw_u8 *data)
{
    Svc_Pulse_Protocol_Send_Cmd(CMD_81_SET_DEVICE_INFO, FUNC_04_CORRECT_TIME);
}

/**
 * @brief: 功能片段3005-模组运行时间
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func3005_Pulse_Runtime(gw_u8 *data)
{
    Svc_Pulse_Protocol_Send_Cmd(CMD_41_QUERY_DEVICE_INFO, FUNC_05_RUN_TIME);
}

/**
 * @brief: 功能片段3010-管段参数
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func3010_Pulse_Pipe_Para(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    if (u16len != 0x0007)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_43_QUERY_PULSE_PARA)
    {
        Svc_Pulse_Protocol_Send_Cmd(CMD_42_QUERY_MEASURE_PARA, FUNC_10_PIPE_PARA);
    }
    else if (cmd_code == CMD_83_SET_PULSE_PARA)
    {
        ps_pulse->s_pulse_para.u8PipeMode = data[u8index];
        u8index++;
        ps_pulse->s_pulse_para.u16SonicLength = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        ps_pulse->s_pulse_para.u16ActiveSonicLength = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        ps_pulse->s_pulse_para.u16Diameter = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        Svc_Pulse_Protocol_Send_Cmd(CMD_82_SET_MEASURE_PARA, FUNC_10_PIPE_PARA);
    }
}

/**
 * @brief: 功能片段3011-始动流速
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func3011_Pulse_Start_Flow(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    if (u16len != 0x0002)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_43_QUERY_PULSE_PARA)
    {
        Svc_Pulse_Protocol_Send_Cmd(CMD_42_QUERY_MEASURE_PARA, FUNC_11_START_FLOW_SPEED);
    }
    else if (cmd_code == CMD_83_SET_PULSE_PARA)
    {
        ps_pulse->s_pulse_para.u16SatrtSpeed = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
        u8index += 2;
        Svc_Pulse_Protocol_Send_Cmd(CMD_82_SET_MEASURE_PARA, FUNC_11_START_FLOW_SPEED);
    }
}

/**
 * @brief: 功能片段3012-零点参数
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func3012_Pulse_Zero(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    if (u16len != 0x04)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_43_QUERY_PULSE_PARA)
    {
        Svc_Pulse_Protocol_Send_Cmd(CMD_42_QUERY_MEASURE_PARA, FUNC_12_ZERO_CORRECT_PARA);
    }
    else
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
}

/**
 * @brief: 功能片段3013-修正系数
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func3013_Pulse_Correct_Para(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    gw_u8 u8Num;
    u8Num = data[u8index];
    u8index++;
    if (u16len != 1 + 8 * u8Num)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_43_QUERY_PULSE_PARA)
    {
        Svc_Pulse_Protocol_Send_Cmd(CMD_42_QUERY_MEASURE_PARA, FUNC_13_CORRECT_PARA);
    }
    else if (cmd_code == CMD_83_SET_PULSE_PARA)
    {
        ps_pulse->s_pulse_para.u8CorrPointNum = u8Num;
        for (gw_u8 i = 0; i < u8Num; i++)
        {
            ps_pulse->s_pulse_para.s32CorrPoint[i][0] = ((data[u8index] & 0x000000FF) << 24 | (data[u8index + 1] & 0x000000FF) << 16 | (data[u8index + 2] & 0x000000FF) << 8 | (data[u8index + 3] & 0x000000FF));
            u8index += 4;
            ps_pulse->s_pulse_para.s32CorrPoint[i][1] = ((data[u8index] & 0x000000FF) << 24 | (data[u8index + 1] & 0x000000FF) << 16 | (data[u8index + 2] & 0x000000FF) << 8 | (data[u8index + 3] & 0x000000FF));
            u8index += 4;
        }
        Svc_Pulse_Protocol_Send_Cmd(CMD_82_SET_MEASURE_PARA, FUNC_13_CORRECT_PARA);
    }
}

/**
 * @brief: 功能片段3014-零点模式
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func3014_Pulse_ZeroMode(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    if (u16len != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_83_SET_PULSE_PARA)
    {
        ps_pulse->s_pulse_para.u8ZeroModeEn = data[u8index];
        u8index++;
        Svc_Pulse_Protocol_Send_Cmd(CMD_82_SET_MEASURE_PARA, FUNC_14_ZERO_MODE);
    }
}

/**
 * @brief: 功能片段30A0-查询100日内的日流量数据
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func30A0_Pulse_Day_Historical(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();
    S_Pulse_Day_History *day_history;
    day_history = &ps_pulse->s_pulse_para.s_pulse_day_history;
    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    if (u16len != 0x04)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_43_QUERY_PULSE_PARA)
    {
        memcpy(day_history->pu8Query_StartDay, &data[u8index], 3);
        u8index += 3;
        day_history->u8Query_DayNum = data[u8index];
        u8index++;
        gw_u8 num;
        num = Util_Time_Diff_Day(day_history->pu8Query_StartDay, ps_cloud->s_manage.pu8CurTime);

        if ((num <= 0) || (num >= 100) || (day_history->u8Query_DayNum > 20))
        {
            comm_result = COMM_02_ERROR_PARA;
            Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
            return;
        }
        Svc_Pulse_Protocol_Send_Cmd(CMD_C3_PROPRIETARY_PROTOCOL, FUNC_A0_DAY_HISTORICAL);
    }
}

/**
 * @brief: 功能片段30A1-查询 60个月内月流量数据
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func30A1_Pulse_Month_Historical(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();
    S_Pulse_Month_History *month_history;
    month_history = &ps_pulse->s_pulse_para.s_pulse_month_history;

    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    if (u16len != 0x03)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_43_QUERY_PULSE_PARA)
    {
        memcpy(month_history->pu8Query_StartMonth, &data[u8index], 2);
        u8index += 3;
        month_history->u8Query_MonthNum = data[u8index];
        u8index++;
        gw_u8 num;
        num = Util_Time_Diff_Day(month_history->pu8Query_StartMonth, ps_cloud->s_manage.pu8CurTime);

        if ((num <= 0) || (num >= 60) || (month_history->u8Query_MonthNum > 20))
        {
            comm_result = COMM_02_ERROR_PARA;
            Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
            return;
        }
        Svc_Pulse_Protocol_Send_Cmd(CMD_C3_PROPRIETARY_PROTOCOL, FUNC_A1_MONTH_HISTORICAL);
    }
}

/**
 * @brief: 功能片段302A-清除模组校准数据
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func302A_Pulse_Clear_Codata(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    if (u16len != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_83_SET_PULSE_PARA)
    {
        Svc_Pulse_Protocol_Send_Cmd(CMD_C1_QUERY_USAGE_DATA, FUNC_2A_CLEAR_CORRECT_DATA);
    }
}

/**
 * @brief: 功能片段302C-清除模组所有数据
 * @param:{gw_u8 *}*data
 * @return {E_Result_State}
 * @note:
 * @see:
 */
static void Svc_Ir_Func302C_Pulse_Clear_All_Data(gw_u8 *data)
{
    gw_u8 u8index = 0;
    gw_u8 cmd_code = data[u8index];
    u8index++;
    gw_u16 func_code;
    func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    E_Comm_Result comm_result = COMM_00_NORMAL;

    if (data[u8index] != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    u8index++;
    gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
    u8index += 2;
    if (u16len != 0x01)
    {
        comm_result = COMM_03_ERROR_PARA_FORMAT;
        Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
        return;
    }
    if (cmd_code == CMD_83_SET_PULSE_PARA)
    {
        Svc_Pulse_Protocol_Send_Cmd(CMD_C1_QUERY_USAGE_DATA, FUNC_2C_CLEAR_ALL_DATA);
    }
}

// /**
//  * @brief: 功能片段30A2-使能/失能调试串口
//  * @param:{gw_u8 *}*data
//  * @return {E_Result_State}
//  * @note:
//  * @see:
//  */
// static void Svc_Ir_Func30A2_Pulse_Pulse_Debug_Enable(gw_u8 *data)
// {
//     gw_u8 u8index = 0;
//     gw_u8 cmd_code = data[u8index];
//     u8index++;
//     gw_u16 func_code;
//     func_code = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
//     u8index += 2;
//     E_Comm_Result comm_result = COMM_00_NORMAL;
//     S_Pulse *ps_pulse;
//     ps_pulse = Svc_Pulse_Get_Data();

//     if (data[u8index] != 0x01)
//     {
//         comm_result = COMM_03_ERROR_PARA_FORMAT;
//         Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
//         return;
//     }
//     u8index++;
//     gw_u16 u16len = ((data[u8index] & 0x00FF) << 8) | (0x00FF & data[u8index + 1]);
//     u8index += 2;
//     if (u16len != 0x01)
//     {
//         comm_result = COMM_03_ERROR_PARA_FORMAT;
//         Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
//         return;
//     }
//     if (cmd_code == CMD_83_SET_PULSE_PARA)
//     {
//         if (data[u8index] >= 0x02)
//         {
//             comm_result = COMM_02_ERROR_PARA;
//             Svc_Ir_Protocol_Send_Cmd((E_Cmd_Code_Ir)cmd_code, (E_Function_Code_Ir)func_code, (E_Comm_Result)comm_result);
//             return;
//         }
//         ps_pulse->s_pulse_para.u8DebugEn = data[u8index];
//         u8index++;
//         Svc_Pulse_Protocol_Send_Cmd(CMD_C3_PROPRIETARY_PROTOCOL, FUNC_A2_CLOSE_SERIAL_PORT);
//     }
// }

/**************************************发送应答数据***************************************/
/**
 * @brief: 发送数据帧
 * @param:{E_Cmd_Code_Ir}e_cmd_code命令码
 * @param:{E_Function_Code_Ir}Function_code片段码
 * @param:{E_Comm_Result}e_comm_result结果码
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Ir_Protocol_Send_Cmd(E_Cmd_Code_Ir e_cmd_code, E_Function_Code_Ir e_func_code, E_Comm_Result e_comm_result)
{
    s_ir_data.e_cmd_code_ir = e_cmd_code;
    s_ir_data.e_func_code_ir = e_func_code;
    s_ir_data.e_comm_result_ir = e_comm_result;
    if (Svc_Creat_Ir_Frame(&s_ir_data) == E_STATE_SUCCESS)
    {
        Svc_Ir_Uart_Send((gw_s8 *)s_ir_data.pu8Buff, s_ir_data.u16BuffLen);
        Svc_Log_Printf(LOG_INFO, "IR Send: ");
        gw_u16 i = 0;
        for (i = 0; i < s_ir_data.u16BuffLen; i++)
        {
            Svc_Log_Print("%02X ", s_ir_data.pu8Buff[i]);
        }
        Svc_Log_Print("\r\n");
    }
}

/**
 * @brief: 生成整个数据帧
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static E_Result_State Svc_Creat_Ir_Frame(S_Ir_Data *ps_ir_data)
{
    memset(&ps_ir_data->pu8Buff, 0, sizeof(ps_ir_data->pu8Buff));

    Svc_Ir_Creat_Head_Field(ps_ir_data);  // 生成数据帧头
    Svc_Ir_Creat_Data_Field(ps_ir_data);  // 生成数据域
    Svc_Ir_Creat_Check_Field(ps_ir_data); // 生成校验域
    return E_STATE_SUCCESS;
}

/**
 * @brief: 生成数据帧头
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Head_Field(S_Ir_Data *ps_ir_data)
{
    gw_u16 index = 0;
    gw_u8 *buff = ps_ir_data->pu8Buff;
    S_Flash_Data *ps_flash_data;
    ps_flash_data = Svc_Flash_Get_Data();
    S_Flash_Device_Security *ps_security;
    ps_security = &ps_flash_data->s_security;

    buff[index] = (SLAVE_LEAD_CODE & 0xFF000000) >> 24;
    buff[index + 1] = (SLAVE_LEAD_CODE & 0x00FF0000) >> 16;
    buff[index + 2] = (SLAVE_LEAD_CODE & 0x0000FF00) >> 8;
    buff[index + 3] = SLAVE_LEAD_CODE & 0x000000FF; // 引导码
    index += 4;
    buff[index] = IR_FRAME_HEAD; // 帧头
    index++;
    buff[index] = IR_PROTOCOL_VER; // 协议版本
    index++;
    ps_ir_data->s_data_index.u16DataLenIndex = index; // 数据长度所在位置
    index += 2;
    ps_ir_data->s_data_index.u16IdIndex = index; // 产品序列号所在位置
    memcpy(&buff[index], ps_security->product_id, 16);
    index += 16;
    ps_ir_data->s_data_index.u16DataFieldIndex = index;
}

/**
 * @brief: 生成数据域
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Data_Field(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u16 index = ps_ir_data->s_data_index.u16DataFieldIndex; // 继承长度
    E_Cmd_Code_Ir cmd = ps_ir_data->e_cmd_code_ir;
    buff[index] = ps_ir_data->e_cmd_code_ir; // 命令码
    index++;
    if ((cmd == CMD_A1_REQUEST_OTA) || (cmd == CMD_A2_REQUEST_OTA_DATA))
    {
        ps_ir_data->u16BuffLen = index;
        Svc_Ir_Creat_User_Data(ps_ir_data); // 生成功能片段码、片段类型、片段长度、数据
        return;
    }
    buff[index] = ps_ir_data->e_comm_result_ir; // 结果码
    index++;
    /*这部分不需要带数据，返回命令码和结果码即可*/
    if ((cmd != CMD_81_SET_SPECIAL_PARA) && (cmd != CMD_82_SET_NORMAL_PARA) && (cmd != CMD_C0_OPERATE))
    {
        if (ps_ir_data->e_comm_result_ir == COMM_00_NORMAL) // 结果非正常，只返回命令码、结果码
        {
            ps_ir_data->u16BuffLen = index;
            Svc_Ir_Creat_User_Data(ps_ir_data); // 生成功能片段码、片段类型、片段长度、数据
        }
    }
    else
    {
        ps_ir_data->u16BuffLen = index; // 目前数据帧长度
    }
}

/**
 * @brief: 生成校验域、帧尾
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Check_Field(S_Ir_Data *ps_ir_data)
{
    gw_u16 u16CrcLen;
    u16CrcLen = ps_ir_data->u16BuffLen - ps_ir_data->s_data_index.u16IdIndex;
    gw_u16 u16UserDataLen = u16CrcLen;
    gw_u8 index = ps_ir_data->u16BuffLen;
    gw_u8 *buff = ps_ir_data->pu8Buff;

    buff[ps_ir_data->s_data_index.u16DataLenIndex] = (u16UserDataLen & 0xFF00) >> 8;
    buff[ps_ir_data->s_data_index.u16DataLenIndex + 1] = u16UserDataLen & 0x00FF;

    ps_ir_data->u16Crc = Util_Crc16(&buff[ps_ir_data->s_data_index.u16IdIndex], u16CrcLen);
    buff[index] = (ps_ir_data->u16Crc & 0xFF00) >> 8;
    buff[index + 1] = ps_ir_data->u16Crc & 0x00FF;
    index += 2;

    buff[index] = IR_FRAME_TAIL;
    index++;
    int16_t s16OutLen = Change_Original_Data(&buff[4], index - 4, &buff[4]); // 转义
    ps_ir_data->u16BuffLen = s16OutLen + 4;
}

/**
 * @brief: 根据命令码生成数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_User_Data(S_Ir_Data *ps_ir_data)
{
    E_Cmd_Code_Ir cmd_code;
    cmd_code = ps_ir_data->e_cmd_code_ir;
    switch (cmd_code)
    {
    case CMD_41_QUERY_SPECIAL_PARA:
        Svc_Ir_Creat_Cmd41(ps_ir_data);
        break;
    case CMD_42_QUERY_NORMAL_PARA:
        Svc_Ir_Creat_Cmd42(ps_ir_data);
        break;
    case CMD_C1_QUERY_HISTORY_DATA:
        Svc_Ir_Creat_CmdC1(ps_ir_data);
        break;
    case CMD_C3_MAINTAIN:
        Svc_Ir_Creat_CmdC3(ps_ir_data);
        break;
    case CMD_A1_REQUEST_OTA:
        Svc_Ir_Creat_CmdA1(ps_ir_data);
        break;
    case CMD_A2_REQUEST_OTA_DATA:
        Svc_Ir_Creat_CmdA2(ps_ir_data);
        break;
    case CMD_43_QUERY_PULSE_PARA:
        Svc_Ir_Creat_Cmd43(ps_ir_data);
        break;
    case CMD_83_SET_PULSE_PARA:
        Svc_Ir_Creat_Cmd83(ps_ir_data);
        break;
    default:
        break;
    }
}

/**
 * @brief: 根据功能码41生成数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Cmd41(S_Ir_Data *ps_ir_data)
{
    E_Function_Code_Ir Func_code;
    Func_code = ps_ir_data->e_func_code_ir;
    switch (Func_code)
    {
    case IR_0003_NETWORK_INFO:
        Svc_Ir_Creat_Func0003(ps_ir_data);
        break;
    case IR_0007_INFORM_KEY:
        Svc_Ir_Creat_Func0007(ps_ir_data);
        break;
    case IR_0004_PRODUCT_ID:
        Svc_Ir_Creat_Func0004(ps_ir_data);
        break;
    default:
        break;
    }
}

/**
 * @brief: 根据功能码42生成数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Cmd42(S_Ir_Data *ps_ir_data)
{
    E_Function_Code_Ir Func_code;
    Func_code = ps_ir_data->e_func_code_ir;
    switch (Func_code)
    {
    case IR_0002_METER_INFO:
        Svc_Ir_Creat_Func0002(ps_ir_data);
        break;
    case IR_0006_DEVICE_TIME:
        Svc_Ir_Creat_Func0006(ps_ir_data);
        break;
    case IR_1001_POWER_STATE:
        Svc_Ir_Creat_Func1001(ps_ir_data);
        break;
    case IR_1120_USAGE_INFO:
        Svc_Ir_Creat_Func1120(ps_ir_data);
        break;
    case IR_1420_REPORTCYCLE:
        Svc_Ir_Creat_Func1420(ps_ir_data);
        break;
    case IR_1423_INFORM_RELIABLE_INFO:
        Svc_Ir_Creat_Func1423(ps_ir_data);
        break;
    case IR_1424_ERR_FLOW:
        Svc_Ir_Creat_Func1424(ps_ir_data);
        break;
    case IR_1425_NORMAL_PARA_INFO:
        Svc_Ir_Creat_Func1425(ps_ir_data);
        break;
    default:
        break;
    }
}

/**
 * @brief: 根据功能码C1生成数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_CmdC1(S_Ir_Data *ps_ir_data)
{
    E_Function_Code_Ir Func_code;
    Func_code = ps_ir_data->e_func_code_ir;
    switch (Func_code)
    {
    case IR_1151_REALTIME_USAGE_INFO:
        Svc_Ir_Creat_Func1151(ps_ir_data);
        break;
    case IR_1502_QUERY_USAGE:
        Svc_Ir_Creat_Func1502(ps_ir_data);
        break;
    case IR_1504_QUERY_USAGE:
        Svc_Ir_Creat_Func1504(ps_ir_data);
        break;
    case IR_1C01_SYNC_DIAL_NUM:
        Svc_Ir_Creat_Func1C01(ps_ir_data);
        break;
    default:
        break;
    }
}

/**
 * @brief: 根据功能码C3生成数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_CmdC3(S_Ir_Data *ps_ir_data)
{
    E_Function_Code_Ir Func_code;
    Func_code = ps_ir_data->e_func_code_ir;
    switch (Func_code)
    {
    case IR_1141_DENSE_USAGE_INFO:
        Svc_Ir_Creat_Func1141(ps_ir_data);
        break;
    case IR_1608_METER_STATE:
        Svc_Ir_Creat_Func1608(ps_ir_data);
        break;
    case IR_1609_TIME_PERIOD_EVENT:
        Svc_Ir_Creat_Func1609(ps_ir_data);
        break;
    case IR_160A_LATESET_EVENT_LOG:
        Svc_Ir_Creat_Func160A(ps_ir_data);
        break;
    default:
        break;
    }
}

/**
 * @brief: 根据功能码A1生成数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_CmdA1(S_Ir_Data *ps_ir_data)
{
    S_Ota *s_ota;
    s_ota = Svc_Ota_Get_Data();
    S_Ota_Para *s_ota_para = &s_ota->s_para;

    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = s_ota_para->u8softversion[0];
    buff[u8index + 1] = s_ota_para->u8softversion[1];
    u8index += 2;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 根据功能码A2生成数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_CmdA2(S_Ir_Data *ps_ir_data)
{
    S_Ota *s_ota;
    s_ota = Svc_Ota_Get_Data();
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    gw_u32 u32OtaEndAddr;

    buff[u8index] = s_ota->s_para.u8softversion[0];
    buff[u8index + 1] = s_ota->s_para.u8softversion[1];
    u8index += 2;
    if (s_ota->startflag == 1)
    {
        s_ota->u32CurLen = OTA_PACKGE_SIZE * s_ota->u16PackNum;
        s_ota->u32RemainLen = s_ota->s_para.u32FirmwareLen - s_ota->u32CurLen;
        s_ota->u32OtaStartAddr = s_ota->u32CurLen; // s_ota->u32OtaStartAddr +
        buff[u8index] = (s_ota->u32OtaStartAddr & 0xFF000000) >> 24;
        buff[u8index + 1] = (s_ota->u32OtaStartAddr & 0x00FF0000) >> 16;
        buff[u8index + 2] = (s_ota->u32OtaStartAddr & 0x0000FF00) >> 8;
        buff[u8index + 3] = (s_ota->u32OtaStartAddr & 0x000000FF);
        u8index = u8index + 4;
        if (s_ota->u32RemainLen < OTA_PACKGE_SIZE)
        {
            u32OtaEndAddr = s_ota->u32OtaStartAddr + s_ota->u32RemainLen;
        }
        else
        {
            u32OtaEndAddr = s_ota->u32OtaStartAddr + OTA_PACKGE_SIZE - 1;
        }
        buff[u8index] = (u32OtaEndAddr & 0xFF000000) >> 24;
        buff[u8index + 1] = (u32OtaEndAddr & 0x00FF0000) >> 16;
        buff[u8index + 2] = (u32OtaEndAddr & 0x0000FF00) >> 8;
        buff[u8index + 3] = (u32OtaEndAddr & 0x000000FF);
        u8index = u8index + 4;
    }
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 根据功能码43生成数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Cmd43(S_Ir_Data *ps_ir_data)
{
    E_Function_Code_Ir Func_code;
    Func_code = ps_ir_data->e_func_code_ir;
    switch (Func_code)
    {
    case IR_3001_PULSE_INFO:
        Svc_Ir_Creat_Func3001(ps_ir_data);
        break;
    case IR_3002_PULSE_BAUDRATE:
        Svc_Ir_Creat_Func3002(ps_ir_data);
        break;
    case IR_3003_PULSE_WORKMODE:
        Svc_Ir_Creat_Func3003(ps_ir_data);
        break;
    case IR_3005_PULSE_RUNTIME:
        Svc_Ir_Creat_Func3005(ps_ir_data);
        break;
    case IR_3010_PULSE_PIPE_PARA:
        Svc_Ir_Creat_Func3010(ps_ir_data);
        break;
    case IR_3011_PULSE_START_FLOW:
        Svc_Ir_Creat_Func3011(ps_ir_data);
        break;
    case IR_3012_PULSE_ZERO:
        Svc_Ir_Creat_Func3012(ps_ir_data);
        break;
    case IR_3013_PULSE_CORRECT_PARA:
        Svc_Ir_Creat_Func3013(ps_ir_data);
        break;
    case IR_30A0_PULSE_DAY_HISTORICAL:
        Svc_Ir_Creat_Func30A0(ps_ir_data);
        break;
    case IR_30A1_PULSE_MONTH_HISTORICAL:
        Svc_Ir_Creat_Func30A1(ps_ir_data);
        break;
    default:
        break;
    }
}

/**
 * @brief: 根据功能码83生成数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Cmd83(S_Ir_Data *ps_ir_data)
{
   E_Function_Code_Ir Func_code;
    Func_code = ps_ir_data->e_func_code_ir;
    switch (Func_code)
    {
    case IR_3014_PULSE_ZEROMODE:
        Svc_Ir_Creat_Func3014(ps_ir_data);
        break;
    default:
        break;
    }   
}

/**
 * @brief: 通讯模组网络连接
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func0003(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    gw_s8 *ps8Strs[2] = {NULL};
    gw_s8 *ps8IpStrs[4] = {NULL};
    gw_u16 u16OutSize;

    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    gw_u8 pu8Ip[32];
    memcpy(pu8Ip, &ps_flash->s_para.s_nb_info.pu8ServerIp, 32);
    u16OutSize = Util_Data_String_Split((gw_s8 *)pu8Ip, (gw_s8)',', ps8Strs, 2);
    if (u16OutSize < 2)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->string split fail!", __FUNCTION__);
        return;
    }
    u16OutSize = Util_Data_String_Split((gw_s8 *)pu8Ip, (gw_s8)'.', ps8IpStrs, 4);
    if (u16OutSize < 4)
    {
        Svc_Log_Printf(LOG_ERROR, "%s->string split fail!", __FUNCTION__);
        return;
    }
    buff[u8index] = Util_Data_String_To_Uint8((gw_u8 *)ps8IpStrs[0], strlen((const char *)ps8IpStrs[0])); // 服务器地址
    buff[u8index + 1] = Util_Data_String_To_Uint8((gw_u8 *)ps8IpStrs[1], strlen((const char *)ps8IpStrs[1]));
    buff[u8index + 2] = Util_Data_String_To_Uint8((gw_u8 *)ps8IpStrs[2], strlen((const char *)ps8IpStrs[2]));
    buff[u8index + 3] = Util_Data_String_To_Uint8((gw_u8 *)ps8IpStrs[3], strlen((const char *)ps8IpStrs[3]));
    u8index = u8index + 4;

    gw_u16 u16Port = Util_Data_String_To_Uint16((gw_u8 *)ps8Strs[1], strlen((const char *)ps8Strs[1])); // 端口号

    buff[u8index] = ((u16Port & 0xFF00) >> 8); // 端口号
    buff[u8index + 1] = (u16Port & 0x00FF);
    u8index = u8index + 2;

    gw_u8 apn_len = strlen((const char *)ps_flash->s_para.s_nb_info.pu8Apn); // apn长度
    buff[u8index] = apn_len;
    u8index++;
    if (apn_len > 0)
    {
        memcpy(&buff[u8index], ps_flash->s_para.s_nb_info.pu8Apn, apn_len); // apn
        u8index = u8index + apn_len;
    }

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 设备密钥
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func0007(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    memcpy(&buff[u8index], ps_flash->s_security.pu8Key, 16);
    u8index += 16;
    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 产品序列号
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func0004(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    memcpy(&buff[u8index], ps_flash->s_security.product_id, 16);
    u8index += 16;
    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 表计信息
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func0002(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    S_Flash_Nb_Info *ps_nb_info;
    ps_nb_info = &ps_flash->s_para.s_nb_info;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
#if DN15
    buff[u8index] = 0x0F;
#elif DN20
    buff[u8index] = 0x14;
#elif DN25
    buff[u8index] = 0x19;
#endif
    u8index++;
    buff[u8index] = HW_MAIN_VER;    // 硬件主版本
    buff[u8index + 1] = HW_SUB_VER; // 硬件子版本
    u8index += 2;
    buff[u8index] = ps_flash->s_security.main_version;    // 软件主版本
    buff[u8index + 1] = ps_flash->s_security.sub_version; // 软件子版本
    u8index += 2;
    buff[u8index] = ps_nb_info->Comm_Model_Ver_len; // NB模组版本长度
    u8index++;
    memcpy(&buff[u8index], ps_nb_info->Comm_Model_Ver, ps_nb_info->Comm_Model_Ver_len); // NB模组版本号
    u8index += ps_nb_info->Comm_Model_Ver_len;

    buff[u8index] = ps_nb_info->Comm_Model_Imei_len; // IMEI长度
    u8index++;
    memcpy(&buff[u8index], ps_nb_info->Comm_Model_Imei, ps_nb_info->Comm_Model_Imei_len); // IMEI
    u8index += ps_nb_info->Comm_Model_Imei_len;

    buff[u8index] = ps_nb_info->Comm_Model_Imsi_len; // IMSI长度
    u8index++;
    memcpy(&buff[u8index], ps_nb_info->Comm_Model_Imsi, ps_nb_info->Comm_Model_Imsi_len); // IMSI
    u8index += ps_nb_info->Comm_Model_Imsi_len;

    buff[u8index] = ps_nb_info->Comm_Model_Iccid_len; // ICCID长度
    u8index++;
    memcpy(&buff[u8index], ps_nb_info->Comm_Model_Iccid, ps_nb_info->Comm_Model_Iccid_len); // ICCID
    u8index += ps_nb_info->Comm_Model_Iccid_len;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 设备时间
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func0006(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();

    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    memcpy(&buff[u8index], ps_cloud->s_manage.pu8CurTime, 6);
    u8index += 6;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 电源状态
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1001(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;

    gw_u32 u32BatAdc;
    u32BatAdc = Svc_Bat_Get_Adc();

    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x03; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    buff[u8index] = (u32BatAdc & 0xFF00) >> 8;
    buff[u8index + 1] = u32BatAdc & 0x00FF;
    u8index += 2;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 总用量信息
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1120(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;

    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();
    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();

    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    memcpy(&buff[u8index], ps_cloud->s_manage.pu8CurTime, 6);
    u8index += 6;
    buff[u8index] = (ps_pulse->u32Usage & 0xFF000000) >> 24;
    buff[u8index + 1] = (ps_pulse->u32Usage & 0x00FF0000) >> 16;
    buff[u8index + 2] = (ps_pulse->u32Usage & 0x0000FF00) >> 8;
    buff[u8index + 3] = ps_pulse->u32Usage & 0x000000FF;
    u8index += 4;
    buff[u8index] = (ps_pulse->u32UsageRe & 0xFF000000) >> 24;
    buff[u8index + 1] = (ps_pulse->u32UsageRe & 0x00FF0000) >> 16;
    buff[u8index + 2] = (ps_pulse->u32UsageRe & 0x0000FF00) >> 8;
    buff[u8index + 3] = ps_pulse->u32UsageRe & 0x000000FF;
    u8index += 4;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 实时上报周期
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1420(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    buff[u8index] = (ps_flash->s_para.u32CommCycle & 0xFF00) >> 8;
    buff[u8index + 1] = ps_flash->s_para.u32CommCycle & 0x00FF; // 实时通讯间隔
    u8index += 2;

    memcpy(&buff[u8index], ps_flash->s_para.pu8DayUploadTime, 3);
    u8index += 3;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 通讯可靠机制配置
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1423(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    gw_u16 u16ReConnectTime = ps_flash->s_para.u16ReConnectTime / 60;
    buff[u8index] = (u16ReConnectTime & 0xFF00) >> 8;
    buff[u8index + 1] = u16ReConnectTime & 0x00FF; // 连接失败后重试间隔
    u8index += 2;

    buff[u8index] = ps_flash->s_para.u8ReSendCnt;
    u8index++;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 异常流量检测配置
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1424(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    buff[u8index] = (ps_flash->s_para.u16LargeFlowThreshold & 0xFF00) >> 8;
    buff[u8index + 1] = ps_flash->s_para.u16LargeFlowThreshold & 0x00FF; // 过流阈值
    u8index += 2;
    buff[u8index] = (ps_flash->s_para.u16SmallFlowThreshold & 0xFF00) >> 8;
    buff[u8index + 1] = ps_flash->s_para.u16SmallFlowThreshold & 0x00FF; // 小流阈值
    u8index += 2;
    buff[u8index] = (ps_flash->s_para.u16ReverseFlowThreshold & 0xFF00) >> 8;
    buff[u8index + 1] = ps_flash->s_para.u16ReverseFlowThreshold & 0x00FF; // 反流阈值
    u8index += 2;
    buff[u8index] = (ps_flash->s_para.u16LargeFlowContinue & 0xFF00) >> 8;
    buff[u8index + 1] = ps_flash->s_para.u16LargeFlowContinue & 0x00FF; // 过流流量阈值
    u8index += 2;
    buff[u8index] = (ps_flash->s_para.u16SmallFlowContinue & 0xFF00) >> 8;
    buff[u8index + 1] = ps_flash->s_para.u16SmallFlowContinue & 0x00FF; // 小流流量阈值
    u8index += 2;
    buff[u8index] = (ps_flash->s_para.u16ReverseFlowDuration & 0xFF00) >> 8;
    buff[u8index + 1] = ps_flash->s_para.u16ReverseFlowDuration & 0x00FF; // 反流流量阈值
    u8index += 2;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 表计基本参数配置
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1425(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x03; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    buff[u8index] = (ps_flash->s_para.battery1_first_low_voltage_threshold & 0xFF00) >> 8;
    buff[u8index + 1] = ps_flash->s_para.battery1_first_low_voltage_threshold & 0x00FF;
    u8index += 2;
    buff[u8index] = (ps_flash->s_para.battery1_second_low_voltage_threshold & 0xFF00) >> 8;
    buff[u8index + 1] = ps_flash->s_para.battery1_second_low_voltage_threshold & 0x00FF;
    u8index += 2;
    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 查某日流量信息
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1151(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Flash_Day_Usage ps_day_usage;

    S_Flash_Day_Usage *ps_day;
    ps_day = &ps_flash->s_usage_info.s_day_usage;

    S_Cloud *ps_cloud;
    ps_cloud = Svc_Cloud_Get_Data();

    gw_u32 u32CurTotalUsage;
    gw_u32 u32ReverseTotalUsage;
    gw_u16 u16DayMaxFlow;
    if ((ps_ir_data->pu8QueryDate[0] == ps_cloud->s_manage.pu8CurTime[0]) && (ps_ir_data->pu8QueryDate[1] == ps_cloud->s_manage.pu8CurTime[1]) && (ps_ir_data->pu8QueryDate[2] == ps_cloud->s_manage.pu8CurTime[2]))
    {   //当天还未存储，直接从内存中获取数据
        u32CurTotalUsage = ps_day->s_realtime_usage.u32ForwardTotalUsage / 1000; // 累计正流
        buff[u8index] = (u32CurTotalUsage & 0xFF000000) >> 24;
        buff[u8index + 1] = (u32CurTotalUsage & 0x00FF0000) >> 16;
        buff[u8index + 2] = (u32CurTotalUsage & 0x0000FF00) >> 8;
        buff[u8index + 3] = u32CurTotalUsage & 0x000000FF;
        u8index += 4;
        u32ReverseTotalUsage = ps_day->s_realtime_usage.u32ReverseTotalUsage / 1000; // 累计逆流
        buff[u8index] = (u32ReverseTotalUsage & 0xFF000000) >> 24;
        buff[u8index + 1] = (u32ReverseTotalUsage & 0x00FF0000) >> 16;
        buff[u8index + 2] = (u32ReverseTotalUsage & 0x0000FF00) >> 8;
        buff[u8index + 3] = u32ReverseTotalUsage & 0x000000FF;
        u8index += 4;
        u16DayMaxFlow = ps_day->s_realtime_usage.u16DayMaxFlow; // 日最高流速
        buff[u8index] = (u16DayMaxFlow & 0xFF00) >> 8;
        buff[u8index + 1] = u16DayMaxFlow & 0x00FF;
        u8index += 2;

        memcpy(&buff[u8index], ps_day->s_realtime_usage.pu8DayMaxFlowTime, 6); // 日最高流量时间
        u8index += 6;

        memcpy(&buff[u8index], ps_cloud->s_manage.pu8CurTime, 6); // 水表采集时间
        u8index += 6;
    }
    else
    {
        //历史
        Svc_Flash_Read_Day_Usage(ps_ir_data->pu8QueryDate, &ps_day_usage);
        u32CurTotalUsage = ps_day_usage.s_realtime_usage.u32ForwardTotalUsage / 1000; // 累计正流
        buff[u8index] = (u32CurTotalUsage & 0xFF000000) >> 24;
        buff[u8index + 1] = (u32CurTotalUsage & 0x00FF0000) >> 16;
        buff[u8index + 2] = (u32CurTotalUsage & 0x0000FF00) >> 8;
        buff[u8index + 3] = u32CurTotalUsage & 0x000000FF;
        u8index += 4;
        u32ReverseTotalUsage = ps_day_usage.s_realtime_usage.u32ReverseTotalUsage / 1000; // 累计逆流
        buff[u8index] = (u32ReverseTotalUsage & 0xFF000000) >> 24;
        buff[u8index + 1] = (u32ReverseTotalUsage & 0x00FF0000) >> 16;
        buff[u8index + 2] = (u32ReverseTotalUsage & 0x0000FF00) >> 8;
        buff[u8index + 3] = u32ReverseTotalUsage & 0x000000FF;
        u8index += 4;
        u16DayMaxFlow = ps_day_usage.s_realtime_usage.u16DayMaxFlow; // 日最高流速
        buff[u8index] = (u16DayMaxFlow & 0xFF00) >> 8;
        buff[u8index + 1] = u16DayMaxFlow & 0x00FF;
        u8index += 2;

        memcpy(&buff[u8index], ps_day_usage.s_realtime_usage.pu8DayMaxFlowTime, 6); // 日最高流量时间
        u8index += 6;

        memcpy(&buff[u8index], ps_day_usage.s_realtime_usage.pu8UsageCollectTime, 3); // 水表采集时间
        u8index += 3;
        buff[u8index] = 23;
        buff[u8index + 1] = 59;
        buff[u8index + 2] = 59;
        u8index += 3;
    }

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 查询 6 个月内日区间明细
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note: 每包只发一天，分包由接收线程处理，按日期发送
 * @see:
 */
static void Svc_Ir_Creat_Func1502(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    S_Flash_Day_Usage ps_day_usage;

    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    memcpy(&buff[u8index], ps_ir_data->pu8QueryDate, 3);
    u8index += 3;
    buff[u8index] = 1;
    u8index++;
    Svc_Flash_Read_Day_Usage(ps_ir_data->pu8QueryDate, &ps_day_usage);
    for (gw_u8 i = 0; i < 24; i++)
    {
        buff[u8index] = (ps_day_usage.pu16Data[i] & 0xFF00) >> 8;
        buff[u8index + 1] = ps_day_usage.pu16Data[i] & 0x00FF;
        u8index += 2;
    }

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 查询 36 个月内月区间明细
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1504(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Flash_Month_Usage ps_month_usage;

    memcpy(&buff[u8index], ps_ir_data->pu8QueryDate, 2);
    u8index += 2;
    buff[u8index] = ps_ir_data->u8QueryNum;
    u8index++;
    gw_u8 StatrMonth[2];
    memcpy(StatrMonth, ps_ir_data->pu8QueryDate, 2);

    for (gw_u8 i = 0; i < ps_ir_data->u8QueryNum; i++)
    {
        Bsp_Iwdg_Feed();
        Svc_Flash_Read_Month_Usage(ps_ir_data->pu8QueryDate, &ps_month_usage);
        Util_Time_Cal_Month(StatrMonth, i, ps_ir_data->pu8QueryDate);
        buff[u8index] = (ps_month_usage.u32monthusage & 0xFF00) >> 8;
        buff[u8index + 1] = ps_month_usage.u32monthusage & 0x00FF;
        u8index += 2;
    }

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 机电同步
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1C01(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    buff[u8index] = (ps_pulse->u32BaseUsage & 0xFF000000) >> 24;
    buff[u8index + 1] = (ps_pulse->u32BaseUsage & 0x00FF0000) >> 16;
    buff[u8index + 2] = (ps_pulse->u32BaseUsage & 0x0000FF00) >> 8;
    buff[u8index + 3] = ps_pulse->u32BaseUsage & 0x000000FF;
    u8index += 4;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 密集周期流量信息
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1141(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Flash_Day_Usage ps_day_usage;

    Svc_Flash_Read_Day_Usage(ps_ir_data->pu8QueryDate, &ps_day_usage);
    
    memcpy(&buff[u8index], ps_day_usage.s_dense_usage.pu8StartTime, 6);
    u8index += 6;
    buff[u8index] = ps_day_usage.s_dense_usage.u8TimeInterval;
    u8index++;
    buff[u8index] = 48;
    u8index++;
    for (gw_u8 i = 0; i < 48; i++)
    {
        buff[u8index] = (ps_day_usage.s_dense_usage.pu16ForwardUsage[i] & 0xFF00) >> 8;
        buff[u8index + 1] = ps_day_usage.s_dense_usage.pu16ForwardUsage[i] & 0x00FF;
        u8index += 2;
    }
    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 表状态
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1608(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();

    buff[u8index] = (ps_flash->s_security.s_state.u32device_alarm & 0xFF000000) >> 24;
    buff[u8index + 1] = (ps_flash->s_security.s_state.u32device_alarm & 0x00FF0000) >> 16;
    buff[u8index + 2] = (ps_flash->s_security.s_state.u32device_alarm & 0x0000FF00) >> 8;
    buff[u8index + 3] = ps_flash->s_security.s_state.u32device_alarm & 0x000000FF;
    u8index += 4;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 读时间段事件记录
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func1609(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;

    gw_u8 u8ActLen;
    E_Flash_Meter_Event meter_event = (E_Flash_Meter_Event)s_ir_data.Event;
    gw_u8 u8BcdStatr[6], u8BcdEnd[6];
    for (gw_u8 i = 0; i < 6; i++)
    {
        u8BcdStatr[i] = Util_Data_Decimal_To_Bcd(s_ir_data.Event_StatrTime[i]);
        u8BcdEnd[i] = Util_Data_Decimal_To_Bcd(s_ir_data.Event_EndTime[i]);
    }
    gw_u8 pu8EventData[Meter_Event_Entry_Len_Max * 9];
    u8ActLen = Svc_Flash_Time_Quantum_Meter_Event(meter_event, u8BcdStatr, u8BcdEnd, s_ir_data.Event_Num, pu8EventData);
    buff[u8index] = u8ActLen; // 记录条数
    u8index++;
    memcpy(&buff[u8index], pu8EventData, u8ActLen * 9); // 事件记录数据
    u8index += u8ActLen * 9;
    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 读最新事件记录
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func160A(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    gw_u8 u8ActLen;
    E_Flash_Meter_Event meter_event = (E_Flash_Meter_Event)s_ir_data.Event;
    gw_u8 pu8EventData[Meter_Event_Entry_Len_Max * 9];
    u8ActLen = Svc_Flash_New_Meter_Event(meter_event, s_ir_data.Event_Num, pu8EventData);
    buff[u8index] = u8ActLen; // 记录条数
    u8index++;
    memcpy(&buff[u8index], pu8EventData, u8ActLen * 9); // 事件记录数据
    u8index += u8ActLen * 9;
    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 模组设备信息
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func3001(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();
    memcpy(&buff[u8index], ps_pulse->s_pulse_para.pu8Pulse_Devic_Id, 4); // 设备ID
    u8index += 4;
    memcpy(&buff[u8index], ps_pulse->s_pulse_para.pu8Pulse_Manufac_Id, 4); // 制造商ID
    u8index += 4;
    buff[u8index] = ps_pulse->s_pulse_para.u8Pulse_Devic_Type; // 设备类型
    u8index++;
    buff[u8index] = (ps_pulse->s_pulse_para.u16Pulse_Sw_Ver & 0xFF00) >> 8; // 软件版本
    buff[u8index + 1] = ps_pulse->s_pulse_para.u16Pulse_Sw_Ver & 0x00FF;
    u8index += 2;
    buff[u8index] = (ps_pulse->s_pulse_para.u16Pulse_Hw_Ver & 0xFF00) >> 8; // 硬件版本
    buff[u8index + 1] = ps_pulse->s_pulse_para.u16Pulse_Hw_Ver & 0x00FF;
    u8index += 2;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 模组通信波特率
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func3002(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    switch (ps_pulse->s_pulse_para.u16Baudrate)
    {
    case 9600:
        buff[u8index] = 0xBD;
        break;
    case 4800:
        buff[u8index] = 0xBC;
        break;
    case 2400:
        buff[u8index] = 0xBB;
        break;
    default:
        break;
    }
    u8index++;
    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 模组工作模式
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func3003(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    buff[u8index] = ps_pulse->s_pulse_para.ePulseMode;
    u8index++;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 模组运行时间
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func3005(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    buff[u8index] = (ps_pulse->s_pulse_para.u32Runtime & 0xFF000000) >> 24;
    buff[u8index + 1] = (ps_pulse->s_pulse_para.u32Runtime & 0x00FF0000) >> 16;
    buff[u8index + 2] = (ps_pulse->s_pulse_para.u32Runtime & 0x0000FF00) >> 8;
    buff[u8index + 3] = ps_pulse->s_pulse_para.u32Runtime & 0x000000FF;
    u8index += 4;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 管段参数
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func3010(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    buff[u8index] = ps_pulse->s_pulse_para.u8PipeMode;
    u8index++;
    buff[u8index] = (ps_pulse->s_pulse_para.u16SonicLength & 0xFF00) >> 8;
    buff[u8index + 1] = ps_pulse->s_pulse_para.u16SonicLength & 0x00FF;
    u8index += 2;
    buff[u8index] = (ps_pulse->s_pulse_para.u16ActiveSonicLength & 0xFF00) >> 8;
    buff[u8index + 1] = ps_pulse->s_pulse_para.u16ActiveSonicLength & 0x00FF;
    u8index += 2;
    buff[u8index] = (ps_pulse->s_pulse_para.u16Diameter & 0xFF00) >> 8;
    buff[u8index + 1] = ps_pulse->s_pulse_para.u16Diameter & 0x00FF;
    u8index += 2;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 始动流速
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func3011(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    buff[u8index] = (ps_pulse->s_pulse_para.u16SatrtSpeed & 0xFF00) >> 8;
    buff[u8index + 1] = ps_pulse->s_pulse_para.u16SatrtSpeed & 0x00FF;
    u8index += 2;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 零点参数
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func3012(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    buff[u8index] = (ps_pulse->s_pulse_para.u32ZeroPara & 0xFF000000) >> 24;
    buff[u8index + 1] = (ps_pulse->s_pulse_para.u32ZeroPara & 0x00FF0000) >> 16;
    buff[u8index + 2] = (ps_pulse->s_pulse_para.u32ZeroPara & 0x0000FF00) >> 8;
    buff[u8index + 3] = ps_pulse->s_pulse_para.u32ZeroPara & 0x000000FF;
    u8index += 4;

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 修正系数
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func3013(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    gw_u32 s32CorrPointA;
    gw_u32 s32CorrPointB;
    gw_u8 u8Num = ps_pulse->s_pulse_para.u8CorrPointNum;
    buff[u8index] = u8Num;
    for (gw_u8 i = 0; i < u8Num; i++)
    {
        s32CorrPointA = ps_pulse->s_pulse_para.s32CorrPoint[i][0];
        s32CorrPointB = ps_pulse->s_pulse_para.s32CorrPoint[i][1];
        buff[u8index] = (s32CorrPointA & 0xFF000000) >> 24;
        buff[u8index + 1] = (s32CorrPointA & 0x00FF0000) >> 16;
        buff[u8index + 2] = (s32CorrPointA & 0x0000FF00) >> 8;
        buff[u8index + 3] = s32CorrPointA & 0x000000FF;
        u8index += 4;
        buff[u8index] = (s32CorrPointB & 0xFF000000) >> 24;
        buff[u8index + 1] = (s32CorrPointB & 0x00FF0000) >> 16;
        buff[u8index + 2] = (s32CorrPointB & 0x0000FF00) >> 8;
        buff[u8index + 3] = s32CorrPointB & 0x000000FF;
        u8index += 4;
    }

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 零点测试模式
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */ 
static void Svc_Ir_Creat_Func3014(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();
    
    if(ps_pulse->s_pulse_para.u8ZeroModeEn == 1)
    {
      buff[u8index] = 0x01;
      u8index++;
    }
    else if(ps_pulse->s_pulse_para.u8ZeroModeEn == 0)
    {
      buff[u8index] = 0x00;
      u8index++;
      buff[u8index] = (ps_pulse->s_pulse_para.u32ZeroPara & 0xFF000000) >> 24;
      buff[u8index + 1] = (ps_pulse->s_pulse_para.u32ZeroPara & 0x00FF0000) >> 16;
      buff[u8index + 2] = (ps_pulse->s_pulse_para.u32ZeroPara & 0x0000FF00) >> 8;
      buff[u8index + 3] = ps_pulse->s_pulse_para.u32ZeroPara & 0x000000FF;  
      u8index += 4;
    }
    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 查询100日内的日流量数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func30A0(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    memcpy(&buff[u8index], ps_pulse->s_pulse_para.s_pulse_day_history.pu8Query_StartDay, 3);
    u8index += 3;
    gw_u8 DayNum = ps_pulse->s_pulse_para.s_pulse_day_history.u8Query_DayNum;
    buff[u8index] = DayNum;
    u8index++;
    for (gw_u8 i = 0; i < DayNum; i++)
    {
        buff[u8index] = (ps_pulse->s_pulse_para.s_pulse_day_history.pu8Day_Usage[i] & 0xFF000000) >> 24;
        buff[u8index + 1] = (ps_pulse->s_pulse_para.s_pulse_day_history.pu8Day_Usage[i] & 0x00FF0000) >> 16;
        buff[u8index + 2] = (ps_pulse->s_pulse_para.s_pulse_day_history.pu8Day_Usage[i] & 0x0000FF00) >> 8;
        buff[u8index + 3] = ps_pulse->s_pulse_para.s_pulse_day_history.pu8Day_Usage[i] & 0x000000FF;
        u8index += 4;
    }

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 查询 60个月内月流量数据
 * @param：{S_Ir_Data}*ps_ir_data
 * @return {void}
 * @note:
 * @see:
 */
static void Svc_Ir_Creat_Func30A1(S_Ir_Data *ps_ir_data)
{
    gw_u8 *buff = ps_ir_data->pu8Buff;
    gw_u8 u8index = ps_ir_data->u16BuffLen;
    buff[u8index] = (ps_ir_data->e_func_code_ir & 0xFF00) >> 8;
    buff[u8index + 1] = ps_ir_data->e_func_code_ir & 0x00FF; // 功能片段码
    u8index += 2;
    buff[u8index] = 0x01; // 片段类型
    u8index++;
    gw_u16 FuncLenIndex = u8index; // 片段长度所在位置
    u8index += 2;
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();

    gw_u8 MonthNum = ps_pulse->s_pulse_para.s_pulse_month_history.u8Query_MonthNum;
    memcpy(&buff[u8index], ps_pulse->s_pulse_para.s_pulse_month_history.pu8Query_StartMonth, 2);
    u8index += 2;
    buff[u8index] = MonthNum;
    u8index++;
    for (gw_u8 i = 0; i < MonthNum; i++)
    {
        buff[u8index] = (ps_pulse->s_pulse_para.s_pulse_month_history.puMonth_Usage[i] & 0xFF000000) >> 24;
        buff[u8index + 1] = (ps_pulse->s_pulse_para.s_pulse_month_history.puMonth_Usage[i] & 0x00FF0000) >> 16;
        buff[u8index + 2] = (ps_pulse->s_pulse_para.s_pulse_month_history.puMonth_Usage[i] & 0x0000FF00) >> 8;
        buff[u8index + 3] = ps_pulse->s_pulse_para.s_pulse_month_history.puMonth_Usage[i] & 0x000000FF;
        u8index += 4;
    }

    buff[FuncLenIndex] = ((u8index - FuncLenIndex - 2) & 0xFF00) >> 8;
    buff[FuncLenIndex + 1] = (u8index - FuncLenIndex - 2) & 0x00FF;
    ps_ir_data->u16BuffLen = u8index;
}

/**
 * @brief: 模组应答处理
 * @param：{void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Module_Ack_Deal(void)
{
    S_Pulse_Data_Ack *ps_pulse_ack;
    ps_pulse_ack = Svc_Get_Pulse_Protocol_Ack();
    E_Comm_Result e_result = COMM_00_NORMAL;
    E_Cmd_Code_Pulse e_cmd_code = ps_pulse_ack->e_cmd_code_pulse;
    Bsp_Iwdg_Feed();
    if (ps_pulse_ack->u8ack == 0x01) // 有回应
    {
        if ((ps_pulse_ack->e_cmd_code_pulse != CMD_C1_QUERY_USAGE_DATA) && (ps_pulse_ack->e_func_code_pulse != FUNC_20_QUERY_CURRENT_USAGE))
        {
            if (ps_pulse_ack->e_comm_result_pulse != COMM_00_PULSE_NORMAL) // 处理失败了
            {
                switch (ps_pulse_ack->e_comm_result_pulse)
                {
                case COMM_01_PULSE_ERROR_PARA:
                    e_result = COMM_02_ERROR_PARA;
                    break;
                case COMM_02_PULSE_ERROR_CMD_NO_SUPPORT:
                    e_result = COMM_04_ERROR_CMD_NO_SUPPORT;
                    break;
                case COMM_FF_PULSE_ERROR_SYS:
                    e_result = COMM_FF_ERROR_SYS;
                    break;
                default:
                    break;
                }
            }
            switch (e_cmd_code)
            {
            case CMD_41_QUERY_DEVICE_INFO:
                Svc_Pulse_Cmd41_Ack(ps_pulse_ack, e_result);
                break;
            case CMD_42_QUERY_MEASURE_PARA:
                Svc_Pulse_Cmd42_Ack(ps_pulse_ack, e_result);
                break;
            case CMD_81_SET_DEVICE_INFO:
                Svc_Pulse_Cmd81_Ack(ps_pulse_ack, e_result);
                break;
            case CMD_82_SET_MEASURE_PARA:
                Svc_Pulse_Cmd82_Ack(ps_pulse_ack, e_result);
                break;
            case CMD_C1_QUERY_USAGE_DATA:
                Svc_Pulse_CmdC1_Ack(ps_pulse_ack, e_result);
                break;
            case CMD_C3_PROPRIETARY_PROTOCOL:
                Svc_Pulse_CmdC3_Ack(ps_pulse_ack, e_result);
                break;
            default:
                break;
            }
            memset(&ps_pulse_ack, 0, sizeof(S_Pulse_Data_Ack));
        }
    }
}

static void Svc_Pulse_Cmd41_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result)
{
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();
    switch (ps_pulse_ack->e_func_code_pulse)
    {
    case FUNC_01_METER_INFO:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_3001_PULSE_INFO, e_result);
        break;
    case FUNC_02_COMM_BAUDRATE:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_3002_PULSE_BAUDRATE, e_result);
        break;
    case FUNC_03_WORK_MODE:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_3003_PULSE_WORKMODE, e_result);
        if (ps_pulse->s_pulse_para.ePulseMode == E_Pulse_Mode_Calibra)
            Svc_Ir_Set_Keep_Alive_Time(7200);
        else
            Svc_Ir_Set_Keep_Alive_Time(IR_OPEN_TIME);
        break;
    case FUNC_05_RUN_TIME:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_3005_PULSE_RUNTIME, e_result);
        break;
    default:
        break;
    }
}

static void Svc_Pulse_Cmd42_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result)
{
    switch (ps_pulse_ack->e_func_code_pulse)
    {
    case FUNC_10_PIPE_PARA:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_3010_PULSE_PIPE_PARA, e_result);
        break;
    case FUNC_11_START_FLOW_SPEED:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_3011_PULSE_START_FLOW, e_result);
        break;
    case FUNC_12_ZERO_CORRECT_PARA:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_3012_PULSE_ZERO, e_result);
        break;
    case FUNC_13_CORRECT_PARA:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_3013_PULSE_CORRECT_PARA, e_result);
        break;
    default:
        break;
    }
}

static void Svc_Pulse_Cmd81_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result)
{
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    S_Pulse *ps_pulse;
    ps_pulse = Svc_Pulse_Get_Data();
    switch (ps_pulse_ack->e_func_code_pulse)
    {
    case FUNC_02_COMM_BAUDRATE:
        Svc_Ir_Protocol_Send_Cmd(CMD_83_SET_PULSE_PARA, IR_3002_PULSE_BAUDRATE, e_result);
        break;
    case FUNC_03_WORK_MODE:
        Svc_Ir_Protocol_Send_Cmd(CMD_83_SET_PULSE_PARA, IR_3003_PULSE_WORKMODE, e_result);
        if (ps_pulse->s_pulse_para.ePulseMode == E_Pulse_Mode_Calibra)
        {
            ps_flash->s_other.e_work_mode = E_Mode_Calibration;
        }
        else
        {
            ps_flash->s_other.e_work_mode = E_Mode_Normal;
        }
        break;
    case FUNC_04_CORRECT_TIME:
        Svc_Ir_Protocol_Send_Cmd(CMD_83_SET_PULSE_PARA, IR_3004_PULSE_TIME_CALIBRATE, e_result);
        break;
    default:
        break;
    }
}

static void Svc_Pulse_Cmd82_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result)
{
    switch (ps_pulse_ack->e_func_code_pulse)
    {
    case FUNC_10_PIPE_PARA:
        Svc_Ir_Protocol_Send_Cmd(CMD_83_SET_PULSE_PARA, IR_3010_PULSE_PIPE_PARA, e_result);
        break;
    case FUNC_11_START_FLOW_SPEED:
        Svc_Ir_Protocol_Send_Cmd(CMD_83_SET_PULSE_PARA, IR_3011_PULSE_START_FLOW, e_result);
        break;
    case FUNC_13_CORRECT_PARA:
        Svc_Ir_Protocol_Send_Cmd(CMD_83_SET_PULSE_PARA, IR_3013_PULSE_CORRECT_PARA, e_result);
        break;
    case FUNC_14_ZERO_MODE:
        Svc_Ir_Protocol_Send_Cmd(CMD_83_SET_PULSE_PARA, IR_3014_PULSE_ZEROMODE, e_result);
        break;
    case FUNC_15_SET_USAGE:
        Svc_Ir_Protocol_Send_Cmd(CMD_C0_OPERATE, IR_1C01_SYNC_DIAL_NUM, e_result);
        break;
    default:
        break;
    }
}

static void Svc_Pulse_CmdC1_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result)
{
    switch (ps_pulse_ack->e_func_code_pulse)
    {
    case FUNC_2A_CLEAR_CORRECT_DATA:
        Svc_Ir_Protocol_Send_Cmd(CMD_83_SET_PULSE_PARA, IR_302A_PULSE_CLEAR_CODATA, e_result);
        break;
    case FUNC_2C_CLEAR_ALL_DATA:
        Svc_Ir_Protocol_Send_Cmd(CMD_83_SET_PULSE_PARA, IR_302C_PULSE_CLEAR_ALL_DATA, e_result);
        break;
    default:
        break;
    }
}

static void Svc_Pulse_CmdC3_Ack(S_Pulse_Data_Ack *ps_pulse_ack, E_Comm_Result e_result)
{
    switch (ps_pulse_ack->e_func_code_pulse)
    {
    case FUNC_A0_DAY_HISTORICAL:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_30A0_PULSE_DAY_HISTORICAL, e_result);
        break;
    case FUNC_A1_MONTH_HISTORICAL:
        Svc_Ir_Protocol_Send_Cmd(CMD_43_QUERY_PULSE_PARA, IR_30A1_PULSE_MONTH_HISTORICAL, e_result);
        break;
    case FUNC_A2_CLOSE_SERIAL_PORT:
        Svc_Ir_Protocol_Send_Cmd(CMD_83_SET_PULSE_PARA, IR_30A2_PULSE_DEBUG_ENABLE, e_result);
        break;
    default:
        break;
    }
}