Tuoreniot.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. #include "stm32f10x.h"
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include "Tuoreniot.h"
  7. #include "mbedtls_util.h"
  8. #include "Log_Module.h"
  9. #include "At_Module.h"
  10. #include "Common_Util.h"
  11. #include "ec800m.h"
  12. #include "cJSON.h"
  13. #include "FlashSetup.h"
  14. #include "Timer_Module.h"
  15. #include "CoAP_Util.h"
  16. // 注册时用的密钥
  17. char regist_key[17]="tuorenzhinenghua";
  18. // 注册数据
  19. uint8_t regist_data[512];
  20. uint16_t regist_data_length;
  21. #if PROD_ENV
  22. // 生产环境
  23. char * REGIST_SERVER = "iot.tuoren.com" ; //注册服务器地址
  24. uint16_t REGIST_PORT = 8888; //端口号
  25. #endif
  26. #if TEST_ENV
  27. // 开发环境
  28. //char * REGIST_SERVER = "b21759p174.iok.la" ; //注册服务器地址
  29. //uint16_t REGIST_PORT = 43097; //端口号
  30. char * REGIST_SERVER = "frp-fun.top" ; //注册服务器地址
  31. uint16_t REGIST_PORT = 27827; //端口号
  32. #endif
  33. // 从flash中读取注册响应
  34. static void ReadRegistResponseFromFlash(void);
  35. // 将注册响应写入到flash中
  36. static void WriteRegistResponseToFlash(void);
  37. // 注册结果
  38. struct TUORENIOT_RegistResponseStruct regist_response = {
  39. .version = 1
  40. };
  41. // 初始化clientID
  42. static char ClientID[60];
  43. static void InitClientId(void)
  44. {
  45. // 设置clientid
  46. memset(ClientID, 0, sizeof(ClientID));
  47. strcat(ClientID, regist_response.productId);
  48. strcat(ClientID, "&");
  49. strcat(ClientID, regist_response.deviceId);
  50. }
  51. /**
  52. *
  53. *注册数据解密
  54. */
  55. uint8_t TUORENIOT_AnalysisRegistData(uint8_t * regist_data, uint16_t regist_data_length)
  56. {
  57. // Log_Printf_Debug("regist_data: \r\n");
  58. // Log_SendHex(regist_data, regist_data_length);
  59. // Log_Printf_Debug("\r\n");
  60. uint8_t result;
  61. utils_aes128_ECB_base64_dec(regist_key,regist_data,regist_data_length);
  62. Log_Printf_Debug("解密数据(%d):%s\r\n", regist_data_length, (char *)regist_data);
  63. cJSON *json = cJSON_Parse((char *)regist_data);
  64. if(!json)
  65. {
  66. Log_Printf_Debug("json parse error,%s\r\n",cJSON_GetErrorPtr());
  67. result = 0;
  68. }
  69. else if(cJSON_GetObjectItem(json, "code")->valueint == 200)
  70. {
  71. regist_response.code = cJSON_GetObjectItem(json, "code")->valueint;
  72. regist_response.version = cJSON_GetObjectItem(json, "version")->valueint;
  73. regist_response.userId = cJSON_GetObjectItem(json, "userId")->valueint;
  74. strcpy(regist_response.networkProtocol, cJSON_GetObjectItem(json, "networkProtocol")->valuestring);
  75. strcpy(regist_response.platform, cJSON_GetObjectItem(json, "platform")->valuestring);
  76. strcpy(regist_response.deviceSecret, cJSON_GetObjectItem(json, "deviceSecret")->valuestring);
  77. strcpy(regist_response.productId, cJSON_GetObjectItem(json, "productId")->valuestring);
  78. strcpy(regist_response.deviceId, cJSON_GetObjectItem(json, "deviceId")->valuestring);
  79. strcpy(regist_response.remoteAddress, cJSON_GetObjectItem(json, "remoteAddress")->valuestring);
  80. regist_response.remotePort = cJSON_GetObjectItem(json, "remotePort")->valueint;
  81. regist_response.wifiNumber = 3;
  82. // 解析wifi
  83. result = 1;
  84. WriteRegistResponseToFlash();
  85. }
  86. else
  87. {
  88. result = 0;
  89. }
  90. cJSON_Delete(json);
  91. return result;
  92. }
  93. static uint32_t SeqOffset = 0;
  94. static char Random[20];
  95. static char Token[50];
  96. // 判断是否认证
  97. uint8_t TUORENIOT_IsAuthentication(void)
  98. {
  99. if(strlen(Token) > 0) // 已认证
  100. {
  101. return 1;
  102. }
  103. else
  104. {
  105. return 0;
  106. }
  107. }
  108. // 拼接认证报文
  109. static char StrForSignature[100];
  110. static char sign[50];
  111. static uint8_t payload[256];
  112. void TUORENIOT_PackAuthMessage(uint8_t * coap_message, uint16_t * coap_message_length)
  113. {
  114. // Log_Printf_Debug("<<STEP: 拼接认证报文\r\n");
  115. // TUORENIOT_PrintfRegistResponseStruct();
  116. SeqOffset = 888;
  117. // 初始化clientId
  118. InitClientId();
  119. // CoAP协议
  120. CoAP_Init(coap_message);
  121. CoAP_Set_T(0);
  122. CoAP_Set_Code(2);
  123. CoAP_Set_MessageID(SeqOffset);
  124. // option
  125. // host
  126. CoAP_Set_Option_Str(3, regist_response.remoteAddress);
  127. // port
  128. CoAP_Set_Option_Short(7, regist_response.remotePort);
  129. // path
  130. CoAP_Set_Option_Str(11, "auth");
  131. // content-format
  132. CoAP_Set_Option_Short(12, 50);
  133. // accept
  134. CoAP_Set_Option_Short(17, 50);
  135. // 待签名数据
  136. // 签名相关
  137. memset(StrForSignature, 0, sizeof(StrForSignature));
  138. sprintf(StrForSignature, "clientId%sdeviceName%sproductKey%sseq%d", ClientID, regist_response.deviceId,regist_response.productId, SeqOffset);
  139. // Log_Printf_Debug("认证报文StrForSignature:\r\n%s\r\n", StrForSignature);
  140. // 签名
  141. memset(sign, 0, sizeof(sign));
  142. utils_hmac_sha1_str(StrForSignature, strlen((char * )StrForSignature), sign, regist_response.deviceSecret, strlen(regist_response.deviceSecret));
  143. // Log_Printf_Debug("签名sign:\r\n%s\r\n", sign);
  144. // payload
  145. memset(payload, 0, sizeof(payload));
  146. sprintf((char * )payload, "{\"clientId\":\"%s\",\"signmethod\":\"hmacsha1\",\"sign\":\"%s\",\"productKey\":\"%s\",\"deviceName\":\"%s\",\"seq\":\"%d\"}", ClientID, sign, regist_response.productId, regist_response.deviceId, SeqOffset);
  147. // 设置payload
  148. CoAP_Set_Payload_Str((char *)payload);
  149. // Log_Printf_Debug("payload:\r\n%s\r\n", payload);
  150. // 生成报文
  151. * coap_message_length = CoAP_Get_Length();
  152. // Log_Printf_Debug("STEP: 拼接认证报文>>\r\n");
  153. }
  154. // 拼接数据报文
  155. // aes cbc
  156. static uint8_t aes_key[16] = {0};
  157. static char iv[] = "543yhjy97ae7fyfg";
  158. static char out[80];
  159. static char sha256_source[100];
  160. static char Rand2089[10] = {'\0'};
  161. static uint8_t Opt2089[20];
  162. void TUORENIOT_PackDataMessage(uint8_t * data, uint8_t data_length, uint8_t * coap_message, uint16_t * coap_message_length)
  163. {
  164. // Log_Printf_Debug("<<STEP: 拼接数据报文\r\n");
  165. // 初始化clientId
  166. InitClientId();
  167. // Log_Printf_Debug("SeqOffset:%d\r\n", SeqOffset);
  168. // 获取密钥
  169. memset(sha256_source, 0, sizeof(sha256_source));
  170. snprintf(sha256_source, sizeof(sha256_source), "%s,%s" ,regist_response.deviceSecret ,Random);
  171. // Log_Printf_Debug("sha256_source:\r\n%s\r\n", sha256_source);
  172. memset(out, 0, sizeof(out));
  173. utils_sha256(sha256_source, strlen(sha256_source), out);
  174. // Log_Printf_Debug("out:\r\n");
  175. // Log_SendHex((uint8_t *)out, strlen(out));
  176. // Log_Printf_Debug("\r\n");
  177. memset(aes_key, 0, sizeof(aes_key));
  178. memcpy(aes_key, out+8, 16); //获取key
  179. // Log_Printf_Debug("aes_key:\r\n");
  180. // Log_SendHex(aes_key, 16);
  181. // Log_Printf_Debug("\r\n");
  182. // CoAP协议
  183. CoAP_Init(coap_message);
  184. CoAP_Set_T(0);
  185. CoAP_Set_Code(2);
  186. CoAP_Set_MessageID(++SeqOffset);
  187. // option
  188. // host
  189. CoAP_Set_Option_Str(3, regist_response.remoteAddress);
  190. // port
  191. CoAP_Set_Option_Short(7, regist_response.remotePort);
  192. // path
  193. CoAP_Set_Option_Str(11, "topic");
  194. CoAP_Set_Option_Str(11, "sys");
  195. CoAP_Set_Option_Str(11, regist_response.productId);
  196. CoAP_Set_Option_Str(11, regist_response.deviceId);
  197. CoAP_Set_Option_Str(11, "thing");
  198. CoAP_Set_Option_Str(11, "model");
  199. CoAP_Set_Option_Str(11, "up_raw");
  200. // content-format
  201. CoAP_Set_Option_Short(12, 50);
  202. // accept
  203. CoAP_Set_Option_Short(17, 50);
  204. // 2088
  205. CoAP_Set_Option_Str(2088, Token);
  206. // 2089
  207. memset(Rand2089, 0, sizeof(Rand2089));
  208. memset(Opt2089, 0, sizeof(Opt2089));
  209. my_itoa(SeqOffset, Rand2089, 10);
  210. int Opt2089_Length = utils_aes128_cbc_enc_with_length(aes_key, iv, (uint8_t *)Rand2089, strlen(Rand2089), Opt2089);
  211. CoAP_Set_Option(2089,Opt2089_Length, Opt2089);
  212. // Log_Printf_Debug("Opt2089:\r\n");
  213. // Log_SendHex(Opt2089, Opt2089_Length);
  214. // Log_Printf_Debug("\r\n");
  215. // Log_Printf_Debug("data:\r\n");
  216. // Log_SendHex(data, data_length);
  217. // Log_Printf_Debug("\r\n");
  218. // payload
  219. memset(payload, 0, sizeof(payload));
  220. int payload_length = utils_aes128_cbc_enc_with_length(aes_key, iv, data, data_length, payload);
  221. CoAP_Set_Payload(payload, payload_length);
  222. // Log_Printf_Debug("payload:\r\n");
  223. // Log_SendHex(payload, payload_length);
  224. // Log_Printf_Debug("\r\n");
  225. // 生成报文
  226. * coap_message_length = CoAP_Get_Length();
  227. // Log_Printf_Debug("STEP: 拼接数据报文>>\r\n");
  228. }
  229. // 设置Token
  230. static void set_token(char * token)
  231. {
  232. memset(Token, 0, sizeof(Token));
  233. strcpy(Token, token);
  234. }
  235. static void set_random(char * random)
  236. {
  237. memset(Random, 0, sizeof(Random));
  238. strcpy(Random, random);
  239. }
  240. static void set_seqOffset(uint32_t seqOffset)
  241. {
  242. SeqOffset = seqOffset;
  243. }
  244. // 接收数据处理
  245. static uint8_t plaintext[256]; // 明文
  246. uint8_t TUORENIOT_AnalysisMessage(uint8_t * coap_message, uint16_t coap_message_length)
  247. {
  248. // Log_Printf_Debug("coap_message(%d):\r\n", coap_message_length);
  249. // Log_SendHex(coap_message, coap_message_length);
  250. // Log_Printf_Debug("\r\n");
  251. memset(payload, 0, sizeof(payload));
  252. uint16_t payload_length = CoAP_Get_Payload(coap_message, coap_message_length, payload);
  253. Log_Printf_Debug("payload长度: %d\r\n", payload_length);
  254. // 判断是认证返回,还是数据发送返回
  255. if(payload_length == 0) // 无返回
  256. {
  257. // 清空Token,重新认证
  258. memset(Token, '\0', sizeof(Token));
  259. return 0;
  260. }
  261. else if(payload[0] == '{' && payload[payload_length-1] == '}') // 认证返回
  262. {
  263. // 解析json
  264. cJSON * cjson = cJSON_Parse((char * )payload);
  265. Log_Printf_Debug("plaintext(%d): %s\r\n",payload_length, payload);
  266. if(cJSON_HasObjectItem(cjson, "random"))
  267. {
  268. char * random = cJSON_GetObjectItem(cjson, "random")->valuestring;
  269. set_random(random);
  270. }
  271. if(cJSON_HasObjectItem(cjson, "seqOffset"))
  272. {
  273. uint16_t seqOffset = cJSON_GetObjectItem(cjson, "seqOffset")->valueint;
  274. set_seqOffset(seqOffset);
  275. }
  276. if(cJSON_HasObjectItem(cjson, "token"))
  277. {
  278. char * token = cJSON_GetObjectItem(cjson, "token")->valuestring;
  279. set_token(token);
  280. }
  281. cJSON_Delete(cjson);//清除结构体
  282. return 1;
  283. }
  284. else
  285. {
  286. // 数据发送成功返回
  287. memset(plaintext, 0, sizeof(plaintext));
  288. uint16_t plaintext_length = utils_aes128_cbc_dec(aes_key, iv, (char * )payload, payload_length, (char * )plaintext);
  289. Log_Printf_Debug("\r\nplaintext(%d): %s\r\n",plaintext_length, (char *)plaintext);
  290. return 2;
  291. }
  292. }
  293. void TUORENIOT_PrintfRegistRequestStruct(struct TUORENIOT_RegistRequestStruct * regist_params_struct)
  294. {
  295. Log_Printf("------print regist params start------\r\n");
  296. Log_Printf("version=%d\r\n", regist_params_struct->version);
  297. Log_Printf("networkType=%s\r\n", regist_params_struct->networkType);
  298. Log_Printf("networkProtocol=%s\r\n", regist_params_struct->networkProtocol);
  299. Log_Printf("deviceId=%s\r\n", regist_params_struct->deviceId);
  300. Log_Printf("platform=%s\r\n", regist_params_struct->platform);
  301. Log_Printf("userId=%d\r\n", regist_params_struct->userId);
  302. Log_Printf("------print regist params end------\r\n");
  303. }
  304. void TUORENIOT_PrintfRegistResponseStruct(void)
  305. {
  306. Log_Printf("------print regist result start------\r\n");
  307. Log_Printf("code=%d\r\n", regist_response.code);
  308. Log_Printf("version=%d\r\n", regist_response.version);
  309. Log_Printf("networkProtocol=%s\r\n", regist_response.networkProtocol);
  310. Log_Printf("platform=%s\r\n", regist_response.platform);
  311. Log_Printf("deviceId=%s\r\n", regist_response.deviceId);
  312. Log_Printf("deviceSecret=%s\r\n", regist_response.deviceSecret);
  313. Log_Printf("remoteAddress=%s\r\n", regist_response.remoteAddress);
  314. Log_Printf("remotePort=%d\r\n", regist_response.remotePort);
  315. Log_Printf("productId=%s\r\n", regist_response.productId);
  316. Log_Printf("userId=%d\r\n", regist_response.userId);
  317. Log_Printf("wifiNumber=%d\r\n", regist_response.wifiNumber);
  318. Log_Printf("------print regist result end------\r\n");
  319. }
  320. // 初始化
  321. void TUORENIOT_Init(void)
  322. {
  323. // 从flash中读取注册结果
  324. ReadRegistResponseFromFlash();
  325. }
  326. // 从flash中读取注册响应
  327. static void ReadRegistResponseFromFlash(void)
  328. {
  329. Log_Printf_Debug("sizeof(regist_response): %d\r\n", sizeof(regist_response));
  330. //读取flash
  331. Log_Printf_Debug("读取前code:%d\r\n", regist_response.code);
  332. Log_Printf_Debug("sizeof(regist_result): %d\r\n", sizeof(regist_response));
  333. FlashReadOperate((uint8_t*)&regist_response, sizeof(regist_response), FLASH_SAVE_ADDR);
  334. Log_Printf_Debug("读取后code:%d\r\n", regist_response.code);
  335. if(regist_response.code == 200)
  336. {
  337. TUORENIOT_PrintfRegistResponseStruct();
  338. }
  339. }
  340. // 将注册响应写入到flash中
  341. static void WriteRegistResponseToFlash(void)
  342. {
  343. FlashWriteOperate((uint8_t*)&regist_response, sizeof(regist_response), FLASH_SAVE_ADDR);
  344. regist_response.code = 0;
  345. Log_Printf_Debug("写入数据完成\r\n");
  346. FlashReadOperate((uint8_t*)&regist_response, sizeof(regist_response), FLASH_SAVE_ADDR);
  347. TUORENIOT_PrintfRegistResponseStruct();
  348. }
  349. // 获取code
  350. uint8_t TUORENIOT_GetCodeOfRegistResponse(void)
  351. {
  352. return regist_response.code;
  353. }