tr_protocol.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * tr_protocol.c
  3. *
  4. * Created on: 2025年10月13日
  5. * Author: Administrator
  6. */
  7. #include <stdio.h>
  8. #include <stdint.h>
  9. #include <string.h>
  10. #include "tr_protocol.h"
  11. #include "tr_tools_util.h"
  12. static void insert(uint8_t* dest, uint16_t dest_start, uint8_t* source, uint16_t source_start, uint16_t len)
  13. {
  14. uint16_t i = 0;
  15. while (i < len)
  16. {
  17. dest[dest_start + i] = source[source_start + i];
  18. i++;
  19. }
  20. }
  21. // 拼包的方法
  22. void ProtocolInit(trProtocol* protocol) {
  23. protocol->version = 1;
  24. protocol->length = 8;
  25. protocol->currentOptinNumber = 0;
  26. protocol->optionsNum = 0;
  27. memset(protocol->message, 0, sizeof(protocol->message));
  28. protocol->message[0] = 'T';
  29. protocol->message[1] = 'R';
  30. protocol->message[2] = protocol->version;
  31. }
  32. // 设置目的地址
  33. void ProtocolSetDestAddress(trProtocol* protocol, uint8_t destAddress) {
  34. protocol->destAddress = destAddress;
  35. protocol->message[3] = destAddress;
  36. }
  37. // 设置源地址
  38. void ProtocolSetSourceAddress(trProtocol* protocol, uint8_t sourceAddress) {
  39. protocol->sourceAddress = sourceAddress;
  40. protocol->message[4] = sourceAddress;
  41. }
  42. // 设置类型
  43. void ProtocolSetType(trProtocol* protocol, uint8_t type) {
  44. protocol->type = type;
  45. protocol->message[5] = type;
  46. }
  47. // 设置option
  48. void ProtocolSetOption(trProtocol* protocol, uint16_t optionNumber, uint16_t optionLength, uint8_t* optionValue) {
  49. uint16_t pos_start = protocol->length, opt_length = 1;
  50. int delta = optionNumber - protocol->currentOptinNumber;
  51. if (delta < 0) {
  52. return;
  53. }
  54. else if (delta < 13) {
  55. protocol->message[pos_start] |= (delta & 0xFF) << 4;
  56. }
  57. else if (delta < 255 + 13) {
  58. protocol->message[pos_start] |= (0x0D & 0xFF) << 4;
  59. uint8_t ext = delta - 0x0D;
  60. protocol->message[pos_start + opt_length++] = ext;
  61. }
  62. else if (delta < 65535 + 255 + 14) {
  63. protocol->message[pos_start] |= (0x0E & 0xFF) << 4;
  64. uint16_t ext = (delta - 0x0E - 0xFF);
  65. protocol->message[pos_start + opt_length++] = (ext >> 8) & 0xFF;
  66. protocol->message[pos_start + opt_length++] = ext & 0xFF;
  67. }
  68. else {
  69. return;
  70. }
  71. // length
  72. if (optionLength < 1) {
  73. return;
  74. }
  75. else if (optionLength < 13) {
  76. protocol->message[pos_start] |= (optionLength & 0xFF);
  77. }
  78. else if (optionLength < 255 + 13) {
  79. protocol->message[pos_start] |= (0x0D & 0xFF);
  80. uint8_t ext = optionLength - 0x0D;
  81. protocol->message[pos_start + opt_length++] = ext;
  82. }
  83. else if (optionLength < 65535 + 255 + 14) {
  84. protocol->message[pos_start] |= (0x0E & 0xFF);
  85. uint16_t ext = (optionLength - 0x0E - 0xFF);
  86. protocol->message[pos_start + opt_length++] = (ext >> 8) & 0xFF;
  87. protocol->message[pos_start + opt_length++] = ext & 0xFF;
  88. }
  89. else {
  90. return;
  91. }
  92. insert(protocol->message, pos_start + opt_length, optionValue, 0, optionLength);
  93. opt_length += optionLength;
  94. protocol->length += opt_length;
  95. protocol->currentOptinNumber = optionNumber;
  96. }
  97. // 设置字符串类型的option
  98. void ProtocolSetOptionString(trProtocol* protocol, uint16_t optionNumber, char* optionValue) {
  99. uint16_t len = strlen(optionValue);
  100. ProtocolSetOption(protocol, optionNumber, len, (uint8_t*)optionValue);
  101. }
  102. // 设置short类型的option
  103. void ProtocolSetOptionShort(trProtocol* protocol, uint16_t optionNumber, uint16_t optionValue) {
  104. uint8_t value[2];
  105. value[0] = (optionValue >> 8) & 0xFF;
  106. value[1] = optionValue & 0xFF;
  107. ProtocolSetOption(protocol, optionNumber, sizeof(value), value);
  108. }
  109. // 设置char类型的option
  110. void ProtocolSetOptionChar(trProtocol* protocol, uint16_t optionNumber, uint8_t optionValue) {
  111. uint8_t value[1];
  112. value[0] = optionValue & 0xFF;
  113. ProtocolSetOption(protocol, optionNumber, sizeof(value), value);
  114. }
  115. // 设置payload
  116. void ProtocolSetPayload(trProtocol* protocol, uint16_t payloadLength, uint8_t* payload) {
  117. uint16_t pos = protocol->length;
  118. protocol->message[pos] = 0xFF;
  119. insert(protocol->message, pos + 1, payload, 0, payloadLength);
  120. protocol->length += payloadLength + 1;
  121. }
  122. // 设置字符串类型的payload
  123. void ProtocolSetPayloadString(trProtocol* protocol, const char* payloadString) {
  124. uint16_t len = strlen(payloadString);
  125. ProtocolSetPayload(protocol, len, (uint8_t*)payloadString);
  126. }
  127. // 打包
  128. void ProtocolPackage(trProtocol* protocol) {
  129. protocol->message[6] = (protocol->length + 2) >> 8 & 0xFF;
  130. protocol->message[7] = (protocol->length + 2) & 0xFF;
  131. uint16_t crc = CalCRC16(protocol->message, protocol->length);
  132. protocol->message[protocol->length++] = crc >> 8 & 0xFF;
  133. protocol->message[protocol->length++] = crc & 0xFF;
  134. }
  135. // 报文解析
  136. uint8_t ProtocolCheckCRC(uint8_t* message, uint16_t messageLength) {
  137. // uint16_t crc = CalCRC16(message, messageLength - 2);
  138. // if ((crc >> 8 & 0xFF) != message[messageLength - 2]) {
  139. // return 0;
  140. // }
  141. // if ((crc & 0xFF) != message[messageLength - 1]) {
  142. // return 0;
  143. // }
  144. return 1;
  145. }
  146. // 获取版本号
  147. uint8_t ProtocolGetVersion(uint8_t* message, uint16_t messageLength) {
  148. if (!ProtocolCheckCRC(message, messageLength)) {
  149. return 0;
  150. }
  151. return message[2];
  152. }
  153. // 获取报文类型
  154. uint8_t ProtocolGetType(uint8_t* message, uint16_t messageLength) {
  155. if (!ProtocolCheckCRC(message, messageLength)) {
  156. return 0;
  157. }
  158. return message[5];
  159. }
  160. // 获取目的地址
  161. uint8_t ProtocolGetDestAddress(uint8_t* message, uint16_t messageLength) {
  162. if (!ProtocolCheckCRC(message, messageLength)) {
  163. return 0;
  164. }
  165. return message[3];
  166. }
  167. // 获取源地址
  168. uint8_t ProtocolGetSourceAddress(uint8_t* message, uint16_t messageLength) {
  169. if (!ProtocolCheckCRC(message, messageLength)) {
  170. return 0;
  171. }
  172. return message[4];
  173. }
  174. // option结构体
  175. typedef struct
  176. {
  177. uint8_t valid; // 是否合法
  178. uint16_t number; // 编号
  179. uint16_t length; // 长度
  180. uint16_t pos; // 位置
  181. uint8_t delta_ext; // 编号扩展,字节
  182. uint8_t length_ext; // 长度扩展,字节
  183. }
  184. trOptionStruct;
  185. static trOptionStruct _GetOption(uint8_t* message, uint16_t pos, uint16_t number)
  186. {
  187. trOptionStruct option_struct = {1, number, message[pos] & 0x0F, pos, 0, 0};
  188. uint8_t delta = (message[pos] & 0xF0) >> 4;
  189. if (delta < 0x0D)
  190. {
  191. option_struct.delta_ext = 0;
  192. option_struct.number += delta;
  193. }
  194. else if (delta == 0x0D)
  195. {
  196. option_struct.delta_ext = 1;
  197. uint8_t num = message[pos + 1];
  198. option_struct.number += (0x0D + num);
  199. }
  200. else if (delta == 0x0E)
  201. {
  202. option_struct.delta_ext = 2;
  203. uint16_t num = 0;
  204. num = (num | message[pos + 1]) << 8;
  205. num = num | message[pos + 2];
  206. option_struct.number += (0x0E + 0xFF + num);
  207. }
  208. else
  209. {
  210. option_struct.valid = 0;
  211. return option_struct;
  212. }
  213. if (option_struct.length < 0x0D)
  214. {
  215. option_struct.length_ext = 0;
  216. }
  217. else if (option_struct.length == 0x0D)
  218. {
  219. option_struct.length_ext = 1;
  220. uint8_t num = message[pos + option_struct.delta_ext + 1];
  221. option_struct.length = (0x0D + num);
  222. }
  223. else if (option_struct.length == 0x0E)
  224. {
  225. option_struct.length_ext = 2;
  226. uint16_t num = 0;
  227. num = (num | message[pos + option_struct.delta_ext + 1]) << 8;
  228. num = num | message[pos + option_struct.delta_ext + 2];
  229. option_struct.length = (0x0E + 0xFF + num);
  230. }
  231. else
  232. {
  233. option_struct.valid = 0;
  234. return option_struct;
  235. }
  236. return option_struct;
  237. }
  238. // 获取option
  239. static trOptionStruct getOption(uint8_t* message, uint16_t messageLength, uint16_t number)
  240. {
  241. uint16_t pos = 8;
  242. uint16_t current_number = 0;
  243. trOptionStruct option_struct = {0};
  244. while (pos < messageLength)
  245. {
  246. option_struct = _GetOption(message, pos, current_number);
  247. if (option_struct.valid == 0 || option_struct.number == number)
  248. {
  249. break;
  250. }
  251. else
  252. {
  253. current_number = option_struct.number;
  254. pos = option_struct.pos + option_struct.delta_ext + option_struct.length_ext + option_struct.length + 1; // 下一个循环的位置起点
  255. }
  256. }
  257. return option_struct;
  258. }
  259. // 获取option和长度
  260. uint16_t ProtocolGetOption(uint8_t* message, uint16_t messageLength, uint16_t optionNumber, uint8_t* optionValue) {
  261. trOptionStruct option_struct = getOption(message, messageLength, optionNumber);
  262. if (option_struct.valid)
  263. {
  264. uint8_t i;
  265. for (i = 0; i < option_struct.length; i++)
  266. {
  267. optionValue[i] = message[option_struct.pos + option_struct.delta_ext + option_struct.length_ext + 1 + i];
  268. }
  269. return option_struct.length;
  270. }
  271. else
  272. {
  273. return 0;
  274. }
  275. }
  276. // 获取short类型的option
  277. uint8_t ProtocolGetOptionShort(uint8_t* message, uint16_t messageLength, uint16_t optionNumber, uint16_t * optionValue) {
  278. uint8_t value[8];
  279. uint16_t optionLength = ProtocolGetOption(message, messageLength, optionNumber, value);
  280. if (optionLength != 2) {
  281. return 0;
  282. }
  283. *optionValue = 0;
  284. *optionValue |= value[0] << 8;
  285. *optionValue |= value[1];
  286. return 1;
  287. }
  288. // 获取char类型的option
  289. uint8_t ProtocolGetOptionChar(uint8_t* message, uint16_t messageLength, uint16_t optionNumber, uint8_t* optionValue) {
  290. uint8_t value[8];
  291. uint16_t optionLength = ProtocolGetOption(message, messageLength, optionNumber, value);
  292. if (optionLength != 1) {
  293. return 0;
  294. }
  295. *optionValue = 0;
  296. *optionValue |= value[0];
  297. return 1;
  298. }
  299. typedef struct
  300. {
  301. uint8_t valid;
  302. uint16_t pos;
  303. uint16_t length;
  304. }
  305. trPayloadStruct;
  306. // 获取payload
  307. static trPayloadStruct Get_Payload(uint8_t* coap_message, uint16_t coap_length)
  308. {
  309. uint16_t pos = 8;
  310. uint16_t current_number = 0;
  311. trOptionStruct option_struct;
  312. trPayloadStruct payload_struct = {1, 0, 0};
  313. while (pos < coap_length)
  314. {
  315. if (coap_message[pos] == 0xFF)
  316. {
  317. payload_struct.valid = 1;
  318. payload_struct.pos = pos + 1;
  319. payload_struct.length = coap_length - pos - 1;
  320. break;
  321. }
  322. option_struct = _GetOption(coap_message, pos, current_number);
  323. if (option_struct.valid == 0)
  324. {
  325. payload_struct.valid = 0;
  326. payload_struct.length = 0;
  327. payload_struct.pos = 0;
  328. break;
  329. }
  330. else
  331. {
  332. current_number = option_struct.number;
  333. pos = option_struct.pos + option_struct.delta_ext + option_struct.length_ext + option_struct.length + 1; // 下一个循环的位置起点
  334. }
  335. }
  336. return payload_struct;
  337. }
  338. // 获取payload和长度
  339. uint16_t ProtocolGetPayload(uint8_t* message, uint16_t messageLength, uint8_t* payload) {
  340. if (!ProtocolCheckCRC(message, messageLength)) {
  341. return 0;
  342. }
  343. trPayloadStruct payload_struct = Get_Payload(message, messageLength - 2);
  344. if (payload_struct.valid)
  345. {
  346. uint8_t i;
  347. for (i = 0; i < payload_struct.length; i++)
  348. {
  349. payload[i] = message[payload_struct.pos + i];
  350. }
  351. return payload_struct.length;
  352. }
  353. else
  354. {
  355. return 0;
  356. }
  357. }