#include "parseDeviceMessage.h" #include "cJson.h" #include "systick.h" #include "usart.h" #include "string.h" #include #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(const 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(char *dmaBuffer) { if (UART0_RX_STAT > 0) { UART0_RX_STAT = 0; uint32_t len; uint16_t checkCode; extract_data_from_buffer(dmaBuffer, &len, &checkCode); uint16_t jsonCheck = checksum(dmaBuffer, len); if (checkCode == jsonCheck) { processHttp(dmaBuffer); } } } /* * 函数名: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(const uint8_t *data) { CONFIG_PARAMS *gateway; gateway=get_config_params(); gateway->data_valid_flag = 0xF1; char* ptr = (char*)data; gateway->dataSource=parseIntField(ptr,"\"dataSource\":"); gateway->baudrate=parseIntField(ptr,"\"baudrate\":"); gateway->checkBit=parseIntField(ptr,"\"checkBit\":"); gateway->stopBit=parseIntField(ptr,"\"stopBit\":"); 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; } /* * 函数名: 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; }