gateway_message.c 11 KB

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