tr_protocol.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  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. // 设置payload
  110. void ProtocolSetPayload(trProtocol* protocol, uint16_t payloadLength, uint8_t* payload) {
  111. uint16_t pos = protocol->length;
  112. protocol->message[pos] = 0xFF;
  113. insert(protocol->message, pos + 1, payload, 0, payloadLength);
  114. protocol->length += payloadLength + 1;
  115. }
  116. // 设置字符串类型的payload
  117. void ProtocolSetPayloadString(trProtocol* protocol, const char* payloadString) {
  118. uint16_t len = strlen(payloadString);
  119. ProtocolSetPayload(protocol, len, (uint8_t*)payloadString);
  120. }
  121. // 打包
  122. void ProtocolPackage(trProtocol* protocol) {
  123. protocol->message[6] = protocol->length >> 8 & 0xFF;
  124. protocol->message[7] = protocol->length & 0xFF;
  125. uint16_t crc = CalCRC16(protocol->message, protocol->length);
  126. protocol->message[protocol->length++] = crc >> 8 & 0xFF;
  127. protocol->message[protocol->length++] = crc & 0xFF;
  128. }
  129. // 报文解析
  130. uint8_t ProtocolCheckCRC(uint8_t* message, uint16_t messageLength) {
  131. uint16_t crc = CalCRC16(message, messageLength - 2);
  132. if ((crc >> 8 & 0xFF) != message[messageLength - 2]) {
  133. return 0;
  134. }
  135. if ((crc & 0xFF) != message[messageLength - 1]) {
  136. return 0;
  137. }
  138. return 1;
  139. }
  140. // 获取版本号
  141. uint8_t ProtocolGetVersion(uint8_t* message, uint16_t messageLength) {
  142. if (!ProtocolCheckCRC(message, messageLength)) {
  143. return 0;
  144. }
  145. return message[2];
  146. }
  147. // 获取报文类型
  148. uint8_t ProtocolGetType(uint8_t* message, uint16_t messageLength) {
  149. if (!ProtocolCheckCRC(message, messageLength)) {
  150. return 0;
  151. }
  152. return message[5];
  153. }
  154. // 获取目的地址
  155. uint8_t ProtocolGetDestAddress(uint8_t* message, uint16_t messageLength) {
  156. if (!ProtocolCheckCRC(message, messageLength)) {
  157. return 0;
  158. }
  159. return message[3];
  160. }
  161. // 获取源地址
  162. uint8_t ProtocolGetSourceAddress(uint8_t* message, uint16_t messageLength) {
  163. if (!ProtocolCheckCRC(message, messageLength)) {
  164. return 0;
  165. }
  166. return message[4];
  167. }
  168. // option结构体
  169. typedef struct
  170. {
  171. uint8_t valid; // 是否合法
  172. uint16_t number; // 编号
  173. uint16_t length; // 长度
  174. uint16_t pos; // 位置
  175. uint8_t delta_ext; // 编号扩展,字节
  176. uint8_t length_ext; // 长度扩展,字节
  177. }
  178. trOptionStruct;
  179. static trOptionStruct _GetOption(uint8_t* message, uint16_t pos, uint16_t number)
  180. {
  181. trOptionStruct option_struct = {1, number, message[pos] & 0x0F, pos, 0, 0};
  182. uint8_t delta = (message[pos] & 0xF0) >> 4;
  183. if (delta < 0x0D)
  184. {
  185. option_struct.delta_ext = 0;
  186. option_struct.number += delta;
  187. }
  188. else if (delta == 0x0D)
  189. {
  190. option_struct.delta_ext = 1;
  191. uint8_t num = message[pos + 1];
  192. option_struct.number += (0x0D + num);
  193. }
  194. else if (delta == 0x0E)
  195. {
  196. option_struct.delta_ext = 2;
  197. uint16_t num = 0;
  198. num = (num | message[pos + 1]) << 8;
  199. num = num | message[pos + 2];
  200. option_struct.number += (0x0E + 0xFF + num);
  201. }
  202. else
  203. {
  204. option_struct.valid = 0;
  205. return option_struct;
  206. }
  207. if (option_struct.length < 0x0D)
  208. {
  209. option_struct.length_ext = 0;
  210. }
  211. else if (option_struct.length == 0x0D)
  212. {
  213. option_struct.length_ext = 1;
  214. uint8_t num = message[pos + option_struct.delta_ext + 1];
  215. option_struct.length = (0x0D + num);
  216. }
  217. else if (option_struct.length == 0x0E)
  218. {
  219. option_struct.length_ext = 2;
  220. uint16_t num = 0;
  221. num = (num | message[pos + option_struct.delta_ext + 1]) << 8;
  222. num = num | message[pos + option_struct.delta_ext + 2];
  223. option_struct.length = (0x0E + 0xFF + num);
  224. }
  225. else
  226. {
  227. option_struct.valid = 0;
  228. return option_struct;
  229. }
  230. return option_struct;
  231. }
  232. // 获取option
  233. static trOptionStruct getOption(uint8_t* message, uint16_t messageLength, uint16_t number)
  234. {
  235. uint16_t pos = 8;
  236. uint16_t current_number = 0;
  237. trOptionStruct option_struct = {0};
  238. while (pos < messageLength)
  239. {
  240. option_struct = _GetOption(message, pos, current_number);
  241. if (option_struct.valid == 0 || option_struct.number == number)
  242. {
  243. break;
  244. }
  245. else
  246. {
  247. current_number = option_struct.number;
  248. pos = option_struct.pos + option_struct.delta_ext + option_struct.length_ext + option_struct.length + 1; // 下一个循环的位置起点
  249. }
  250. }
  251. return option_struct;
  252. }
  253. // 获取option和长度
  254. uint16_t ProtocolGetOption(uint8_t* message, uint16_t messageLength, uint16_t optionNumber, uint8_t* optionValue) {
  255. trOptionStruct option_struct = getOption(message, messageLength, optionNumber);
  256. if (option_struct.valid)
  257. {
  258. uint8_t i;
  259. for (i = 0; i < option_struct.length; i++)
  260. {
  261. optionValue[i] = message[option_struct.pos + option_struct.delta_ext + option_struct.length_ext + 1 + i];
  262. }
  263. return option_struct.length;
  264. }
  265. else
  266. {
  267. return 0;
  268. }
  269. }
  270. // 获取option
  271. uint8_t ProtocolGetOptionShort(uint8_t* message, uint16_t messageLength, uint16_t optionNumber, uint16_t * optionValue) {
  272. uint8_t value[8];
  273. uint16_t optionLength = ProtocolGetOption(message, messageLength, optionNumber, value);
  274. if (optionLength != 2) {
  275. return 0;
  276. }
  277. *optionValue = 0;
  278. *optionValue |= value[0] << 8;
  279. *optionValue |= value[1];
  280. return 1;
  281. }
  282. typedef struct
  283. {
  284. uint8_t valid;
  285. uint16_t pos;
  286. uint16_t length;
  287. }
  288. trPayloadStruct;
  289. // 获取payload
  290. static trPayloadStruct Get_Payload(uint8_t* coap_message, uint16_t coap_length)
  291. {
  292. uint16_t pos = 8;
  293. uint16_t current_number = 0;
  294. trOptionStruct option_struct;
  295. trPayloadStruct payload_struct = {1, 0, 0};
  296. while (pos < coap_length)
  297. {
  298. if (coap_message[pos] == 0xFF)
  299. {
  300. payload_struct.valid = 1;
  301. payload_struct.pos = pos + 1;
  302. payload_struct.length = coap_length - pos - 1;
  303. break;
  304. }
  305. option_struct = _GetOption(coap_message, pos, current_number);
  306. if (option_struct.valid == 0)
  307. {
  308. payload_struct.valid = 0;
  309. payload_struct.length = 0;
  310. payload_struct.pos = 0;
  311. break;
  312. }
  313. else
  314. {
  315. current_number = option_struct.number;
  316. pos = option_struct.pos + option_struct.delta_ext + option_struct.length_ext + option_struct.length + 1; // 下一个循环的位置起点
  317. }
  318. }
  319. return payload_struct;
  320. }
  321. // 获取payload和长度
  322. uint16_t ProtocolGetPayload(uint8_t* message, uint16_t messageLength, uint8_t* payload) {
  323. if (!ProtocolCheckCRC(message, messageLength)) {
  324. return 0;
  325. }
  326. trPayloadStruct payload_struct = Get_Payload(message, messageLength - 2);
  327. if (payload_struct.valid)
  328. {
  329. uint8_t i;
  330. for (i = 0; i < payload_struct.length; i++)
  331. {
  332. payload[i] = message[payload_struct.pos + i];
  333. }
  334. return payload_struct.length;
  335. }
  336. else
  337. {
  338. return 0;
  339. }
  340. }