protocol.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. #include "protocol.h"
  2. #include "stdint.h"
  3. #include "stdlib.h"
  4. #include "string.h"
  5. #include "node_message.h"
  6. /*****************************protocol主要为主网关与子节点通讯的协议使用**********************************/
  7. /*****************************其主要作用主网关给子节点轮询发送数据的编码**********************************/
  8. /*****************************子节点解析该主网关发送的数据 **********************************/
  9. /*****************************子节点回应对应的响应 **********************************/
  10. /*****************************子节点回应对应的响应的解析 **********************************/
  11. static volatile int deviceNum = 0; // 记录轮询读取设备的结束位置
  12. static volatile int paramsNum = 0; // 记录轮询读取属性的结束位置
  13. static volatile int startDeviceNum = 0; // 记录轮询读取设备的开始位置
  14. static volatile int startParamsNum = 0; // 记录轮询读取设备属性的开始位置
  15. void insertHexData(uint8_t *String, const uint8_t *hexData, uint8_t insertIndex, uint8_t length);
  16. enum
  17. {
  18. protocol_dlt645_97 = 0x08,
  19. protocol_modbus_read,
  20. protocol_dlt645_07
  21. } PROTOCOL_LENGTH; // 每个协议的数据包长度用于最开始区分不同协议
  22. // 枚举采集数据的存储个数
  23. enum
  24. {
  25. typeInt = 1,
  26. typeFloat,
  27. typeDouble
  28. } DATAType;
  29. // 枚举MODBUS协议具体功能
  30. enum
  31. {
  32. READ_COIL = 0x01,
  33. WRITE_COIL = 0x05,
  34. WRITE_COILS = 0x0F,
  35. READ_REGISTER = 0x03,
  36. WRITE_REFISTER = 0x06,
  37. WRITE_REGISTERS = 0x10
  38. } MODBUS_COMMAND;
  39. // 大小端
  40. typedef enum
  41. {
  42. MModBus_16bitOrder_AB = 1, // 大端
  43. MModBus_16bitOrder_BA,
  44. } MModBus_16bitOrder_t;
  45. /*
  46. *********************************************************************************************************
  47. * 函 数 名: void masterSendNodeString(uint8_t nodeIndex)Index下标从0开始
  48. * 功能说明: 负责取出网关第nodeIndex下的数据组成下发格式的数据,注:此处没有对node是否为NULL进行判断,请确保有该节点的信息
  49. * 形 参:nodeIndex第几个节点数据、string所总成的传递的字符串、size组成的字符串大小
  50. * 返 回 值: 0:该节点下已经没有属性需要在去读出了,1:该节点下还拥有其他属性等待读出。
  51. 注:其一次性只能传输20条属性的值若超出其范围还有数据则要多次组成发送
  52. 逻辑:每次调用该函数都会总成一条string,属性足够的时候会组成一条具有20个属性的指令,并记录结束的设备链表位置,属性链表位置,下次再调用从结束位置再开始,到最后可能就组成不了20个属性的string了,此时将开始的设备num,属性都归位
  53. 且也要记录每次开始的设备位置和属性位置,方便接收应答信号的解析
  54. *********************************************************************************************************
  55. */
  56. int masterSendNodeString(uint8_t nodeIndex, uint8_t *string, uint16_t *size)
  57. {
  58. startDeviceNum = deviceNum; // 起始位置等于上次结束的位置
  59. startParamsNum = paramsNum; // 起始位置等于上次结束的位置
  60. int nowDeviceNum = deviceNum;
  61. int nowparamsNum = paramsNum;
  62. GATEWAY_PARAMS *gateway;
  63. gateway = get_gateway_config_params();
  64. // 将当前的节点指针指到需要读取的节点位置
  65. NODE_PARAMS *currentNode = gateway->node_params;
  66. while (nodeIndex)
  67. {
  68. currentNode = currentNode->nextNode;
  69. nodeIndex--;
  70. }
  71. memset(string, 0, 256); // 清除上一次数据
  72. // 将首字符用nodeAdress
  73. string[0] = currentNode->node_address[0];
  74. string[1] = currentNode->node_address[1];
  75. // 找到当前的设备结束位置
  76. DEVICE_PARAMS *currentDevice = currentNode->device_params;
  77. while (nowDeviceNum)
  78. {
  79. currentDevice = currentDevice->nextDevice;
  80. nowDeviceNum--;
  81. }
  82. // 移动位置到结束位置属性的下一位
  83. NODE_READ_MODBUS_COMMAND *currentModbusParams = currentDevice->params->node_read_modbus_command;
  84. NODE_READ_DLT645_COMMAND *currentDlt645Params = currentDevice->params->node_read_dlt645_command;
  85. switch (currentDevice->protocol)
  86. {
  87. case MODBUS:
  88. while (nowparamsNum)
  89. {
  90. currentModbusParams = currentModbusParams->nextParams;
  91. nowparamsNum--;
  92. }
  93. break;
  94. case DLT645_07:
  95. case DLT645_97:
  96. while (nowparamsNum)
  97. {
  98. currentDlt645Params = currentDlt645Params->nextParams;
  99. nowparamsNum--;
  100. }
  101. break;
  102. default:
  103. break;
  104. }
  105. // 最多进行20次循环组成下发数据
  106. int i = 0;
  107. int len;
  108. len = strlen(string);
  109. do
  110. {
  111. switch (currentDevice->protocol)
  112. {
  113. case MODBUS_READ:
  114. {
  115. uint8_t protocolHexData = protocol_modbus_read;
  116. insertHexData(string, &protocolHexData, len, 1); // 插入modbus长度
  117. len++;
  118. insertHexData(string, &currentModbusParams->functionCode, len, 1); // 插入读取功能码
  119. len++;
  120. insertHexData(string, &currentModbusParams->dataType, len, 1); // 插入读取的数据格式
  121. len++;
  122. insertHexData(string, &currentModbusParams->slaveAddress, len, 1); // 插入modbus从站地址
  123. len++;
  124. insertHexData(string, (uint8_t *)&currentModbusParams->registerAddress, len, 2); // 插入modbus寄存器地址
  125. len += 2;
  126. insertHexData(string, &currentModbusParams->decimalPoint, len, 1); // 插入小数点位数
  127. len++;
  128. insertHexData(string, &currentModbusParams->bigLittleFormat, len, 1); // 插入大小端
  129. len++;
  130. // 属性读取完毕,移位到下一个属性
  131. i++;
  132. currentModbusParams = currentModbusParams->nextParams;
  133. if (currentModbusParams == NULL)
  134. {
  135. currentDevice = currentDevice->nextDevice;
  136. if (currentModbusParams == NULL)
  137. {
  138. deviceNum = 0; // 将结束位置全部归0
  139. paramsNum = 0;
  140. *size = len;
  141. return 1;
  142. }
  143. currentModbusParams = currentDevice->params->node_read_modbus_command;
  144. nowDeviceNum++;
  145. nowparamsNum = 0;
  146. }
  147. break;
  148. }
  149. case DLT645_07:
  150. {
  151. uint8_t protocolHexData = protocol_dlt645_07;
  152. insertHexData(string, &protocolHexData, len, 1); // 插入dlt645_07数据长度
  153. len++;
  154. insertHexData(string, (uint8_t *)&currentDlt645Params->deviceID645, len, 6); // 插入dlt645地址域
  155. len += 6;
  156. insertHexData(string, (uint8_t *)&currentDlt645Params->Identification, len, 4);
  157. len += 4;
  158. // 属性读取完毕,移位到下一个属性
  159. i++;
  160. currentDlt645Params = currentDlt645Params->nextParams;
  161. if (currentDlt645Params == NULL)
  162. {
  163. currentDevice = currentDevice->nextDevice;
  164. if (currentDevice == NULL)
  165. {
  166. deviceNum = 0; // 将结束位置全部归0
  167. paramsNum = 0;
  168. *size = len;
  169. return 1;
  170. }
  171. currentDlt645Params = currentDevice->params->node_read_dlt645_command;
  172. nowDeviceNum++;
  173. nowparamsNum = 0;
  174. }
  175. break;
  176. }
  177. case DLT645_97:
  178. {
  179. uint8_t protocolHexData = protocol_dlt645_97;
  180. insertHexData(string, &protocolHexData, len, 1); // 插入dlt645_97数据长度
  181. len++;
  182. insertHexData(string, (uint8_t *)&currentDlt645Params->deviceID645, len, 6); // 插入dlt645_97地址域
  183. len += 6;
  184. insertHexData(string, (uint8_t *)&currentDlt645Params->Identification, len, 2); // 插入dlt645_97数据标识
  185. len += 2;
  186. // 属性读取完毕,移位到下一个属性
  187. i++;
  188. currentDlt645Params = currentDlt645Params->nextParams;
  189. if (currentDlt645Params == NULL)
  190. {
  191. currentDevice = currentDevice->nextDevice;
  192. if (currentDlt645Params == NULL)
  193. {
  194. deviceNum = 0; // 将结束位置全部归0
  195. paramsNum = 0;
  196. *size = len;
  197. return 1;
  198. }
  199. currentDlt645Params = currentDevice->params->node_read_dlt645_command; // 还有属性则更新位置
  200. nowDeviceNum++;
  201. nowparamsNum = 0;
  202. }
  203. break;
  204. }
  205. default:
  206. goto end_while;
  207. }
  208. nowparamsNum++;
  209. } while (i != 20);
  210. end_while:
  211. // 更新结束的位置分为两种情况,一种还在当前设备的属性中轮询此时nowDeviceNum没有改变过,另外一种情况设备内的属性
  212. if (nowDeviceNum == 0)
  213. {
  214. deviceNum = startDeviceNum;
  215. paramsNum = startParamsNum + nowparamsNum;
  216. }
  217. else
  218. {
  219. deviceNum = startDeviceNum + nowDeviceNum;
  220. paramsNum = nowparamsNum - 1;
  221. }
  222. *size = len;
  223. return 0;
  224. }
  225. /*
  226. *********************************************************************************************************
  227. * 函 数 名: void insertHexData(uint8_t *originalString,const uint8_t *hexData,int position)
  228. * 形 参:uint8_t *String需要插入的字符串,hexData插入的hex数据,insertIndex插入的下标位置,length插入的数据长度
  229. * 返 回 值: 无
  230. 注:插入的数据以被插入的字符串都可能包含0x00不要使用strlen
  231. *********************************************************************************************************
  232. */
  233. void insertHexData(uint8_t *String, const uint8_t *hexData, uint8_t insertIndex, uint8_t length)
  234. {
  235. memcpy(String + insertIndex, hexData, length);
  236. }
  237. /*
  238. *********************************************************************************************************
  239. * 函 数 名: uint8_t SlaveProtocolAnalysis(uint8_t *buff,uint16_t len)
  240. * 形 参:uint8_t *buff等待解析的字符串数据,
  241. * 返 回 值: 0:不是该节点的消息,数据没有进行任何处理。1:为该节点信息,接收到要进行的相应的切换工作
  242. 解析这段数据时要先判断是否为该节点的消息,stuct B *p=malloc(sizeof(struct B);
  243. *********************************************************************************************************
  244. */
  245. #ifdef slave
  246. uint16_t LocalAddress=0x1F6E;
  247. uint8_t SlaveProtocolAnalysis(uint8_t *buff, uint16_t len)
  248. {
  249. NODE_DEVICE_PARAMS *node_receive_params;
  250. node_receive_params = get_node_receive_params();
  251. uint16_t slaveAdress = buff[0] << 8 | buff[1];
  252. int protocol_location = 2; // 起始的协议所处位置
  253. uint8_t i = 0;
  254. while (1)
  255. {
  256. if (slaveAdress == LocalAddress) // 判断此消息是否为该节点的消息,如果不是则跳出
  257. {
  258. node_receive_params = get_node_receive_params();
  259. switch (buff[protocol_location]) // 读取接收到的数据属于什么协议
  260. {
  261. case protocol_modbus_read:
  262. protocol_location++;
  263. node_receive_params->params[i].protcol = MODBUS_READ;
  264. node_receive_params->params[i].dlt645_params = NULL;
  265. free(node_receive_params->params[i].modbus_read);
  266. node_receive_params->params[i].modbus_read = malloc(sizeof(NODE_MODBUS_READ));
  267. node_receive_params->params[i].modbus_write = NULL;
  268. node_receive_params->params[i].modbus_read->functionCode = buff[protocol_location + 1]; // 读出functionCode
  269. node_receive_params->params[i].modbus_read->dataType = buff[protocol_location + 2]; // 读出数据格式
  270. node_receive_params->params[i].modbus_read->slaveAddress = buff[protocol_location + 3]; // 读出从站地址
  271. node_receive_params->params[i].modbus_read->registerAddress = buff[protocol_location + 5] << 8 || buff[protocol_location + 4]; // 读出寄存器地址
  272. node_receive_params->params[i].modbus_read->registerLength = buff[protocol_location + 7] << 8 || buff[protocol_location + 6]; // 读出要读的寄存器长度
  273. node_receive_params->params[i].modbus_read->precision = buff[protocol_location + 8]; // 读出小数点精度
  274. node_receive_params->params[i].modbus_read->bigLittleFormat = buff[protocol_location + 9]; // 读出数据大小端格式
  275. protocol_location += protocol_modbus_read;
  276. break;
  277. case protocol_dlt645_07:
  278. protocol_location++;
  279. node_receive_params->params[i].protcol = DLT645_07;
  280. free(node_receive_params->params[i].dlt645_params);
  281. node_receive_params->params[i].dlt645_params = malloc(sizeof(NODE_DLT645_PARAMS));
  282. node_receive_params->params[i].modbus_read = NULL;
  283. node_receive_params->params[i].modbus_write = NULL;
  284. memcpy(node_receive_params->params[i].dlt645_params->deviceType645, buff + protocol_location, 6);
  285. memcpy((uint8_t *)&node_receive_params->params[i].dlt645_params->dataType645, buff + protocol_location + 6, 4);
  286. protocol_location += protocol_dlt645_07;
  287. break;
  288. case protocol_dlt645_97:
  289. protocol_location++;
  290. node_receive_params->params[i].protcol = DLT645_97;
  291. free(node_receive_params->params[i].dlt645_params);
  292. node_receive_params->params[i].dlt645_params = malloc(sizeof(NODE_DLT645_PARAMS));
  293. node_receive_params->params[i].modbus_read = NULL;
  294. node_receive_params->params[i].modbus_write = NULL;
  295. memcpy(node_receive_params->params[i].dlt645_params->deviceType645, buff + protocol_location, 6);
  296. memcpy((uint8_t *)&node_receive_params->params[i].dlt645_params->dataType645, buff + protocol_location + 6, 2);
  297. protocol_location += protocol_dlt645_97;
  298. break;
  299. default: // 解析没满20个属性
  300. return 1;
  301. }
  302. }
  303. else
  304. {
  305. node_receive_params->Index = i; // 记录本次有多少数据传输过来了
  306. return 0;
  307. }
  308. i++;
  309. if (protocol_location > len) // 判断数据解析是否越界了,越界则跳转出
  310. {
  311. return 1;
  312. }
  313. }
  314. }
  315. /*
  316. *********************************************************************************************************
  317. * 函 数 名: nodeSendReadValue(uint8_t *string)
  318. * 形 参:组成node回传数据,传输数据为
  319. * 返 回 值: 无
  320. *********************************************************************************************************
  321. */
  322. void nodeSendReaddValue(uint8_t *string,uint16_t *size)
  323. {
  324. NODE_DEVICE_PARAMS *node_receive_params;
  325. node_receive_params = get_node_receive_params();
  326. int i = 0;
  327. int len=0;
  328. //先加载node的地址node地址暂时本地写死后续加载
  329. string[len]= LocalAddress>>8;
  330. string[len+1]=LocalAddress;
  331. len+=2;
  332. while (i != 20)
  333. {
  334. switch (node_receive_params->params[i].protcol)
  335. {
  336. case DLT645_07:
  337. case DLT645_97:
  338. if (node_receive_params->params[i].dlt645_params->rxLen <= 4)
  339. {
  340. string[len] = 0x04;
  341. len++;
  342. memcpy(&string[len], node_receive_params->params[i].dlt645_params->value, 4);
  343. len += 4;
  344. }
  345. else if (node_receive_params->params[i].dlt645_params->rxLen == 5)
  346. {
  347. string[len] = 0x05;
  348. len++;
  349. memcpy(&string[len], node_receive_params->params[i].dlt645_params->value, 5);
  350. len += 5;
  351. }
  352. else if (node_receive_params->params[i].dlt645_params->rxLen == 9)
  353. {
  354. string[len] = 0x09;
  355. len++;
  356. memcpy(&string[len], node_receive_params->params[i].dlt645_params->value, 9);
  357. len += 9;
  358. }
  359. else
  360. {
  361. string[len] = 0x00;
  362. len++;
  363. }
  364. break;
  365. case MODBUS:
  366. if (node_receive_params->params[i].modbus_read->rxLen == 4)
  367. {
  368. string[len] = 0x04;
  369. len++;
  370. memcpy(&string[len], node_receive_params->params[i].dlt645_params->value, 4);
  371. len += 4;
  372. }
  373. else
  374. {
  375. string[len] = 0x00;
  376. len++;
  377. }
  378. break;
  379. default:
  380. *size=len;
  381. return;
  382. }
  383. i++;
  384. }
  385. *size=len;
  386. }
  387. /*
  388. *********************************************************************************************************
  389. * 函 数 名: GatewayProtocolAnalysis(uint8_t *string)
  390. * 形 参:将节点应答信息依次解析为json数据
  391. * 返 回 值: 0未读到json数据,1读到了json数据
  392. *********************************************************************************************************
  393. */
  394. int GatewayProtocolAnalysis(uint8_t *string, uint16_t len)
  395. {
  396. char json[1024];
  397. sprintf(json, "{\"data\":[");
  398. // 读取上次循环最终停止位置
  399. int nowDeviceNum = startDeviceNum;
  400. int nowparamsNum = startParamsNum;
  401. GATEWAY_PARAMS *gateway;
  402. gateway = get_gateway_config_params();
  403. uint16_t nodeId = string[0] << 8 | string[1];
  404. // 将当前的节点指针指到需要读取的节点位置
  405. NODE_PARAMS *currentNode = gateway->node_params;
  406. uint16_t currentNodeId = currentNode->node_address[0] << 8 | currentNode->node_address[1];
  407. while (currentNodeId != nodeId)
  408. {
  409. currentNode = currentNode->nextNode;
  410. if (currentNode == NULL)
  411. {
  412. // 没有找到对应该节点信息不是给本机
  413. return 0;
  414. }
  415. currentNodeId = currentNode->node_address[0] << 8 | currentNode->node_address[1];
  416. }
  417. // 找到该节点进行轮询
  418. DEVICE_PARAMS *currentDevice = currentNode->device_params;
  419. while (nowDeviceNum)
  420. {
  421. currentDevice = currentDevice->nextDevice;
  422. nowDeviceNum--;
  423. }
  424. // 移动位置到开始属性
  425. NODE_READ_MODBUS_COMMAND *currentModbusParams = currentDevice->params->node_read_modbus_command;
  426. NODE_READ_DLT645_COMMAND *currentDlt645Params = currentDevice->params->node_read_dlt645_command;
  427. switch (currentDevice->protocol)
  428. {
  429. case MODBUS:
  430. while (nowparamsNum)
  431. {
  432. currentModbusParams = currentModbusParams->nextParams;
  433. nowparamsNum--;
  434. }
  435. break;
  436. case DLT645_07:
  437. case DLT645_97:
  438. while (nowparamsNum)
  439. {
  440. currentDlt645Params = currentDlt645Params->nextParams;
  441. nowparamsNum--;
  442. }
  443. break;
  444. default:
  445. break;
  446. }
  447. int index = 2; // 子节点地址
  448. while (index <len)
  449. {
  450. switch (currentDevice->protocol)
  451. {
  452. case MODBUS:
  453. // modbus协议
  454. switch (*(string + index))
  455. {
  456. case 0x00:
  457. // 没有数据
  458. index++;
  459. break;
  460. case 0x04:
  461. if (currentModbusParams->dataType == 0x01 && currentModbusParams->decimalPoint == 0x00) // modbus底层存储的数据类型 1INT 2float
  462. {
  463. uint32_t data;
  464. data = string[index + 1] + (string[index + 2] >> 8) + (string[index + 3] >> 16) + (string[index + 4] >> 24);
  465. sprintf(json + strlen(json), "{\"deviceId\":\"%s\",\"%s\":%d},", currentDevice->deviceID, currentModbusParams->keyword, data);
  466. }
  467. else // 如果是int且有小数点,或者底层就是float按照float来计算
  468. {
  469. float value;
  470. memcpy(&value,string+index+1,4);
  471. sprintf(json + strlen(json), "{\"deviceId\":\"%s\",\"%s\":%.2f},", currentDevice->deviceID,currentModbusParams->keyword,value);
  472. }
  473. index += 4;
  474. break;
  475. default:
  476. break;
  477. }
  478. currentModbusParams = currentModbusParams->nextParams;
  479. if (currentModbusParams == NULL)
  480. {
  481. currentDevice = currentDevice->nextDevice;
  482. if(currentDevice->protocol==MODBUS)
  483. {
  484. currentModbusParams=currentModbusParams->nextParams;
  485. }
  486. else
  487. {
  488. currentDlt645Params=currentDlt645Params->nextParams;
  489. }
  490. }
  491. break;
  492. case DLT645_07:
  493. case DLT645_97:
  494. switch (*(string + index))
  495. {
  496. case 0x00:
  497. index++;
  498. break;
  499. case 0x04:
  500. {
  501. index++;
  502. float value;
  503. memcpy(&value,string+index,sizeof(float));
  504. sprintf(json + strlen(json), "{\"deviceId\":\"%s\",\"%s\": %.2f},", currentDevice->deviceID, currentDlt645Params->keyword,value);
  505. index += 4;
  506. }
  507. break;
  508. case 0x05:
  509. {
  510. index++;
  511. //%02依次为年月日时分
  512. sprintf(json + strlen(json), "{\"deviceId\":\"%s\",\"%s\": \"%02X%02X%02X%02X%02X\"},",
  513. currentDevice->deviceID, currentDlt645Params->keyword, string[index + 4], string[index + 3], string[index + 2], string[index + 1], string[index]);
  514. index += 5;
  515. }
  516. break;
  517. case 9:
  518. {
  519. index++;
  520. float value;
  521. memcpy(&value, &string[index], 4);
  522. sprintf(json + strlen(json), "{\"deviceId\":\"%s\",\"%s\":\"%02X%02X%02X%02X%02X%.2f\"},",
  523. currentDevice->deviceID, currentDlt645Params->keyword, string[index + 8], string[index + 7], string[index + 6], string[index + 5], string[index + 4], value);
  524. index+=9;
  525. }
  526. break;
  527. default:
  528. break;
  529. }
  530. //移动到下个属性
  531. switch (currentDevice->protocol)
  532. {
  533. case DLT645_97:
  534. case DLT645_07:
  535. currentDlt645Params = currentDlt645Params->nextParams;
  536. if (currentDlt645Params == NULL)
  537. {
  538. currentDevice = currentDevice->nextDevice;
  539. currentDlt645Params=currentDevice->params->node_read_dlt645_command;
  540. }
  541. break;
  542. case MODBUS:
  543. currentModbusParams=currentModbusParams->nextParams;
  544. if(currentModbusParams==NULL)
  545. {
  546. currentDevice=currentDevice->nextDevice;
  547. currentDlt645Params=currentDevice->params->node_read_dlt645_command;
  548. }
  549. break;
  550. }
  551. break;
  552. default:
  553. break;
  554. }
  555. }
  556. if(strlen(string)<10)
  557. {
  558. return 0;
  559. }
  560. sprintf(json+strlen(json)-1,"]}");
  561. }
  562. #endif