protocol.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include "protocol.h"
  2. #include "stdint.h"
  3. #include "gateway_message.h"
  4. #include "stdlib.h"
  5. #include "string.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 {protocol_dlt645_97=0x08,protocol_modbus,protocol_dlt645_07}PROTOCOL_LENGTH; //每个协议的数据包长度
  17. /*
  18. *********************************************************************************************************
  19. * 函 数 名: void masterSendNodeString(uint8_t nodeIndex)Index下标从0开始
  20. * 功能说明: 负责取出网关第nodeIndex下的数据组成下发格式的数据,注:此处没有对node是否为NULL进行判断,请确保有该节点的信息
  21. * 形 参:无
  22. * 返 回 值: 0:该节点下已经没有属性需要在去读出了,1:该节点下还拥有其他属性等待读出。
  23. 注:其一次性只能传输20条属性的值若超出其范围还有数据则要多次组成发送
  24. 逻辑:每次调用该函数都会总成一条string,属性足够的时候会组成一条具有20个属性的指令,并记录结束的设备链表位置,属性链表位置,下次再调用从结束位置再开始,到最后可能就组成不了20个属性的string了,此时将开始的设备num,属性都归位
  25. 且也要记录每次开始的设备位置和属性位置,方便接收应答信号的解析
  26. *********************************************************************************************************
  27. */
  28. int masterSendNodeString(uint8_t nodeIndex,uint8_t *string,uint16_t *size)
  29. {
  30. startDeviceNum=deviceNum; //起始位置等于上次结束的位置
  31. startParamsNum=paramsNum; //起始位置等于上次结束的位置
  32. int nowDeviceNum=deviceNum;
  33. int nowparamsNum=paramsNum;
  34. GATEWAY_PARAMS *gateway;
  35. gateway=get_gateway_config_params();
  36. //将当前的节点指针指到需要读取的节点位置
  37. NODE_PARAMS* currentNode = gateway->node_params;
  38. while(nodeIndex)
  39. {
  40. currentNode = currentNode->nextNode;
  41. nodeIndex--;
  42. }
  43. string=malloc(257);
  44. memset(string,0,257);
  45. //将首字符用nodeAdress
  46. string[0]=currentNode->node_address[0];
  47. string[1]=currentNode->node_address[1];
  48. //找到当前的设备结束位置
  49. DEVICE_PARAMS* currentDevice=currentNode->device_params;
  50. while(!nowDeviceNum)
  51. {
  52. currentDevice=currentDevice->nextDevice;
  53. nowDeviceNum--;
  54. }
  55. PARAMS_PROTOCOL_COMMAND* currentParams=currentDevice->params;
  56. //移动位置到结束位置属性的下一位
  57. while(!nowparamsNum)
  58. {
  59. currentParams=currentParams->nextParams;
  60. nowparamsNum--;
  61. }
  62. if(currentParams==NULL)
  63. {
  64. currentDevice=currentDevice->nextDevice;
  65. //判断当前还有没有设备没有读取了
  66. if(currentDevice==NULL) //且当前链表无后续设备了则跳出循环
  67. {
  68. deviceNum=0; //将结束位置全部归0
  69. paramsNum=0;
  70. return -1;
  71. }
  72. currentParams=currentDevice->params; //有则更新当前指针位置
  73. nowDeviceNum++;
  74. nowparamsNum=0;
  75. }
  76. //最多进行20次循环组成下发数据
  77. int i=0;
  78. int len=strlen((char *)&string);
  79. do
  80. {
  81. switch(currentDevice->protocol)
  82. {
  83. case MODBUS_READ:
  84. insertHexData(string,(uint8_t *)protocol_modbus,len,1); //插入modbus长度
  85. len++;
  86. insertHexData(string,(uint8_t *)MODBUS_READ,len,1); //插入modbus读指令
  87. len++;
  88. insertHexData(string,&currentParams->node_read_modbus_command->dataType,len,1); //插入读取的数据格式
  89. len++;
  90. insertHexData(string,&currentParams->node_read_modbus_command->slaveAddress,len,1); //插入modbus从站地址
  91. len++;
  92. insertHexData(string,(uint8_t *)&currentParams->node_read_modbus_command->registerAddress,len,2); //插入modbus寄存器地址
  93. len+=2;
  94. insertHexData(string,&currentParams->node_read_modbus_command->decimalPoint,len,1); //插入小数点位数
  95. len++;
  96. insertHexData(string,&currentParams->node_read_modbus_command->bigLittleFormat,len,1); //插入大小端
  97. len++;
  98. break;
  99. case MODBUS_WRITE:
  100. insertHexData(string,(uint8_t *)protocol_modbus,len,1); //插入modbus长度
  101. len++;
  102. insertHexData(string,(uint8_t *)MODBUS_WRITE,len,1); //插入modbus读指令
  103. len++;
  104. insertHexData(string,&currentParams->node_write_modbus_command->dataType,len,1); //插入读取的数据格式
  105. len++;
  106. insertHexData(string,&currentParams->node_write_modbus_command->slaveAddress,len,1); //插入modbus从站地址
  107. len++;
  108. insertHexData(string,(uint8_t *)&currentParams->node_write_modbus_command->registerAddress,len,2); //插入modbus寄存器地址
  109. len+=2;
  110. insertHexData(string,0x00,len,1); //插入小数点位数
  111. len++;
  112. insertHexData(string,&currentParams->node_write_modbus_command->bigLittleFormat,len,1); //插入大小端
  113. len++;
  114. break;
  115. case DLT645_07:
  116. insertHexData(string,(uint8_t *)protocol_dlt645_07,len,1); //插入dlt645_07数据长度
  117. len++;
  118. insertHexData(string,(uint8_t *)&currentParams->node_read_dlt645_command->deviceID645,len,6); //插入dlt645地址域
  119. len+=6;
  120. insertHexData(string,(uint8_t *)&currentParams->node_read_dlt645_command->functionCode,len,4);
  121. len+=4;
  122. break;
  123. case DLT645_97:
  124. insertHexData(string,(uint8_t *)protocol_dlt645_97,len,1); //插入dlt645_97数据长度
  125. len++;
  126. insertHexData(string,(uint8_t *)&currentParams->node_read_dlt645_command->deviceID645,len,6); //插入dlt645_97地址域
  127. len+=6;
  128. insertHexData(string,(uint8_t *)&currentParams->node_read_dlt645_command->functionCode,len,2); //插入dlt645_97数据标识
  129. len+=2;
  130. default:
  131. break;
  132. }
  133. i++;
  134. currentParams=currentParams->nextParams;
  135. //判断当前设备有没有属性可读了
  136. if(currentParams==NULL)
  137. {
  138. currentDevice=currentDevice->nextDevice;
  139. //判断当前还有没有设备没有读取了
  140. if(currentDevice==NULL) //且当前链表无后续设备了则跳出循环
  141. {
  142. deviceNum=0; //将结束位置全部归0
  143. paramsNum=0;
  144. break;
  145. }
  146. currentParams=currentDevice->params; //有则更新当前指针位置
  147. nowDeviceNum++;
  148. nowparamsNum=0;
  149. }
  150. nowparamsNum++;
  151. } while (i==20);
  152. //更新结束的位置分为两种情况,一种还在当前设备的属性中轮询此时nowDeviceNum没有改变过,另外一种情况设备内的属性
  153. if(nowDeviceNum==0)
  154. {
  155. deviceNum=startDeviceNum;
  156. paramsNum=startParamsNum+nowparamsNum;
  157. }
  158. else
  159. {
  160. deviceNum=startDeviceNum+nowDeviceNum;
  161. paramsNum=nowparamsNum;
  162. }
  163. *size=len;
  164. }
  165. /*
  166. *********************************************************************************************************
  167. * 函 数 名: void insertHexData(uint8_t *originalString,const uint8_t *hexData,int position)
  168. * 形 参:uint8_t *String需要插入的字符串,hexData插入的hex数据,insertIndex插入的下标位置,length插入的数据长度
  169. * 返 回 值: 无
  170. 注:插入的数据以被插入的字符串都可能包含0x00不要使用strlen
  171. *********************************************************************************************************
  172. */
  173. void insertHexData(uint8_t *String,const uint8_t *hexData,uint8_t insertIndex,uint8_t length)
  174. {
  175. memcpy(String+insertIndex,hexData,length);
  176. }
  177. /*
  178. *********************************************************************************************************
  179. * 函 数 名: uint8_t SlaveProtocolAnalysis(uint8_t *buff,uint16_t len)
  180. * 形 参:uint8_t *buff等待解析的字符串数据,
  181. * 返 回 值: 无
  182. 解析这段数据时要先判断是否为该节点的消息,如果是才进行数据解析工作
  183. *********************************************************************************************************
  184. */
  185. uint8_t SlaveProtocolAnalysis(uint8_t *buff,uint16_t len)
  186. {
  187. uint16_t NodeAdress=buff[0]<<8 || buff[1];
  188. }