gateway_message.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. #include "string.h"
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include "gateway_message.h"
  5. GATEWAY_PARAMS gateway_config_params = {0};
  6. GATEWAY_PARAMS *get_gateway_config_params()
  7. {
  8. return &gateway_config_params;
  9. }
  10. void parseStringField(const char *data, const char *field, char *value);
  11. int parseIntField(const char *data, const char *field);
  12. int extract_substring(const char *input_string, const char *start_token, const char *end_token, char *result);
  13. void addSensorListParams(char *paramString, DEVICE_PARAMS *device);
  14. void addCommandListParams(char *paramString, DEVICE_PARAMS *device);
  15. /**
  16. * @brief 解析输入字符串网关结构体信息,将数据保存
  17. * @param char *gatewayString 输入字符串的数据
  18. * @retval 无
  19. */
  20. void addGatewayParams(char *gatewayString)
  21. {
  22. //gateway_config_params.device_params = NULL;
  23. gateway_config_params.port = parseIntField(gatewayString, "\"port\":");
  24. gateway_config_params.stopBit = parseIntField(gatewayString, "\"stopBit\":");
  25. gateway_config_params.dataBits = parseIntField(gatewayString, "\"dataBit\":");
  26. gateway_config_params.baudrate = parseIntField(gatewayString, "\"baudrate\":");
  27. gateway_config_params.checkBit = parseIntField(gatewayString, "\"checkBit\":");
  28. gateway_config_params.inboundTime= parseIntField(gatewayString, "\"inboundTime\":");
  29. gateway_config_params.comProtocol= parseIntField(gatewayString, "\"comProtocol\":");
  30. parseStringField(gatewayString, "\"host\":\"", (char *)&gateway_config_params.host);
  31. parseStringField(gatewayString, "\"deviceId\":\"", (char *)&gateway_config_params.deviceId);
  32. parseStringField(gatewayString, "\"commandTopic\":\"", (char *)&gateway_config_params.commandTopic);
  33. parseStringField(gatewayString, "\"messageTopic\":\"", (char *)&gateway_config_params.messageTopic);
  34. parseStringField(gatewayString, "\"username\":\"", (char *)&gateway_config_params.username);
  35. parseStringField(gatewayString, "\"password\":\"", (char *)&gateway_config_params.passwd);
  36. char *deviceString = strstr(gatewayString,"deviceList"); //移位置到节点数据开始处
  37. while (1)
  38. {
  39. if (deviceString)
  40. {
  41. addDevice(deviceString); // 往此地址下挂载设备信息
  42. deviceString=deviceString;//重新获取设备字符串的位置
  43. deviceString = strstr(deviceString, "}");
  44. deviceString[0]='A';
  45. deviceString++;
  46. if(deviceString[0]==']')
  47. {
  48. break;
  49. }
  50. }
  51. else
  52. {
  53. return;
  54. }
  55. }
  56. }
  57. /**
  58. * @brief 解析输入字段的字符串,解析出属于该节点下的设备信息
  59. * @param uint8_t *string输入的字符串数据,NODE_PARAMS *node节点信息
  60. * @retval 无
  61. */
  62. void addDevice(char *deviceString)
  63. {
  64. char *paramString = (char *)deviceString; // 属性指针
  65. DEVICE_PARAMS *newDevicePage = (DEVICE_PARAMS *)mymalloc(SRAMEX, sizeof(DEVICE_PARAMS)); // 创建新设备页
  66. newDevicePage->nextDevice = NULL;
  67. newDevicePage->protocol = parseIntField(deviceString, "\"protocol\":");
  68. newDevicePage->MDBdataType = parseIntField(deviceString, "\"dataType\":");
  69. newDevicePage->MDBbigLittleFormat = parseIntField(deviceString, "\"bigLittleFormat\":");
  70. parseStringField(deviceString, "\"deviceId\":\"", (char *)&newDevicePage->deviceID);
  71. newDevicePage->params = (PARAMS_PROTOCOL_COMMAND *)mymalloc(SRAMEX,sizeof(PARAMS_PROTOCOL_COMMAND));
  72. memset(newDevicePage->params, 0, sizeof(PARAMS_PROTOCOL_COMMAND));
  73. paramString = strstr(paramString, "\"sensorData\":["); // 找到该节点的轮询上发属性
  74. while (1) // 此处数据是以数组形式存储所以解析方法和上面不一样
  75. {
  76. addSensorListParams(paramString, newDevicePage); // 解析一个属性并挂载该属性于该属性下
  77. paramString=paramString;
  78. paramString = strstr(paramString, "}"); // 移动到下一条属性
  79. paramString[0]='A';
  80. paramString++;
  81. if (paramString[0] == ']')
  82. {
  83. paramString = (char *)deviceString; // 复原指针位置
  84. break; // 找到了结束符,跳出循环
  85. }
  86. }
  87. if(newDevicePage->protocol==MODBUS) //如果为modbus的话解析写指令
  88. {
  89. paramString=deviceString; //移动到最开始的地方
  90. newDevicePage->MDBbigLittleFormat = parseIntField(paramString, "\"bigLittleFormat\":");
  91. newDevicePage->MDBdataType= parseIntField(paramString, "\"dataType\":");
  92. paramString = strstr(paramString, "\"commandData\":["); // 找到其轮询的写命令
  93. if(paramString!=NULL)
  94. {
  95. while(1)
  96. {
  97. addCommandListParams(paramString, newDevicePage);
  98. paramString = strstr(paramString, "}");
  99. paramString[0]='A';
  100. paramString++;
  101. if (paramString[0] == ']')
  102. {
  103. paramString = (char *)deviceString;// 复原指针位置
  104. break; // 找到了结束符,跳出循环
  105. }
  106. }
  107. }
  108. }
  109. // 解析下发的mqtt存储信息下发控制指令
  110. // 添加设备页到链表末尾
  111. if (gateway_config_params.device_params == NULL)
  112. {
  113. gateway_config_params.device_params = newDevicePage;
  114. }
  115. else
  116. {
  117. DEVICE_PARAMS *current = gateway_config_params.device_params;
  118. while (current->nextDevice != NULL)
  119. {
  120. current = current->nextDevice;
  121. }
  122. current->nextDevice = newDevicePage;
  123. }
  124. //解析modbus command指令将其加载到设备链表中
  125. }
  126. /**
  127. * @brief 解析输入字符串的paramString数据,将数据保存到至该设备结构体下,此处解析sensorList
  128. * @param uint8_t *paramString输入的字符串数据,DEVICE_PARAMS *device节点信息
  129. * @retval 无
  130. */
  131. void addSensorListParams(char *paramString, DEVICE_PARAMS *device)
  132. {
  133. switch (device->protocol)
  134. {
  135. case DLT645_97:
  136. case DLT645_07:
  137. {
  138. GATEWAY_READ_DLT645_COMMAND *read_dlt645_command = mymalloc(SRAMEX,sizeof(GATEWAY_READ_DLT645_COMMAND));
  139. read_dlt645_command->Identification = parseIntField(paramString, "\"identifier645\":");
  140. parseStringField(paramString, "\"identifier\":\"", (char *)&read_dlt645_command->keyword);
  141. char *string = mymalloc(SRAMEX,13);
  142. parseStringField(paramString, "\"deviceID645\":\"", string);
  143. for (int j = 0; j < 6; j++)
  144. {
  145. uint8_t byte;
  146. sscanf((const char *)&string[j * 2], "%2hhx", &byte);
  147. read_dlt645_command->deviceID645[j]=byte;
  148. }
  149. myfree(SRAMEX, string);
  150. string = NULL;
  151. if (device->params->gateway_read_dlt645_command == NULL)
  152. {
  153. device->params->gateway_read_dlt645_command = read_dlt645_command;
  154. }
  155. else
  156. {
  157. GATEWAY_READ_DLT645_COMMAND *current = device->params->gateway_read_dlt645_command;
  158. while (current->nextParams != NULL)
  159. {
  160. current = current->nextParams;
  161. }
  162. current->nextParams = read_dlt645_command;
  163. }
  164. }
  165. break;
  166. case MODBUS:
  167. {
  168. GATEWAY_READ_MODBUS_COMMAND *read_modbus_command = mymalloc(SRAMEX,sizeof(GATEWAY_READ_MODBUS_COMMAND));
  169. memset(read_modbus_command, 0, sizeof(GATEWAY_READ_MODBUS_COMMAND));
  170. parseStringField(paramString,"\"identifier\":\"",(char *)&read_modbus_command->keyword);
  171. read_modbus_command->decimalPoint = parseIntField(paramString, "\"precise\":");
  172. read_modbus_command->functionCode = parseIntField(paramString, "\"rFunctionCode\":");
  173. read_modbus_command->slaveAddress = parseIntField(paramString, "\"slaveAddress\":");
  174. read_modbus_command->registerAddress = parseIntField(paramString, "\"registerAddress\":");
  175. read_modbus_command->registerByteNum = parseIntField(paramString, "\"registerByteNum\":");
  176. if (device->params->gateway_read_modbus_command== NULL)
  177. {
  178. device->params->gateway_read_modbus_command = read_modbus_command;
  179. }
  180. else
  181. {
  182. GATEWAY_READ_MODBUS_COMMAND *current = device->params->gateway_read_modbus_command;
  183. while (current->nextParams != NULL)
  184. {
  185. current = current->nextParams;
  186. }
  187. current->nextParams = read_modbus_command;
  188. }
  189. }
  190. break;
  191. default:
  192. break;
  193. }
  194. }
  195. /**
  196. * @brief 解析输入字符串的paramString数据,将数据保存到至该设备结构体下,此处解析commandList
  197. * @param uint8_t *paramString输入的字符串数据,DEVICE_PARAMS *device节点信息
  198. * @retval 无
  199. */
  200. void addCommandListParams(char *paramString, DEVICE_PARAMS *device)
  201. {
  202. GATEWAY_WRITE_MODBUS_COMMAND *write_modbus_command=mymalloc(SRAMEX,sizeof(GATEWAY_WRITE_MODBUS_COMMAND));
  203. memset(write_modbus_command, 0, sizeof(GATEWAY_WRITE_MODBUS_COMMAND));
  204. parseStringField(paramString,"\"identifier\":\"",(char *)&write_modbus_command->keyword);
  205. write_modbus_command->functionCode=parseIntField(paramString, "\"wFunctionCode\":");
  206. write_modbus_command->slaveAddress=parseIntField(paramString, "\"slaveAddress\":");
  207. write_modbus_command->registerAddress = parseIntField(paramString, "\"registerAddress\":");
  208. write_modbus_command->registerByteNum = parseIntField(paramString, "\"registerByteNum\":");
  209. if(device->params->gateway_write_modbus_command == NULL)
  210. {
  211. device->params->gateway_write_modbus_command=write_modbus_command;
  212. }
  213. else
  214. {
  215. GATEWAY_WRITE_MODBUS_COMMAND *current=device->params->gateway_write_modbus_command;
  216. while (current->nextParams != NULL)
  217. {
  218. current = current->nextParams;
  219. }
  220. current->nextParams = write_modbus_command;
  221. }
  222. }
  223. // 提取int数据
  224. int parseIntField(const char *data, const char *field)
  225. {
  226. char *ptr = strstr(data, field) + strlen(field);
  227. int value;
  228. value = strtol(ptr, &ptr, 10);
  229. return value;
  230. }
  231. // 提取string字符串
  232. void parseStringField(const char *data, const char *field, char *value)
  233. {
  234. char *ptr = strstr(data, field) + strlen(field);
  235. sscanf(ptr, "%[^\"],", value);
  236. }
  237. // 不采用json解析硬解json数据
  238. void processStringJson(uint8_t *data)
  239. {
  240. GATEWAY_PARAMS *gateway;
  241. gateway = get_gateway_config_params();
  242. uint8_t *ptr = (uint8_t *)data;
  243. parseStringField((char *)&ptr, "\"messageTopic\":\"", (char *)&gateway->messageTopic);
  244. parseStringField((char *)&ptr, "\"commandTopic\":\"", (char *)&gateway->commandTopic);
  245. gateway->port = parseIntField((char *)&ptr, "\"port\":\"");
  246. parseStringField((char *)&ptr, "\"host\":\"", (char *)&gateway->host);
  247. parseStringField((char *)&ptr, "\"deviceId\":\"", (char *)&gateway->deviceId);
  248. // 解析最外层数据完成,申请空间存储节点信息
  249. int nodeNum = 1;
  250. char *node_index = mymalloc(SRAMEX,10);
  251. sprintf(node_index, "node_%d", nodeNum);
  252. strstr(ptr, node_index); // 将指针指向第一个节点
  253. while (*ptr == NULL)
  254. {
  255. }
  256. myfree(SRAMEX, node_index);
  257. }
  258. /**
  259. * @brief 从输入的input_string中寻找开始到结束位置的字符串数据,并将数据截取出来,传给result;
  260. * @param input_string输入字符串,start_token字符串起始位置,end_token字符串结束位置,result截取出的字符串
  261. * @retval 0:没有被截取到的字符串。1:有被截取到的字符串。
  262. */
  263. int extract_substring(const char *input_string, const char *start_token, const char *end_token, char *result)
  264. {
  265. const char *start_ptr = strstr(input_string, start_token);
  266. if (start_ptr == NULL)
  267. {
  268. return 0; // 未找到起始标记
  269. }
  270. start_ptr += strlen(start_token); // 移动指针到起始标记之后
  271. const char *end_ptr = strstr(start_ptr, end_token);
  272. if (end_ptr == NULL)
  273. {
  274. // 如果未找到结束标记,将从起始标记开始的字符串一直复制到 \0 结束
  275. strcpy(result, start_ptr);
  276. }
  277. else
  278. {
  279. // 找到结束标记,计算截取的长度并复制
  280. size_t length = end_ptr - start_ptr;
  281. strncpy(result, start_ptr, length);
  282. result[length] = '\0'; // 添加字符串结束符
  283. }
  284. return 1;
  285. }