device_message.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include "device_message.h"
  2. #include "gd32f10x.h"
  3. #include "string.h"
  4. int parseIntField(const char *data, const char *field);
  5. void parseStringField(const char *data, const char *field, char *value);
  6. void addDevice(char *deviceString);
  7. void addSensorListParams(char *paramString, DEVICE_PARAMS *device);
  8. void addCommandListParams(char *paramString, DEVICE_PARAMS *device);
  9. GATEWAY_PARAMS gateway_config_params = {0};
  10. GATEWAY_PARAMS *get_gateway_config_params()
  11. {
  12. return &gateway_config_params;
  13. }
  14. /***
  15. ***其主要分为了三层结构来做的最外层网关层,设备层,属性层
  16. ***其不用json解析,json消耗量太大,用关键字匹配去解析json数据用'}'和后一位']'去做结束判断依次从最内层往外层一层一层解析,解析完最内层的数据将'}'变为'A'防止外层去找结束符号时找到了内层
  17. ***/
  18. //解析网关最外层的相关信息
  19. int addGatewayParams(char *gatewayString)
  20. {
  21. parseStringField(gatewayString, "\"commandTopic\":\"", (char *)&gateway_config_params.commandTopic);
  22. parseStringField(gatewayString, "\"messageTopic\":\"", (char *)&gateway_config_params.messageTopic);
  23. parseStringField(gatewayString,"\"username\":\"",(char *)&gateway_config_params.mqttUserName);
  24. parseStringField(gatewayString,"\"password\":\"",(char *)&gateway_config_params.mqttPassword);
  25. parseStringField(gatewayString, "\"deviceId\":\"", (char *)&gateway_config_params.deviceId);
  26. parseStringField(gatewayString, "\"host\":\"", (char *)&gateway_config_params.host);
  27. gateway_config_params.port = parseIntField(gatewayString, "\"port\":");
  28. gateway_config_params.pollTime = parseIntField(gatewayString, "\"pollTime\":");
  29. gateway_config_params.baudrate=parseIntField(gatewayString, "\"baudrate\":");
  30. gateway_config_params.checkBit=parseIntField(gatewayString, "\"checkBit\":");
  31. gateway_config_params.dataBits=parseIntField(gatewayString, "\"dataBit\":");
  32. gateway_config_params.stopBit=parseIntField(gatewayString, "\"stopBit\":");
  33. gateway_config_params.inboundTime=parseIntField(gatewayString, "\"inboundTime\":");
  34. char *deviceString = strstr(gatewayString, "deviceList");//找到设备数组所处位置
  35. while (1)
  36. {
  37. addDevice(deviceString); // 往此节点下挂载设备信息
  38. deviceString=deviceString;//deviceString内容被内部数据改写了进行一次数据重加载
  39. deviceString = strstr(deviceString, "}"); // 移动到下一条属性
  40. deviceString[0]='A';
  41. deviceString++;
  42. if(deviceString[0]==']')
  43. {
  44. break;
  45. }
  46. }
  47. }
  48. void addGatewayParamsJson(char *gatewayString)
  49. {
  50. }
  51. //添加新的设备
  52. //应其为多层嵌套结构所以其找到最内部对象{}后将其值改写,这样可以避免外部的结构再去寻找
  53. void addDevice(char *deviceString)
  54. {
  55. char *paramString = (char *)deviceString; // 属性指针
  56. DEVICE_PARAMS *newDevicePage = (DEVICE_PARAMS *)malloc(sizeof(DEVICE_PARAMS));
  57. newDevicePage->nextDevice = NULL;
  58. parseStringField(deviceString, "\"deviceId\":\"", (char *)&newDevicePage->deviceID);
  59. newDevicePage->protocol = parseIntField(deviceString, "\"protocol\":");
  60. newDevicePage->params = (PARAMS_PROTOCOL_COMMAND *)malloc(sizeof(PARAMS_PROTOCOL_COMMAND));
  61. paramString = strstr(paramString, "\"sensorData\":["); // 找到该节点的轮询上发属性
  62. if(paramString!=NULL)
  63. {
  64. while(1)
  65. {
  66. addSensorListParams(paramString, newDevicePage); // 解析一个属性并挂载该属性于该属性下
  67. paramString = strstr(paramString, "}"); // 移动到下一条属性
  68. paramString[0]='A';
  69. paramString++;
  70. if (paramString[0] == ']')
  71. {
  72. paramString = (char *)deviceString;//找完了设备层内的属性,将指针指向设备层一开始的位置,防止json导致的sensorList和commandData乱序问题
  73. break;
  74. }
  75. }
  76. }
  77. if(newDevicePage->protocol==MODBUS) //如果为modbus的话解析写指令
  78. {
  79. paramString=deviceString; //移动到最开始的地方
  80. newDevicePage->MDBbigLittleFormat = parseIntField(paramString, "\"bigLittleFormat\":");
  81. newDevicePage->MDBdataType= parseIntField(paramString, "\"dataType\":");
  82. paramString = strstr(paramString, "\"commandData\":["); // 找到其轮询的写命令
  83. if(paramString!=NULL)//可能不存在commandData
  84. {
  85. while(1)
  86. {
  87. addCommandListParams(paramString, newDevicePage);
  88. paramString = strstr(paramString, "}");
  89. paramString[0]='A';
  90. paramString++;
  91. if (paramString[0] == ']')
  92. {
  93. paramString = (char *)deviceString;
  94. break;
  95. }
  96. }
  97. }
  98. }
  99. if(gateway_config_params.device_params==NULL)
  100. {
  101. gateway_config_params.device_params=newDevicePage;
  102. }else
  103. {
  104. DEVICE_PARAMS *current=gateway_config_params.device_params;
  105. while (current->nextDevice != NULL)
  106. {
  107. current = current->nextDevice;
  108. }
  109. current->nextDevice = newDevicePage;
  110. }
  111. }
  112. /**
  113. * @brief 解析输入字符串的paramString数据,将数据保存到至该设备结构体下,此处解析sensorList
  114. * @param uint8_t *paramString输入的字符串数据,DEVICE_PARAMS *device节点信息
  115. * @retval 无
  116. */
  117. void addSensorListParams(char *paramString, DEVICE_PARAMS *device)
  118. {
  119. switch (device->protocol)
  120. {
  121. case DLT645_97:
  122. case DLT645_07:
  123. {
  124. READ_DLT645_COMMAND *read_dlt645_command = malloc(sizeof(READ_DLT645_COMMAND));
  125. READ_MODBUS_COMMAND *read_modbus_command =NULL;
  126. read_dlt645_command->Identification = parseIntField(paramString, "\"identifier645\":");
  127. parseStringField(paramString, "\"identifier\":\"", (char *)&read_dlt645_command->keyword);
  128. char *string = malloc(13);
  129. parseStringField(paramString, "\"deviceID645\":\"", string);
  130. for (int j = 0; j < 6; j++)
  131. {
  132. uint8_t byte;
  133. sscanf((const char *)&string[j * 2], "%2hhx", &byte);
  134. read_dlt645_command->deviceID645[j]=byte;
  135. }
  136. free(string);
  137. if (device->params->node_read_dlt645_command == NULL)
  138. {
  139. device->params->node_read_dlt645_command = read_dlt645_command;
  140. }
  141. else
  142. {
  143. READ_DLT645_COMMAND *current = device->params->node_read_dlt645_command;
  144. while (current->nextParams != NULL)
  145. {
  146. current = current->nextParams;
  147. }
  148. current->nextParams = read_dlt645_command;
  149. }
  150. }
  151. break;
  152. case MODBUS:
  153. {
  154. READ_MODBUS_COMMAND *read_modbus_command = malloc(sizeof(READ_MODBUS_COMMAND));
  155. READ_DLT645_COMMAND *read_dlt645_command = NULL;
  156. parseStringField(paramString,"\"identifier\":\"",(char *)&read_modbus_command->keyword);
  157. read_modbus_command->decimalPoint = parseIntField(paramString, "\"precise\":");
  158. read_modbus_command->functionCode = parseIntField(paramString, "\"rFunctionCode\":");
  159. read_modbus_command->slaveAddress = parseIntField(paramString, "\"slaveAddress\":");
  160. read_modbus_command->registerAddress = parseIntField(paramString, "\"registerAddress\":");
  161. read_modbus_command->registerByteNum = parseIntField(paramString, "\"registerByteNum\":");
  162. if (device->params->node_read_modbus_command == NULL)
  163. {
  164. device->params->node_read_modbus_command = read_modbus_command;
  165. }
  166. else
  167. {
  168. READ_MODBUS_COMMAND *current = device->params->node_read_modbus_command;
  169. while (current->nextParams != NULL)
  170. {
  171. current = current->nextParams;
  172. }
  173. current->nextParams = read_modbus_command;
  174. }
  175. }
  176. break;
  177. default:
  178. break;
  179. }
  180. }
  181. void addCommandListParams(char *paramString, DEVICE_PARAMS *device)
  182. {
  183. WRITE_MODBUS_COMMAND *write_modbus_command=malloc(sizeof(WRITE_MODBUS_COMMAND));
  184. parseStringField(paramString,"\"identifier\":\"",(char *)&write_modbus_command->keyword);
  185. write_modbus_command->registerByteNum = parseIntField(paramString, "\"registerByteNum\":");
  186. write_modbus_command->functionCode=parseIntField(paramString, "\"wFunctionCode\":");
  187. write_modbus_command->slaveAddress=parseIntField(paramString, "\"slaveAddress\":");
  188. write_modbus_command->registerAddress = parseIntField(paramString, "\"registerAddress\":");
  189. if(device->params->node_write_modbus_command == NULL)
  190. {
  191. device->params->node_write_modbus_command=write_modbus_command;
  192. }
  193. else
  194. {
  195. WRITE_MODBUS_COMMAND *current=device->params->node_write_modbus_command;
  196. while (current->nextParams != NULL)
  197. {
  198. current = current->nextParams;
  199. }
  200. current->nextParams = write_modbus_command;
  201. }
  202. }
  203. // 提取int数据如果没有提取到数据则返回-1;提取到返回正确的值
  204. int parseIntField(const char *data, const char *field)
  205. {
  206. char *ptr = strstr(data, field) + strlen(field);
  207. int value;
  208. value = strtol(ptr, &ptr, 10);
  209. return value;
  210. }
  211. /*
  212. */
  213. // 提取string字符串
  214. void parseStringField(const char *data, const char *field, char *value)
  215. {
  216. if(strstr(data, field)==NULL)
  217. {
  218. value=NULL;
  219. }
  220. char *ptr = strstr(data, field) + strlen(field);
  221. sscanf(ptr, "%[^\"],", value);
  222. }