CoAP.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. #include "stm32f10x.h"
  2. #include <string.h>
  3. uint16_t CoAP_Length;
  4. uint16_t Current_Option_Number;
  5. uint8_t CoAP_Message[512];
  6. void Insert(uint8_t * dest, uint16_t dest_start, uint8_t * source, uint16_t source_start, uint16_t len)
  7. {
  8. uint16_t i = 0;
  9. while(i < len)
  10. {
  11. dest[dest_start + i] = source[source_start + i];
  12. i++;
  13. }
  14. }
  15. void insert(uint16_t start, uint8_t * source, uint16_t len)
  16. {
  17. Insert(CoAP_Message, start, source, 0, len);
  18. }
  19. uint8_t * CoAP_Get_Message()
  20. {
  21. return CoAP_Message;
  22. }
  23. uint16_t CoAP_Get_Length()
  24. {
  25. return CoAP_Length;
  26. }
  27. void CoAP_Init()
  28. {
  29. CoAP_Length = 4;
  30. Current_Option_Number = 0;
  31. memset(CoAP_Message, '\0', sizeof(CoAP_Message));
  32. CoAP_Message[0] |= 0x01 << 6; // 协议版本,固定为1
  33. }
  34. // 报文类型,00CON,01NON,10ACK,11Rest
  35. void CoAP_Set_T(uint8_t t)
  36. {
  37. CoAP_Message[0] |= t << 4;
  38. }
  39. // 请求类型
  40. void CoAP_Set_Code(uint8_t code)
  41. {
  42. CoAP_Message[1] = code;
  43. }
  44. // messageID
  45. void CoAP_Set_MessageID(uint16_t messageID)
  46. {
  47. uint8_t message_id[2];
  48. message_id[0] = (messageID >> 8) & 0xFF;
  49. message_id[1] = messageID & 0xFF;
  50. insert(2, message_id, sizeof(message_id));
  51. }
  52. // token len不能大于8
  53. void CoAP_Set_Token(uint8_t * token, uint8_t len)
  54. {
  55. if(len > 8)
  56. {
  57. len = 8;
  58. }
  59. CoAP_Message[0] |= len & 0xFF;
  60. insert(CoAP_Length, token, len);
  61. CoAP_Length += len;
  62. }
  63. // 设置option
  64. void CoAP_Set_Option(uint16_t number, uint16_t length, uint8_t * value)
  65. {
  66. uint16_t pos_start = CoAP_Length, opt_length = 1;
  67. int32_t delta = number - Current_Option_Number;
  68. if (delta < 0){
  69. return;
  70. } else if (delta < 13){
  71. CoAP_Message[pos_start] |= (delta & 0xFF) << 4;
  72. }else if (delta < 255+13){
  73. CoAP_Message[pos_start] |= (0x0D & 0xFF) << 4;
  74. uint8_t ext = delta - 0x0D;
  75. CoAP_Message[pos_start + opt_length++] = ext;
  76. }else if (delta < 65535){
  77. CoAP_Message[pos_start] |= (0x0E & 0xFF) << 4;
  78. uint16_t ext = (delta - 0x0E - 0xFF);
  79. CoAP_Message[pos_start + opt_length++] = (ext >> 8) & 0xFF;
  80. CoAP_Message[pos_start + opt_length++] = ext & 0xFF;
  81. }
  82. // length
  83. if (length < 1){
  84. return;
  85. }else if (length < 13){
  86. CoAP_Message[pos_start] |= (length & 0xFF);
  87. }else if (length < 255+13){
  88. CoAP_Message[pos_start] |= (0x0D & 0xFF);
  89. uint8_t ext = length - 0x0D;
  90. CoAP_Message[pos_start + opt_length++] = ext;
  91. }else if (length < 65535){
  92. CoAP_Message[pos_start] |= (0x0E & 0xFF);
  93. uint16_t ext = (length - 0x0E - 0xFF);
  94. CoAP_Message[pos_start + opt_length++] = (ext >> 8) & 0xFF;
  95. CoAP_Message[pos_start + opt_length++] = ext & 0xFF;
  96. }
  97. insert(pos_start + opt_length, value, length);
  98. opt_length += length;
  99. CoAP_Length += opt_length;
  100. Current_Option_Number = number;
  101. }
  102. // 设置字符串类型的option
  103. void CoAP_Set_Option_Str(uint16_t number, char * message)
  104. {
  105. uint16_t len = strlen(message);
  106. uint8_t value[len];
  107. for(uint16_t i = 0; i < len; i++)
  108. {
  109. value[i] = message[i];
  110. }
  111. CoAP_Set_Option(number, len, value);
  112. }
  113. // 设置short类型的option
  114. void CoAP_Set_Option_Short(uint16_t number, uint16_t num)
  115. {
  116. if(num < 256)
  117. {
  118. uint8_t value[1];
  119. value[0] = num;
  120. CoAP_Set_Option(number, sizeof(value), value);
  121. }
  122. else
  123. {
  124. uint8_t value[2];
  125. value[0] = (num >> 8) & 0xFF;
  126. value[1] = num & 0xFF;
  127. CoAP_Set_Option(number, sizeof(value), value);
  128. }
  129. }
  130. // 设置payload
  131. void CoAP_Set_Payload(uint8_t * payload, uint16_t length)
  132. {
  133. uint16_t pos = CoAP_Length;
  134. CoAP_Message[pos] = 0xFF;
  135. insert(pos + 1, payload, length);
  136. CoAP_Length += length + 1;
  137. }
  138. void CoAP_Set_Payload_Str(char * payload)
  139. {
  140. uint16_t len = strlen(payload);
  141. uint8_t value[len];
  142. for(uint16_t i = 0; i < len; i++)
  143. {
  144. value[i] = payload[i];
  145. }
  146. CoAP_Set_Payload(value, len);
  147. }
  148. // 报文解析
  149. // 获取版本号
  150. uint8_t CoAP_Get_Ver(uint8_t * coap_message)
  151. {
  152. uint8_t ver = (coap_message[0] & 0xC0) >> 6;
  153. return ver;
  154. }
  155. // 获取报文类型
  156. uint8_t CoAP_Get_T(uint8_t * coap_message)
  157. {
  158. uint8_t t = (coap_message[0] & 0x30) >> 4;
  159. return t;
  160. }
  161. // 获取tkl
  162. uint8_t CoAP_Get_Tkl(uint8_t * coap_message)
  163. {
  164. uint8_t tkl = coap_message[0] & 0x0F;
  165. return tkl;
  166. }
  167. // 获取请求方式
  168. uint8_t CoAP_Get_Code(uint8_t * coap_message)
  169. {
  170. uint8_t code = coap_message[1];
  171. return code;
  172. }
  173. // 获取messageID
  174. uint16_t CoAP_Get_MessageID(uint8_t * coap_message)
  175. {
  176. uint16_t messageID = 0;
  177. messageID = (messageID | coap_message[2]) << 8;
  178. messageID = messageID | coap_message[3];
  179. return messageID;
  180. }
  181. // 获取token
  182. uint8_t * CoAP_Get_Token(uint8_t * coap_message, uint8_t * token)
  183. {
  184. uint8_t tkl = CoAP_Get_Tkl(coap_message);
  185. for(uint8_t i = 0; i < tkl; i++)
  186. {
  187. token[i] = coap_message[4 + i];
  188. }
  189. return token;
  190. }
  191. struct Option_Struct
  192. {
  193. uint8_t valid; // 是否合法
  194. uint16_t number; // 编号
  195. uint16_t length; // 长度
  196. uint16_t pos; // 位置
  197. uint8_t delta_ext; // 编号扩展,字节
  198. uint8_t length_ext; // 长度扩展,字节
  199. };
  200. struct Option_Struct Get_Option(uint8_t * coap_message, uint16_t pos, uint16_t number)
  201. {
  202. struct Option_Struct option_struct = {
  203. .valid = 1,
  204. .number = number,
  205. .length = coap_message[pos] & 0x0F,
  206. .pos = pos,
  207. .delta_ext = 0,
  208. .length_ext = 0,
  209. };
  210. uint8_t delta = (coap_message[pos] & 0xF0) >> 4;
  211. if(delta < 0x0D)
  212. {
  213. option_struct.delta_ext = 0;
  214. option_struct.number += delta;
  215. }
  216. else if(delta == 0x0D)
  217. {
  218. option_struct.delta_ext = 1;
  219. uint8_t num = coap_message[pos + 1];
  220. option_struct.number += (0x0D + num);
  221. }
  222. else if(delta == 0x0E)
  223. {
  224. option_struct.delta_ext = 2;
  225. uint16_t num = 0;
  226. num = (num | coap_message[pos + 1]) << 8;
  227. num = num | coap_message[pos + 2];
  228. option_struct.number += (0x0E + 0xFF + num);
  229. }
  230. else
  231. {
  232. option_struct.valid = 0;
  233. return option_struct;
  234. }
  235. if(option_struct.length < 0x0D)
  236. {
  237. option_struct.length_ext = 0;
  238. }
  239. else if(option_struct.length == 0x0D)
  240. {
  241. option_struct.length_ext = 1;
  242. uint8_t num = coap_message[pos + option_struct.delta_ext + 1];
  243. option_struct.length = (0x0D + num);
  244. }
  245. else if(option_struct.length == 0x0E)
  246. {
  247. option_struct.length_ext = 2;
  248. uint16_t num = 0;
  249. num = (num | coap_message[pos + option_struct.delta_ext + 1]) << 8;
  250. num = num | coap_message[pos + option_struct.delta_ext + 2];
  251. option_struct.length = (0x0E + 0xFF + num);
  252. }
  253. else
  254. {
  255. option_struct.valid = 0;
  256. return option_struct;
  257. }
  258. return option_struct;
  259. }
  260. // 获取option长度
  261. struct Option_Struct CoAP_Get_Option(uint8_t * coap_message, uint16_t coap_length, uint16_t number)
  262. {
  263. uint8_t tkl = CoAP_Get_Tkl(coap_message);
  264. uint16_t pos = 4 + tkl;
  265. uint16_t current_number = 0;
  266. struct Option_Struct option_struct;
  267. while(pos < coap_length)
  268. {
  269. option_struct = Get_Option(coap_message, pos, current_number);
  270. if(option_struct.valid == 0 || option_struct.number == number)
  271. {
  272. break;
  273. }
  274. else
  275. {
  276. current_number = option_struct.number;
  277. pos = option_struct.pos + option_struct.delta_ext + option_struct.length_ext + option_struct.length + 1; // 下一个循环的位置起点
  278. }
  279. }
  280. return option_struct;
  281. }
  282. // 获取option长度
  283. uint16_t CoAP_Get_Option_Length(uint8_t * coap_message, uint16_t coap_length, uint16_t number)
  284. {
  285. uint16_t length = 0;
  286. struct Option_Struct option_struct = CoAP_Get_Option(coap_message, coap_length, number);
  287. if(option_struct.valid)
  288. {
  289. length = option_struct.length;
  290. }
  291. return length;
  292. }
  293. // 获取option value
  294. uint8_t * CoAP_Get_Option_Value(uint8_t * coap_message, uint16_t coap_length, uint16_t number, uint8_t * value)
  295. {
  296. struct Option_Struct option_struct = CoAP_Get_Option(coap_message, coap_length, number);
  297. if(option_struct.valid)
  298. {
  299. for(uint8_t i = 0; i < option_struct.length; i++)
  300. {
  301. value[i] = coap_message[option_struct.pos + option_struct.delta_ext + option_struct.length_ext + 1 + i];
  302. }
  303. }
  304. else
  305. {
  306. // value[0] = 0x99;
  307. }
  308. return value;
  309. }
  310. struct Payload_Struct
  311. {
  312. uint8_t valid;
  313. uint16_t pos;
  314. uint16_t length;
  315. };
  316. // 获取payload
  317. struct Payload_Struct Get_Payload(uint8_t * coap_message, uint16_t coap_length)
  318. {
  319. uint8_t tkl = CoAP_Get_Tkl(coap_message);
  320. uint16_t pos = 4 + tkl;
  321. uint16_t current_number = 0;
  322. struct Option_Struct option_struct;
  323. struct Payload_Struct payload_struct = {
  324. .valid = 1,
  325. .pos = 0,
  326. .length = 0
  327. };
  328. while(pos < coap_length)
  329. {
  330. if(coap_message[pos] == 0xFF)
  331. {
  332. payload_struct.valid = 1;
  333. payload_struct.pos = pos + 1;
  334. payload_struct.length = coap_length - pos - 1;
  335. break;
  336. }
  337. option_struct = Get_Option(coap_message, pos, current_number);
  338. if(option_struct.valid == 0)
  339. {
  340. payload_struct.valid = 0;
  341. payload_struct.length = 0;
  342. payload_struct.pos = 0;
  343. break;
  344. }
  345. else
  346. {
  347. current_number = option_struct.number;
  348. pos = option_struct.pos + option_struct.delta_ext + option_struct.length_ext + option_struct.length + 1; // 下一个循环的位置起点
  349. }
  350. }
  351. return payload_struct;
  352. }
  353. // 获取payload长度
  354. uint16_t CoAP_Get_Payload_Length(uint8_t * coap_message, uint16_t coap_length)
  355. {
  356. struct Payload_Struct payload_struct = Get_Payload(coap_message, coap_length);
  357. return payload_struct.length;
  358. }
  359. // 获取payload值
  360. uint8_t * CoAP_Get_Payload(uint8_t * coap_message, uint16_t coap_length, uint8_t * payload)
  361. {
  362. struct Payload_Struct payload_struct = Get_Payload(coap_message, coap_length);
  363. if(payload_struct.valid)
  364. {
  365. for(uint8_t i = 0; i < payload_struct.length; i++)
  366. {
  367. payload[i] = coap_message[payload_struct.pos + i];
  368. }
  369. }
  370. else
  371. {
  372. }
  373. return payload;
  374. }