#include "device_message.h" #include "gd32f10x.h" #include "string.h" int parseIntField(const char *data, const char *field); void parseStringField(const char *data, const char *field, char *value); void addDevice(char *deviceString); void addSensorListParams(char *paramString, DEVICE_PARAMS *device); void addCommandListParams(char *paramString, DEVICE_PARAMS *device); GATEWAY_PARAMS gateway_config_params = {0}; GATEWAY_PARAMS *get_gateway_config_params() { return &gateway_config_params; } /*** ***其主要分为了三层结构来做的最外层网关层,设备层,属性层 ***其不用json解析,json消耗量太大,用关键字匹配去解析json数据用'}'和后一位']'去做结束判断依次从最内层往外层一层一层解析,解析完最内层的数据将'}'变为'A'防止外层去找结束符号时找到了内层 ***/ //解析网关最外层的相关信息 int addGatewayParams(char *gatewayString) { parseStringField(gatewayString, "\"commandTopic\":\"", (char *)&gateway_config_params.commandTopic); parseStringField(gatewayString, "\"messageTopic\":\"", (char *)&gateway_config_params.messageTopic); parseStringField(gatewayString, "\"deviceId\":\"", (char *)&gateway_config_params.deviceId); parseStringField(gatewayString, "\"host\":\"", (char *)&gateway_config_params.host); gateway_config_params.port = parseIntField(gatewayString, "\"port\":"); gateway_config_params.pollTime = parseIntField(gatewayString, "\"pollTime\":"); gateway_config_params.baudrate=parseIntField(gatewayString, "\"baudrate\":"); gateway_config_params.checkBit=parseIntField(gatewayString, "\"checkBit\":"); gateway_config_params.dataBits=parseIntField(gatewayString, "\"dataBit\":"); gateway_config_params.stopBit=parseIntField(gatewayString, "\"stopBit\":"); gateway_config_params.inboundTime=parseIntField(gatewayString, "\"inboundTime\":"); char *deviceString = strstr(gatewayString, "deviceList");//找到设备数组所处位置 while (1) { addDevice(deviceString); // 往此节点下挂载设备信息 deviceString=deviceString;//deviceString内容被内部数据改写了进行一次数据重加载 deviceString = strstr(deviceString, "}"); // 移动到下一条属性 deviceString[0]='A'; deviceString++; if(deviceString[0]==']') { break; } } } void addGatewayParamsJson(char *gatewayString) { } //添加新的设备 //应其为多层嵌套结构所以其找到最内部对象{}后将其值改写,这样可以避免外部的结构再去寻找 void addDevice(char *deviceString) { char *paramString = (char *)deviceString; // 属性指针 DEVICE_PARAMS *newDevicePage = (DEVICE_PARAMS *)malloc(sizeof(DEVICE_PARAMS)); newDevicePage->nextDevice = NULL; parseStringField(deviceString, "\"deviceId\":\"", (char *)&newDevicePage->deviceID); newDevicePage->protocol = parseIntField(deviceString, "\"protocol\":"); newDevicePage->params = (PARAMS_PROTOCOL_COMMAND *)malloc(sizeof(PARAMS_PROTOCOL_COMMAND)); paramString = strstr(paramString, "\"sensorData\":["); // 找到该节点的轮询上发属性 if(paramString!=NULL) { while(1) { addSensorListParams(paramString, newDevicePage); // 解析一个属性并挂载该属性于该属性下 paramString = strstr(paramString, "}"); // 移动到下一条属性 paramString[0]='A'; paramString++; if (paramString[0] == ']') { paramString = (char *)deviceString;//找完了设备层内的属性,将指针指向设备层一开始的位置,防止json导致的sensorList和commandData乱序问题 break; } } } if(newDevicePage->protocol==MODBUS) //如果为modbus的话解析写指令 { paramString=deviceString; //移动到最开始的地方 newDevicePage->MDBbigLittleFormat = parseIntField(paramString, "\"bigLittleFormat\":"); newDevicePage->MDBdataType= parseIntField(paramString, "\"dataType\":"); paramString = strstr(paramString, "\"commandData\":["); // 找到其轮询的写命令 if(paramString!=NULL)//可能不存在commandData { while(1) { addCommandListParams(paramString, newDevicePage); paramString = strstr(paramString, "}"); paramString[0]='A'; paramString++; if (paramString[0] == ']') { paramString = (char *)deviceString; break; } } } } if(gateway_config_params.device_params==NULL) { gateway_config_params.device_params=newDevicePage; }else { DEVICE_PARAMS *current=gateway_config_params.device_params; while (current->nextDevice != NULL) { current = current->nextDevice; } current->nextDevice = newDevicePage; } } /** * @brief 解析输入字符串的paramString数据,将数据保存到至该设备结构体下,此处解析sensorList * @param uint8_t *paramString输入的字符串数据,DEVICE_PARAMS *device节点信息 * @retval 无 */ void addSensorListParams(char *paramString, DEVICE_PARAMS *device) { switch (device->protocol) { case DLT645_97: case DLT645_07: { READ_DLT645_COMMAND *read_dlt645_command = malloc(sizeof(READ_DLT645_COMMAND)); READ_MODBUS_COMMAND *read_modbus_command =NULL; read_dlt645_command->Identification = parseIntField(paramString, "\"identifier645\":"); parseStringField(paramString, "\"identifier\":\"", (char *)&read_dlt645_command->keyword); char *string = malloc(13); parseStringField(paramString, "\"deviceID645\":\"", string); for (int j = 0; j < 6; j++) { uint8_t byte; sscanf((const char *)&string[j * 2], "%2hhx", &byte); read_dlt645_command->deviceID645[j]=byte; } free(string); if (device->params->node_read_dlt645_command == NULL) { device->params->node_read_dlt645_command = read_dlt645_command; } else { READ_DLT645_COMMAND *current = device->params->node_read_dlt645_command; while (current->nextParams != NULL) { current = current->nextParams; } current->nextParams = read_dlt645_command; } } break; case MODBUS: { READ_MODBUS_COMMAND *read_modbus_command = malloc(sizeof(READ_MODBUS_COMMAND)); READ_DLT645_COMMAND *read_dlt645_command = NULL; parseStringField(paramString,"\"identifier\":\"",(char *)&read_modbus_command->keyword); read_modbus_command->decimalPoint = parseIntField(paramString, "\"precise\":"); read_modbus_command->functionCode = parseIntField(paramString, "\"rFunctionCode\":"); read_modbus_command->slaveAddress = parseIntField(paramString, "\"slaveAddress\":"); read_modbus_command->registerAddress = parseIntField(paramString, "\"registerAddress\":"); read_modbus_command->registerByteNum = parseIntField(paramString, "\"registerByteNum\":"); if (device->params->node_read_modbus_command == NULL) { device->params->node_read_modbus_command = read_modbus_command; } else { READ_MODBUS_COMMAND *current = device->params->node_read_modbus_command; while (current->nextParams != NULL) { current = current->nextParams; } current->nextParams = read_modbus_command; } } break; default: break; } } void addCommandListParams(char *paramString, DEVICE_PARAMS *device) { WRITE_MODBUS_COMMAND *write_modbus_command=malloc(sizeof(WRITE_MODBUS_COMMAND)); parseStringField(paramString,"\"identifier\":\"",(char *)&write_modbus_command->keyword); write_modbus_command->registerByteNum = parseIntField(paramString, "\"registerByteNum\":"); write_modbus_command->functionCode=parseIntField(paramString, "\"wFunctionCode\":"); write_modbus_command->slaveAddress=parseIntField(paramString, "\"slaveAddress\":"); write_modbus_command->registerAddress = parseIntField(paramString, "\"registerAddress\":"); if(device->params->node_write_modbus_command == NULL) { device->params->node_write_modbus_command=write_modbus_command; } else { WRITE_MODBUS_COMMAND *current=device->params->node_write_modbus_command; while (current->nextParams != NULL) { current = current->nextParams; } current->nextParams = write_modbus_command; } } // 提取int数据如果没有提取到数据则返回-1;提取到返回正确的值 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); }