Aliyuniot.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include "stm32f10x.h"
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include "Aliyuniot.h"
  7. #include "CoAP_Util.h"
  8. #include "mbedtls_util.h"
  9. #include "cJSON.h"
  10. #include "Log_Module.h"
  11. #include "Common_Util.h"
  12. /** 阿里云连接参数 **/
  13. static char ProductKey[20] = "k0g9w9xRhhi";
  14. static char DeviceName[20] = "3738393435363738";
  15. static char DeviceSecret[40] = "9b59c75bc0044b0de06f3a3355ce94ee";
  16. static char ClientID[60];
  17. static uint16_t Port = 5682;
  18. static char Host[60];
  19. static uint32_t SeqOffset = 65534;
  20. static char Random[20];
  21. static char Token[50];
  22. static void initClientIdAndHost(void);
  23. // 打印参数
  24. void aliyuniot_printf_params(void)
  25. {
  26. Log_Printf("------aliyun start------\r\n");
  27. Log_Printf("ProductKey=%s\r\n", ProductKey);
  28. Log_Printf("DeviceName=%s\r\n", DeviceName);
  29. Log_Printf("DeviceSecret=%s\r\n", DeviceSecret);
  30. Log_Printf("Token=%s\r\n", Token);
  31. Log_Printf("Random=%s\r\n", Random);
  32. Log_Printf("SeqOffset=%d\r\n", SeqOffset);
  33. Log_Printf("------aliyun end------\r\n");
  34. }
  35. // 获取host
  36. char * aliyuniot_get_host(void)
  37. {
  38. initClientIdAndHost();
  39. return Host;
  40. }
  41. // 获取port
  42. uint16_t aliyuniot_get_port(void)
  43. {
  44. return Port;
  45. }
  46. // 判断是否认证
  47. uint8_t aliyuniot_is_authentication(void)
  48. {
  49. if(strlen(Token) > 0) // 已认证
  50. {
  51. return 1;
  52. }
  53. else
  54. {
  55. return 0;
  56. }
  57. }
  58. // 设置阿里云连接参数
  59. void aliyuniot_set_device_params(char * prodect_key, char * device_name, char * device_secret)
  60. {
  61. memset(ProductKey, 0, sizeof(ProductKey));
  62. strcpy(ProductKey, prodect_key);
  63. memset(DeviceName, 0, sizeof(DeviceName));
  64. strcpy(DeviceName, device_name);
  65. memset(DeviceSecret, 0, sizeof(DeviceSecret));
  66. strcpy(DeviceSecret, device_secret);
  67. }
  68. // 设置Token
  69. static void set_token(char * token)
  70. {
  71. memset(Token, 0, sizeof(Token));
  72. strcpy(Token, token);
  73. }
  74. static void set_random(char * random)
  75. {
  76. memset(Random, 0, sizeof(Random));
  77. strcpy(Random, random);
  78. }
  79. static void set_seqOffset(uint32_t seqOffset)
  80. {
  81. SeqOffset = seqOffset;
  82. }
  83. void aliyuniot_set_device_token(char * token, char * random, uint32_t seqOffset)
  84. {
  85. set_token(token);
  86. set_random(random);
  87. set_seqOffset(seqOffset);
  88. }
  89. // 初始化Host和clientID
  90. static void initClientIdAndHost(void)
  91. {
  92. // 设置host
  93. memset(Host, 0, sizeof(Host));
  94. strcat(Host, ProductKey);
  95. strcat(Host, ".coap.cn-shanghai.link.aliyuncs.com");
  96. // 设置clientid
  97. memset(ClientID, 0, sizeof(ClientID));
  98. strcat(ClientID, ProductKey);
  99. strcat(ClientID, "&");
  100. strcat(ClientID, DeviceName);
  101. }
  102. // 拼接认证报文
  103. static char StrForSignature[100];
  104. static char sign[50];
  105. static uint8_t payload[256];
  106. void aliyuniot_get_auth_message(uint8_t * coap_message, uint16_t * coap_message_length)
  107. {
  108. // 先初始化clientID和Host
  109. initClientIdAndHost();
  110. // CoAP协议
  111. CoAP_Init(coap_message);
  112. CoAP_Set_T(0);
  113. CoAP_Set_Code(2);
  114. CoAP_Set_MessageID(SeqOffset);
  115. // option
  116. // host
  117. CoAP_Set_Option_Str(3, Host);
  118. // port
  119. CoAP_Set_Option_Short(7, Port);
  120. // path
  121. CoAP_Set_Option_Str(11, "auth");
  122. // content-format
  123. CoAP_Set_Option_Short(12, 50);
  124. // accept
  125. CoAP_Set_Option_Short(17, 50);
  126. // 待签名数据
  127. // 签名相关
  128. memset(StrForSignature, 0, sizeof(StrForSignature));
  129. sprintf(StrForSignature, "clientId%sdeviceName%sproductKey%sseq%d", ClientID, DeviceName, ProductKey, SeqOffset);
  130. // Log_Printf_Debug("认证报文StrForSignature:%s\r\n", StrForSignature);
  131. // 签名
  132. memset(sign, 0, sizeof(sign));
  133. utils_hmac_sha1_str(StrForSignature, strlen((char * )StrForSignature), sign, DeviceSecret, strlen(DeviceSecret));
  134. // payload
  135. memset(payload, 0, sizeof(payload));
  136. sprintf((char * )payload, "{\"clientId\":\"%s\",\"signmethod\":\"hmacsha1\",\"sign\":\"%s\",\"productKey\":\"%s\",\"deviceName\":\"%s\",\"seq\":\"%d\"}", ClientID, sign, ProductKey, DeviceName, SeqOffset);
  137. // 设置payload
  138. CoAP_Set_Payload_Str((char *)payload);
  139. // 生成报文
  140. * coap_message_length = CoAP_Get_Length();
  141. }
  142. // 拼接数据报文
  143. // aes cbc
  144. static uint8_t aes_key[16] = {0};
  145. static char iv[] = "543yhjy97ae7fyfg";
  146. static char out[80];
  147. static char sha256_source[100];
  148. static char Rand2089[10] = {'\0'};
  149. static uint8_t Opt2089[20];
  150. void aliyuniot_get_data_message(uint8_t * data, uint8_t data_length, uint8_t * coap_message, uint16_t * coap_message_length)
  151. {
  152. // aliyuniot_printf_params();
  153. // 先初始化clientID和Host
  154. initClientIdAndHost();
  155. SeqOffset++;
  156. // Log_Printf_Debug("STEP: 拼接数据报文,seqOffset=%d\r\n", SeqOffset);
  157. // 获取密钥
  158. memset(sha256_source, 0, sizeof(sha256_source));
  159. snprintf(sha256_source, sizeof(sha256_source), "%s,%s" ,DeviceSecret ,Random);
  160. memset(out, 0, sizeof(out));
  161. utils_sha256(sha256_source, strlen(sha256_source), out);
  162. memset(aes_key, 0, sizeof(aes_key));
  163. memcpy(aes_key, out+8, 16); //获取key
  164. // CoAP协议
  165. CoAP_Init(coap_message);
  166. CoAP_Set_T(0);
  167. CoAP_Set_Code(2);
  168. CoAP_Set_MessageID(SeqOffset);
  169. // option
  170. // host
  171. CoAP_Set_Option_Str(3, Host);
  172. // port
  173. CoAP_Set_Option_Short(7, Port);
  174. // path
  175. CoAP_Set_Option_Str(11, "topic");
  176. CoAP_Set_Option_Str(11, "sys");
  177. CoAP_Set_Option_Str(11, ProductKey);
  178. CoAP_Set_Option_Str(11, DeviceName);
  179. CoAP_Set_Option_Str(11, "thing");
  180. CoAP_Set_Option_Str(11, "model");
  181. CoAP_Set_Option_Str(11, "up_raw");
  182. // content-format
  183. CoAP_Set_Option_Short(12, 50);
  184. // accept
  185. CoAP_Set_Option_Short(17, 50);
  186. // 2088
  187. CoAP_Set_Option_Str(2088, Token);
  188. // 2089
  189. memset(Rand2089, 0, sizeof(Rand2089));
  190. memset(Opt2089, 0, sizeof(Opt2089));
  191. my_itoa(SeqOffset, Rand2089, 10);
  192. int Opt2089_Length = utils_aes128_cbc_enc_with_length(aes_key, iv, (uint8_t *)Rand2089, strlen(Rand2089), Opt2089);
  193. CoAP_Set_Option(2089,Opt2089_Length, Opt2089);
  194. // payload
  195. memset(payload, 0, sizeof(payload));
  196. int payload_length = utils_aes128_cbc_enc_with_length(aes_key, iv, data, data_length, payload);
  197. CoAP_Set_Payload(payload, payload_length);
  198. // 生成报文
  199. * coap_message_length = CoAP_Get_Length();
  200. }
  201. // 接收数据处理
  202. static uint8_t plaintext[256]; // 明文
  203. uint8_t aliyuniot_recv_data_handle(uint8_t * coap_message, uint16_t coap_message_length)
  204. {
  205. memset(payload, 0, sizeof(payload));
  206. uint16_t payload_length = CoAP_Get_Payload(coap_message, coap_message_length, payload);
  207. Log_Printf_Debug("payload长度: %d\r\n", payload_length);
  208. // 判断是认证返回,还是数据发送返回
  209. if(payload_length == 0) // 无返回
  210. {
  211. // 清空Token,重新认证
  212. memset(Token, '\0', sizeof(Token));
  213. return 0;
  214. }
  215. else if(payload[0] == '{' && payload[payload_length-1] == '}') // 认证返回
  216. {
  217. // 解析json
  218. cJSON * cjson = cJSON_Parse((char * )payload);
  219. // Log_Printf_Debug("plaintext(%d): %s\r\n",payload_length, payload);
  220. if(cJSON_HasObjectItem(cjson, "random"))
  221. {
  222. char * random = cJSON_GetObjectItem(cjson, "random")->valuestring;
  223. set_random(random);
  224. }
  225. if(cJSON_HasObjectItem(cjson, "seqOffset"))
  226. {
  227. uint16_t seqOffset = cJSON_GetObjectItem(cjson, "seqOffset")->valueint;
  228. set_seqOffset(seqOffset);
  229. }
  230. if(cJSON_HasObjectItem(cjson, "token"))
  231. {
  232. char * token = cJSON_GetObjectItem(cjson, "token")->valuestring;
  233. set_token(token);
  234. }
  235. cJSON_Delete(cjson);//清除结构体
  236. return 1;
  237. }
  238. else
  239. {
  240. // 数据发送成功返回
  241. memset(plaintext, 0, sizeof(plaintext));
  242. uint16_t plaintext_length = utils_aes128_cbc_dec(aes_key, iv, (char * )payload, payload_length, (char * )plaintext);
  243. Log_Printf_Debug("\r\nplaintext(%d): %s\r\n",plaintext_length, (char *)plaintext);
  244. return 2;
  245. }
  246. }