#include "parseDeviceMessage.h"
#include "cJson.h"
#include "systick.h"
#include "usart.h"
#include "string.h"
#include <math.h>
#include "mqttRecv.h"
#include "log.h"
#include "ec800m.h"
#include "main.h"

#define MQTT_SUB_CMD_WRITE 0
#define MQTT_SUB_CMD_READ 1
ring_buffer mqttRecv;
void processHTTPjson(cJSON *json);
char *processStringData(cJSON *data_obj, const char *key);
int processIntData(cJSON *data_obj, const char *key);
void processHttp(uint8_t *data);

static void extract_data_from_buffer(const char *buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr);
//static void extract_data_from_buffer232(const char *buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr);
static uint16_t checksum(const char *str, uint16_t len);

// json解析字符串
char *processStringData(cJSON *data_obj, const char *key)
{
  cJSON *json_data = cJSON_GetObjectItemCaseSensitive(data_obj, key);
  if (cJSON_IsString(json_data) && (json_data->valuestring != NULL))
  {
    return json_data->valuestring;
  }
  else
  {
    return NULL;
  }
}
// json解析int
int processIntData(cJSON *data_obj, const char *key)
{
  cJSON *json_data = cJSON_GetObjectItemCaseSensitive(data_obj, key);
  // if (cJSON_IsNumber(json_data) && (json_data->valueint != NULL)) 解决寄存器地址为0问题
  if (cJSON_IsNumber(json_data))
  {
    return json_data->valueint;
  }
  else
  {
    // gateway.data_valid_flag = 0; // 如果任意数据为NULL则此次数据为无效
    return -1;
  }
}



/*
 *  函数名：void WaitForUpData(void)
 *  输入参数：无
 *  输出参数：无
 *  返回值：无
 *  函数作用:等待更新本地flash信息
 */

bool WaitForUpData(void)
{
	if (UART0_RX_STAT > 0)
  {
    UART0_RX_STAT = 0;
    uint32_t len;
    uint16_t checkCode;
    extract_data_from_buffer(UART0_RX_BUF, &len, &checkCode);
		
    uint16_t jsonCheck = checksum(UART0_RX_BUF, len);
    if (checkCode == jsonCheck)
    {
				memset(UART0_RX_BUF + len, 0, sizeof(UART0_RX_BUF) - len);
			if(UART0_RX_NUM<1024)
				{
					cJSON *json = cJSON_Parse(UART0_RX_BUF);
					if (json != NULL)
					{
						processHTTPjson(json);
						cJSON_Delete(json);
						Clear_DMA_Buffer();
						return true;
					}
					else
					{
						cJSON_Delete(json);
						Clear_DMA_Buffer();
						LogPrint(LOG_INFO, __func__, __LINE__, "json is to long");
						return false;
					}
			}
			else
			{
				processHttp(UART0_RX_BUF);
			}
		}
  }
}






/*
 *  函数名：static void extract_data_from_buffer(const char* buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr)
 *  输入参数：buffer字符串
 *  输出参数：json有效字符串长度len_ptr,checkCode_ptr校验码指针
 *  返回值：无
 *  函数作用:eg.   QFDWL: 621,3e23  从json信息最后端取出这段json的有效长度和校验码
 */
static void extract_data_from_buffer(const char *buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr)
{
  char *start = strstr(buffer, "+QFDWL:");
  if (start != NULL)
  {
    start += 8; // 跳过"+QFDWL:"
    uint32_t len = 0;
    sscanf(start, "%u,", &len);     // 读取长度
    start = strchr(start, ',') + 1; // 跳过逗号
    uint16_t checkCode = 0;
    sscanf(start, "%hx", &checkCode); // 读取16进制数据
    // 将提取的数据存入形参
    *len_ptr = len;
    *checkCode_ptr = checkCode;
  }
}
/*
 *  函数名：void processHTTPjson(cJSON *json)
 *  输入参数：json从http get获取的json字符串
 *  输出参数：无
 *  返回值：无
 *  函数作用:解析json字符串将设备配置信息写到flash中 strcpy NULL指针导致的内存泄露问题
 */
void processHTTPjson(cJSON *json)
{
  CONFIG_PARAMS gateway;
  gateway.data_valid_flag = 0xF1; // 将数据标识位置为有效
  cJSON *readArrayItem = cJSON_GetObjectItem(json, "sensorData");
  gateway.device_read_data_num = cJSON_GetArraySize(readArrayItem);
  cJSON *writeArrayItem = cJSON_GetObjectItem(json, "commandData");
  gateway.device_write_data_num = cJSON_GetArraySize(writeArrayItem);

  strcpy(gateway.host, processStringData(json, "host"));
  gateway.port = processIntData(json, "port");
  //strcpy(gateway.deviceId, processStringData(json, "deviceId"));  这条数据将不在进行解析由芯片id决定
  strcpy(gateway.messageTopic, processStringData(json, "messageTopic"));
  strcpy(gateway.commandTopic, processStringData(json, "commandTopic"));
  gateway.dataSource = processIntData(json, "dataSource");
  gateway.baudrate = processIntData(json, "baudrate");
  gateway.dataBits = processIntData(json, "dataBit");
	gateway.stopBit = processIntData(json, "stopBit");
	
  gateway.checkBit = processIntData(json, "checkBit");
  gateway.flowControl = processIntData(json, "flowControl");
  gateway.dataType645 = processIntData(json, "version645");
	gateway.inboundTime=	processIntData(json, "inboundTime");
	gateway.pollTime=	processIntData(json, "pollTime");	

  if (cJSON_IsArray(readArrayItem))
  {
    for (int i = 0; i < gateway.device_read_data_num; i++)
    {
      cJSON *read_data_obj = cJSON_GetArrayItem(readArrayItem, i);
      if (cJSON_IsObject(read_data_obj))
      {
        if (gateway.dataSource == MODBUS)
        {
          strcpy(gateway.device_read_data[i].deviceId, processStringData(read_data_obj, "deviceId"));
          strcpy(gateway.device_read_data[i].keyword, processStringData(read_data_obj, "identifier"));
          gateway.device_read_data[i].mdbSlave = processIntData(read_data_obj, "slaveAddress");
          gateway.device_read_data[i].mdbRegister = processIntData(read_data_obj, "registerAddress");
          gateway.device_read_data[i].mdbFunctionCode = processIntData(read_data_obj, "rFunctionCode");
          gateway.device_read_data[i].registerLength = processIntData(read_data_obj, "registerByteNum");
          gateway.device_read_data[i].decimalPoint = processIntData(read_data_obj, "precise");
          gateway.device_read_data[i].bigLittleFormat=processIntData(read_data_obj,"bigLittleFormat");

        }
        else if (gateway.dataSource == DLT645)
        {
          strcpy(gateway.device_read_data[i].deviceId, processStringData(read_data_obj, "deviceId"));
          strcpy(gateway.device_read_data[i].keyword, processStringData(read_data_obj, "identifier"));
          gateway.device_read_data[i].dataType645 = processIntData(read_data_obj, "identifier645");
          char idstring[13];
          strcpy(idstring, processStringData(read_data_obj, "deviceID645"));
          // 将deviceID645 由string变成0x
          for (int j = 0; j < 6; j++)
          {
            {
              uint8_t byte;
              sscanf((const char *)&idstring[j * 2], "%2hhx", &byte);
              gateway.device_read_data[i].deviceID645[j] = byte;
            }
          }
        }
      }
			
    }
    //写数据预存数组
    for (int i = 0; i < gateway.device_write_data_num; i++)
    {
      cJSON *write_data_obj = cJSON_GetArrayItem(writeArrayItem, i);
      if (gateway.dataSource == MODBUS)
      {
        strcpy(gateway.device_write_data[i].deviceId, processStringData(write_data_obj, "deviceId"));
          strcpy(gateway.device_write_data[i].keyword, processStringData(write_data_obj, "identifier"));
          gateway.device_write_data[i].mdbSlave = processIntData(write_data_obj, "slaveAddress");
          gateway.device_write_data[i].mdbRegister = processIntData(write_data_obj, "registerAddress");
          gateway.device_write_data[i].mdbFunctionCode = processIntData(write_data_obj, "wFunctionCode");
          gateway.device_write_data[i].registerLength = processIntData(write_data_obj, "registerByteNum");
          gateway.device_write_data[i].decimalPoint = processIntData(write_data_obj, "precise");
          gateway.device_write_data[i].bigLittleFormat=processIntData(write_data_obj,"bigLittleFormat");
      }
			
    }
  }
  save_config_params(&gateway);
}
//提取int数据
int parseIntField(const char* data, const char* field) {
    char* ptr = strstr(data, field) + strlen(field);
		int value;
    value = strtol(ptr, &ptr, 10);
		return value;
}

//提取string字符串
void parseStringField(const char* data, const char* field, char* value) {
    char* ptr = strstr(data, field) + strlen(field) ; 
    sscanf(ptr, "%[^\"],", value);
}


void parseCommandData();



void processHttp(uint8_t *data)
{
		CONFIG_PARAMS gateway;
		gateway.data_valid_flag = 0xF1; 
    char* ptr = (char*)data;
   
		
		gateway.dataSource=parseIntField(ptr,"\"dataSource\":");
		gateway.baudrate=parseIntField(ptr,"\"baudrate\":");
		gateway.checkBit=parseIntField(ptr,"\"checkBit\":");
		parseStringField(ptr,"\"commandTopic\":\"",(char *)&gateway.commandTopic);
		gateway.dataBits=parseIntField(ptr,"\"dataBit\":");
		parseStringField(ptr,"\"deviceId\":\"",(char *)&gateway.deviceId);
		parseStringField(ptr,"\"host\":\"",(char *)&gateway.host);
		gateway.inboundTime=parseIntField(ptr,"\"inboundTime\":");
		parseStringField(ptr,"\"messageTopic\":\"",(char *)&gateway.messageTopic);
		gateway.pollTime=parseIntField(ptr,"\"pollTime\":");
		gateway.port=parseIntField(ptr,"\"port\":");
		if(gateway.dataSource==2)											//为MODBUS
		{
			ptr = strstr(ptr, "\"commandData\":[");                 
			int i=0;
			while(1)
			{
				gateway.device_write_data[i].bigLittleFormat=parseIntField(ptr,"\"bigLittleFormat\":");
				parseStringField(ptr,"\"deviceId\":\"",(char *)&gateway.device_write_data[i].deviceId);
				parseStringField(ptr,"\"identifier\":\"",(char *)&gateway.device_write_data[i].keyword);
				gateway.device_write_data[i].registerLength =parseIntField(ptr,"\"registerByteNum\":\"");
				gateway.device_write_data[i].mdbRegister=parseIntField(ptr,"\"registerAddress\":");
				gateway.device_write_data[i].mdbSlave =parseIntField(ptr,"\"slaveAddress\":");
				gateway.device_write_data[i].mdbFunctionCode=parseIntField(ptr,"\"wFunctionCode\":");
				ptr=strstr(ptr,"}");									//移动位置到结束
				ptr++;
				if(ptr[0]==']')
				{
					i++;
				  gateway.device_write_data_num=i;
					ptr = (char*)data;
					break;
				}
				
				ptr = strchr(ptr, ',');
				
				if (!ptr)
				{
					i++;
					gateway.device_write_data_num=i;
					ptr = (char*)data;
					break;
				}
				i++;
			}
			ptr=strstr(ptr,"\"sensorData\":[");
			i=0;
			while(*ptr != ']')
			{
				gateway.device_read_data[i].bigLittleFormat=parseIntField(ptr,"\"bigLittleFormat\":");
				parseStringField(ptr,"\"deviceId\":\"",(char *)&gateway.device_read_data[i].deviceId);
				parseStringField(ptr,"\"identifier\":\"",(char *)&gateway.device_read_data[i].keyword);
				gateway.device_read_data[i].mdbRegister=parseIntField(ptr,"\"registerAddress\":");
				gateway.device_read_data[i].mdbSlave =parseIntField(ptr,"\"slaveAddress\":");
				gateway.device_read_data[i].registerLength =parseIntField(ptr,"\"registerByteNum\":");
				gateway.device_read_data[i].mdbFunctionCode=parseIntField(ptr,"\"rFunctionCode\":");
				gateway.device_read_data[i].decimalPoint=parseIntField(ptr,"\"precise\":");
				ptr=strstr(ptr,"}");									//移动位置到结束
				ptr++;
				if(ptr[0]==']')
				{
					i++;
				  gateway.device_read_data_num=i;
					ptr = (char*)data;
					break;
				}
				
				ptr = strchr(ptr, ',');
				
				if (!ptr)
				{
					i++;
					gateway.device_read_data_num=i;
					ptr = (char*)data;
					break;
				}
				i++;
			}
		}
		
		else if(gateway.dataSource==1)               //为dlt645协议
		{
			gateway.dataType645=parseIntField(ptr,"\"version645\":");
			ptr=strstr(ptr,"\"sensorData\":[");
			int i=0;
			while(*ptr != ']')
			{
				char *string=malloc(13);
				parseStringField(ptr,"\"deviceID645\":\"",string);
				for (int j = 0; j < 6; j++)
        { 
          {
            uint8_t byte;
            sscanf((const char *)&string[j * 2], "%2hhx", &byte);
            gateway.device_read_data[i].deviceID645[j] = byte;
          }
        }
				free(string);
				parseStringField(ptr, "\"deviceId\":\"",(char *)&gateway.device_read_data[i].deviceId);
				parseStringField(ptr, "\"identifier\":\"",(char *)&gateway.device_read_data[i].keyword);
				gateway.device_read_data[i].dataType645=parseIntField(ptr,"\"identifier645\":");
				ptr=strstr(ptr,"}");
				ptr++;
				if(ptr[0]==']')
				{
					i++;
				  gateway.device_read_data_num=i;
					ptr = (char*)data;
					break;
				}
				
				ptr = strchr(ptr, ',');
				
				if (!ptr)
				{
					i++;
					gateway.device_read_data_num=i;
					ptr = (char*)data;
					break;
				}
				i++;
			}
		}
		ptr=NULL;
		save_config_params(&gateway);
}
/*
 *  函数名： void mmodbusRead(CONFIG_PARAMS * gateway)
 *  输入参数：gateway网关存储的配置参数
 *  输出参数：网关结构体指针
 *  返回值：无
 *  函数作用:根据存储的设备信息发送modbus信息返回值存储到gateway->device_read_data[i].data中
 *           modbusRead读数据只考虑读16位寄存器和32位寄存器这两种情况，但对其返回值进行处理后返回值一律为float型4个字节存储在内部
 */
void modbusRead(CONFIG_PARAMS *gateway)
{
  for (int i = 0; i < gateway->device_read_data_num; i++)
  {
		delay_1ms(100);
    uint16_t data[gateway->device_read_data[i].registerLength/2];
		mmodbus_set16bitOrder(gateway->device_read_data[i].bigLittleFormat);
    if (gateway->device_read_data[i].mdbFunctionCode == 0x03)
    {
      bool success = mmodbus_readHoldingRegisters16i(gateway->device_read_data[i].mdbSlave,
                                                     gateway->device_read_data[i].mdbRegister,
                                                     gateway->device_read_data[i].registerLength/2,
                                                     data);
      if (success)
      {
        if (gateway->device_read_data[i].registerLength == 4)
        {
          uint32_t value = (uint32_t)data[0] << 16 | data[1];
          gateway->device_read_data[i].rxLen = 4;
					//增加小数点为0则gateway->device_read_data[i].data内存储为整形数据
					if(gateway->device_read_data[i].decimalPoint!=0)																//小数点不为0的清空
					{
						float convertedValue = (float)value / pow(10, gateway->device_read_data[i].decimalPoint);
						memcpy(gateway->device_read_data[i].data, &convertedValue, 4);
					}
					else if(gateway->device_read_data[i].decimalPoint==0)														//小数点为0
					{
						gateway->device_read_data[i].data[0]=value;
						gateway->device_read_data[i].data[1]=value<<8;
						gateway->device_read_data[i].data[2]=value<<16;
						gateway->device_read_data[i].data[3]=value<<24;
					}
        }
        else if (gateway->device_read_data[i].registerLength == 2)
        {
					
          uint32_t value = data[0];
          gateway->device_read_data[i].rxLen = 4;
          if(gateway->device_read_data[i].decimalPoint!=0)																//小数点不为0的清空
					{
						float convertedValue = (float)value / pow(10, gateway->device_read_data[i].decimalPoint);
						memcpy(gateway->device_read_data[i].data, &convertedValue, 4);
					}
					else if(gateway->device_read_data[i].decimalPoint==0)														//小数点为0
					{
						gateway->device_read_data[i].data[0]=value;
						gateway->device_read_data[i].data[1]=value<<8;
						gateway->device_read_data[i].data[2]=value<<16;
						gateway->device_read_data[i].data[3]=value<<24;
					}
        }
      }
      else
      {
        gateway->device_read_data[i].rxLen = 0;
      }
    }
    else if (gateway->device_read_data[i].mdbFunctionCode == 0x01)
    {
      uint8_t data[2];
			mmodbus_set16bitOrder(gateway->device_read_data[i].bigLittleFormat);
      bool success = mmodbus_readCoils(gateway->device_read_data[i].mdbSlave,
                                       gateway->device_read_data[i].mdbRegister,
                                       gateway->device_read_data[i].registerLength,
                                       data);
      if (success)
      {
        uint32_t value = (uint32_t)data[0] << 8 | data[1];
        gateway->device_read_data[i].rxLen = 4;
      }
      else
      {
        gateway->device_read_data[i].rxLen = 0;
      }
    }
		task_fwdgt_reload();
  }
}


/*
 *  函数名：void parseMQTTData(CONFIG_PARAMS *gateway)
 *  输入参数：device存储的各类产品信息
 *  输出参数：无
 *  返回值：无
 *  函数作用:从环形缓冲区中一个个把json信息读出，与存储的gateway内的子设备信息匹配后将对应指令匹配执行并返回相应的值
 *  查询逻辑现在有两套数组read数组和write数组，当接收中断产生时先判断是进行读还是写、之后在查询此网关支持的协议MODBUS还是
 *  645，后根据协议去不同数组查询不同的本地存储信息、组装发送给子设备,然后根据查询的值进行采集上传数据
 */
void parseMQTTData(CONFIG_PARAMS *gateway)
{
  while (UART0_RX_MQTT_SUB_STAT == 1)
  {
    UART0_RX_MQTT_SUB_STAT = 0;
    char payload_out[200];
    char mqtt_publish[200];
    char json[128];
    while (MQTT_BUFFER_READ(json))
    {
      LogPrint(LOG_INFO, __func__, __LINE__, "Received JSON: %s", json);
      cJSON *mqtt_sub_json = cJSON_Parse(json);
      if (mqtt_sub_json != NULL)
      {
        uint8_t action1[1];
        uint8_t action;
        strcpy(action1, processStringData(mqtt_sub_json, "action"));
        // 解决字符串为
        if (action1[0] == '0')
        {
          action = 0;
        }
        else if (action1[0] == '1')
        {
          action = 1;
        }
        uint8_t identifier[20];
        strcpy(identifier, processStringData(mqtt_sub_json, "identifier"));
        uint8_t deviceId[20];
        strcpy(deviceId, processStringData(mqtt_sub_json, "deviceId"));
        uint16_t value = processIntData(mqtt_sub_json, "parameter");
        uint8_t messageId[10];
        strcpy(messageId, processStringData(mqtt_sub_json, "messageId"));

        // 判断其指令过来是读还是写
        if (action == MQTT_SUB_CMD_WRITE)
        {
          for (int i = 0; i <= gateway->device_write_data_num; i++)
          {

            if (strcmp(gateway->device_write_data[i].deviceId, deviceId) == 0)
            {
              if (strcmp(gateway->device_write_data[i].keyword, identifier) == 0) // 寻找到对应存储的地址
              {
                if (gateway->dataSource == MODBUS)
                {
                  if (gateway->device_write_data[i].mdbFunctionCode == 0x05)
                  {
                    mmodbus_set16bitOrder(gateway->device_write_data[i].bigLittleFormat);
                    bool success = mmodbus_writeCoil(gateway->device_write_data[i].mdbSlave,
                                                     gateway->device_write_data[i].mdbRegister,
                                                     (uint8_t)value);
                    // 成功
                    if (success)
                    {
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
                              action1,
                              gateway->device_write_data[i].keyword,
                              gateway->device_write_data[i].deviceId, messageId, success);
                    }
                    else
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
                              action1,
                              gateway->device_write_data[i].keyword,
                              gateway->device_write_data[i].deviceId, messageId, success);
                  }
                  else if (gateway->device_write_data[i].mdbFunctionCode == 0x06)
                  {
                    mmodbus_set16bitOrder(gateway->device_write_data[i].bigLittleFormat);
                    bool success = mmodbus_writeHoldingRegister16i(gateway->device_write_data[i].mdbSlave,
                                                                   gateway->device_write_data[i].mdbRegister,
                                                                   (uint16_t)value);
                    if (success)
                    {
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
                              action1,
                              gateway->device_write_data[i].keyword,
                              gateway->device_write_data[i].deviceId, messageId, success);
                    }
                    else
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
                              action1,
                              gateway->device_write_data[i].keyword,
                              gateway->device_write_data[i].deviceId, messageId, success);
                  }
                  else
                  {
                    // 考虑后续兼容其他自定义协议
                  }
                }
                // DLT645暂时不支持写入操作
                else if (gateway->dataSource == DLT645)
                {
                  LogPrint(LOG_ERROR, __func__, __LINE__, "DLT645 does not support write instructions");
                }
              }
            }
            else
              LogPrint(LOG_ERROR, __func__, __LINE__, "No child device information matched to settings");
          }
        }
        // 指令是来读某属性值的
        else if (action == MQTT_SUB_CMD_READ)
        {
          for (int i = 0; i <= gateway->device_read_data_num; i++)
          {
            if (strcmp(gateway->device_read_data[i].deviceId, deviceId) == 0)
            {
              if (strcmp(gateway->device_read_data[i].keyword, identifier) == 0) // 寻找到对应存储的地址
              {
                if (gateway->dataSource == MODBUS)
                {
                  if (gateway->device_read_data[i].mdbFunctionCode == 0x01)
                  {
                    uint8_t data[2];
                    mmodbus_set16bitOrder(gateway->device_read_data[i].bigLittleFormat);
                    bool success = mmodbus_readCoils(gateway->device_read_data[i].mdbSlave,
                                                     gateway->device_read_data[i].mdbRegister,
                                                     gateway->device_read_data[i].registerLength,
                                                     data);
                    uint8_t value1;
                    if (success)
                    {
                      uint16_t value1 = (uint16_t)data[0] << 8 | data[1];
                      if (value1 == 0xFF00)
                      {
                        value1 = 1;
                      }
                      else if (value1 == 0x0000)
                      {
                        value1 = 0;
                      }
                      // 读线圈成功的json
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"parameter\":%d}",
                              action1,
                              gateway->device_read_data[i].keyword,
                              gateway->device_read_data[i].deviceId, messageId, success, value);
                    }
                    // 读线圈失败的json
                    else
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
                              action1,
                              gateway->device_read_data[i].keyword,
                              gateway->device_read_data[i].deviceId, messageId, success);
                  }
                  else if (gateway->device_read_data[i].mdbFunctionCode == 0x03)
                  {
                    uint16_t data[gateway->device_read_data[i].registerLength/2];
                    mmodbus_set16bitOrder(gateway->device_read_data[i].bigLittleFormat);
                    bool success = mmodbus_readHoldingRegisters16i(gateway->device_read_data[i].mdbSlave,
                                                                   gateway->device_read_data[i].mdbRegister,
                                                                   gateway->device_read_data[i].registerLength/2,
                                                                   data);
                    if (success)
                    {
                      float convertedValue;
                      if (gateway->device_read_data[i].registerLength == 2)
                      {
                        uint16_t value = data[0];
                        convertedValue = (float)value / pow(10, gateway->device_read_data[i].decimalPoint);
                      }
                      else if (gateway->device_read_data[i].registerLength == 4)
                      {
                        uint32_t value = (uint32_t)data[0] << 16 | data[1];
                        convertedValue = (float)value / pow(10, gateway->device_read_data[i].decimalPoint);
                      }
                      // 读寄存器值成功的json
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"value\":%.2f}",
                              action1,
                              gateway->device_read_data[i].keyword,
                              gateway->device_read_data[i].deviceId, messageId, success, convertedValue);
                    }
                    else
                    {
                      // 读寄存器失败的json
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
                              action1,
                              gateway->device_read_data[i].keyword,
                              gateway->device_read_data[i].deviceId, messageId, success);
                    }
                  }
                }
                else if (gateway->dataSource == DLT645)
                {
                  float value;
                  uint8_t minute, hour, day, month, year;
                  uint8_t read_buf[10];
                  gateway->device_read_data[i].rxLen = 0;
                  memset(read_buf, 0, 10);
                  memset(gateway->device_read_data[i].data, 0, 10); // 清空data内容
                  dlt645_set_addr(&dlt645, gateway->device_read_data[i].deviceID645);
                  int8_t rs = dlt645_read_data(&dlt645, gateway->device_read_data[i].dataType645, read_buf, DLT645_2007);
                  if (rs != -1)
                  {
                    if (rs <= 4)
                    {
                      memcpy(&value, read_buf, 4);
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"value\":%.2f}",
                              action1,
                              gateway->device_read_data[i].keyword,
                              gateway->device_read_data[i].deviceId, messageId, 1, value);
                    }
                    else if (rs == 5)
                    {
                      memcpy(&value, gateway->device_read_data[i].data, 4);
                      year = gateway->device_read_data[i].data[4];
                      month = gateway->device_read_data[i].data[3];
                      day = gateway->device_read_data[i].data[2];
                      hour = gateway->device_read_data[i].data[1];
                      minute = gateway->device_read_data[i].data[0];
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"value\":\"%02X%02X%02X%02X%02X\"}",
                              action1,
                              gateway->device_read_data[i].keyword,
                              gateway->device_read_data[i].deviceId, messageId, 1, year, month, day, hour, minute);
                    }
                    else if (rs > 5)
                    {
                      memcpy(&value, gateway->device_read_data[i].data, 4);
                      year = gateway->device_read_data[i].data[8];
                      month = gateway->device_read_data[i].data[7];
                      day = gateway->device_read_data[i].data[6];
                      hour = gateway->device_read_data[i].data[5];
                      minute = gateway->device_read_data[i].data[4];
                      sprintf((char *)payload_out,
                              "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"value\":\"%02X%02X%02X%02X%02X%.2f\"}",
                              action1,
                              gateway->device_read_data[i].keyword,
                              gateway->device_read_data[i].deviceId, messageId, 1, year, month, day, hour, minute, value);
                    }
                  }
                  else
                  {
                    // dlt645读取失败的json组成
                    sprintf((char *)payload_out,
                            "{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
                            action1,
                            gateway->device_read_data[i].keyword,
                            gateway->device_read_data[i].deviceId, messageId, 0);
                  }
                }
              }
            }
          }
        }
        // 上传对应的响应信息
        sprintf((char *)mqtt_publish, "AT+QMTPUBEX=0,0,0,0,\"%s\",%d\r\n", gateway->messageTopic, strlen(payload_out));
        EC800MSendCmd(mqtt_publish, strlen(mqtt_publish));
        WaitResponse("<", 1000);
        EC800MSendCmd(payload_out, strlen(payload_out));
        WaitResponse(RSP_OK, 1000);
      }
      cJSON_Delete(mqtt_sub_json);
    }
  }
}
/*
 *  函数名：void dlt645_read(CONFIG_PARAMS *gateway)
 *  输入参数：设备地址*address 数据标识 readCode
 *  输出参数：无
 *  返回值：无
 *  函数作用：读取645协议内部数据
备注：dlt645协议为网上下载，返回值为数据长度
      现在要加读日期信息YYMMDDhhmm
      对源代码改动不多的方法是通过返回的数据长度去做判断
      当数据长度为2、3、4时此时 read_buf数据包内仅含采集到的浮点数数据、          把float值4个字节直接拷贝出即可
      当数据长度为5时           read_buf数据包为日期数据                          其中5个字节分别为YYMMDDhhmm直接拷贝出来
      当数据长度大于5时         read_buf内既包含浮点数又包含日期时间              其中前4个字节为浮点数数据后五个字节为日期信息
*/


void dlt645_read(CONFIG_PARAMS *gateway)
{
  uint8_t read_buf[10];
  for (int i = 0; i < gateway->device_read_data_num; i++)
  {
    gateway->device_read_data[i].rxLen = 0;
    
    memset(read_buf, 0, 10);
    memset(gateway->device_read_data[i].data, 0, 10); 
    dlt645_set_addr(&dlt645, gateway->device_read_data[i].deviceID645);
		int8_t rs;
		if(gateway->dataType645==DLT645_2007){
			rs = dlt645_read_data(&dlt645, gateway->device_read_data[i].dataType645, read_buf, DLT645_2007);
		}
		else {
			rs = dlt645_read_data(&dlt645, gateway->device_read_data[i].dataType645, read_buf, DLT645_1997);
		}
    if (rs != -1)
    {
      if (rs <= 4)
      {
        memcpy(gateway->device_read_data[i].data, read_buf, 4);
        gateway->device_read_data[i].rxLen = rs;
      }
      else if (rs == 5)
      {
        memcpy(gateway->device_read_data[i].data, read_buf, 5);
        gateway->device_read_data[i].rxLen = rs;
      }
      else if (rs > 5)
      {
        memcpy(gateway->device_read_data[i].data, read_buf, 9);
        gateway->device_read_data[i].rxLen = rs;
      }
    }
    else
    {
      gateway->device_read_data[i].rxLen = 0;
    }
		task_fwdgt_reload();
		}
  
}

// 模块下载download校验值
static uint16_t checksum(const char *str, uint16_t len)
{
  uint16_t sum = 0;
  uint8_t odd = 0;

  // 如果字符串长度为奇数，则将最后一个字符设置为高8位，低8位设置为0
  if (len % 2 == 1)
  {
    odd = 1;
    len--;
  }

  // 将每两个字符作为一个16位的数值进行异或操作
  for (uint16_t i = 0; i < len; i += 2)
  {
    sum ^= ((uint16_t)str[i] << 8) | (uint16_t)str[i + 1];
  }

  // 如果字符串长度为奇数，则还需要将最后一个字符与0xFF00异或
  if (odd)
  {
    sum ^= (uint16_t)str[len] << 8;
  }
  // 返回校验和
  return sum;
}

