Tuoreniot.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  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. #include "esp32.h"
  17. // 泵号
  18. extern uint8_t mcu_id[8];
  19. // 注册时用的密钥
  20. char regist_key[17]="tuorenzhinenghua";
  21. // 注册数据
  22. uint8_t regist_data[1024];
  23. uint16_t regist_data_length;
  24. #if PROD_ENV
  25. // 生产环境
  26. char * REGIST_SERVER = "iot.tuoren.com" ; //注册服务器地址
  27. uint16_t REGIST_PORT = 8888; //端口号
  28. #endif
  29. #if TEST_ENV
  30. //char * REGIST_SERVER = "18017zi0ec26.vicp.fun" ; //注册服务器地址
  31. //uint16_t REGIST_PORT = 58562; //端口号
  32. char * REGIST_SERVER = "z18z017026.51vip.biz" ; //注册服务器地址
  33. uint16_t REGIST_PORT = 10029; //端口号
  34. #endif
  35. // 从flash中读取注册响应
  36. static void ReadRegistResponseFromFlash(void);
  37. // 将注册响应写入到flash中
  38. static void WriteRegistResponseToFlash(void);
  39. // 注册结果
  40. struct TUORENIOT_RegistResponseStruct regist_response = {
  41. .version = 1
  42. };
  43. // 初始化clientID
  44. static char ClientID[60];
  45. static void InitClientId(void)
  46. {
  47. // 设置clientid
  48. memset(ClientID, 0, sizeof(ClientID));
  49. strcat(ClientID, regist_response.productKey);
  50. strcat(ClientID, "&");
  51. strcat(ClientID, regist_response.deviceId);
  52. }
  53. /*************************************** 注册信息打包函数 ***************************************/
  54. void TUORENIOT_PackRegistRequest(uint8_t * pack_data, uint16_t * pack_data_length, struct TUORENIOT_RegistRequestStruct * registParams)
  55. {
  56. Log_Printf_Debug("mcu_id: %s\r\n", mcu_id);
  57. byteToHexStr(mcu_id, registParams->deviceId, sizeof(mcu_id));
  58. sprintf((char *)(pack_data + 2), "{\"version\":\"%d\",\"networkType\":\"%d\",\"networkProtocol\":\"%d\",\"productId\":\"%s\",\"deviceId\":\"%s\",\"userId\":\"%s\",\"sim\":\"%s\",\"netMac\":\"%s\"}",
  59. registParams->version, registParams->networkType, registParams->networkProtocol, registParams->productId, registParams->deviceId, registParams->userId, registParams->sim, registParams->netMac); // 拼接AT指令
  60. Log_Printf_Debug("%s\r\n", (char *)(pack_data + 2));
  61. uint16_t datalen = utils_aes128_ECB_base64_enc_with_length(regist_key, (pack_data + 2));
  62. pack_data[0] = datalen>>8;//头2个字节赋值数据长度
  63. pack_data[1] = datalen;
  64. * pack_data_length = datalen + 2;
  65. }
  66. /*************************************** 注册数据解密函数 ***************************************/
  67. static int wifi_count=0; //WiFi信息计数变量
  68. uint8_t TUORENIOT_AnalysisRegistData(uint8_t * regist_data, uint16_t regist_data_length)
  69. {
  70. Log_Printf_Debug("regist_data: \r\n");
  71. Log_SendHex(regist_data, regist_data_length);
  72. Log_Printf_Debug("\r\n");
  73. uint8_t result;
  74. utils_aes128_ECB_base64_dec(regist_key,regist_data,regist_data_length);
  75. Log_Printf_Debug("解密数据(%d):%s\r\n", regist_data_length, (char *)regist_data);
  76. cJSON *json = cJSON_Parse((char *)regist_data);
  77. if(!json)
  78. {
  79. Log_Printf_Debug("json parse error,%s\r\n",cJSON_GetErrorPtr());
  80. result = 0;
  81. }
  82. else if(cJSON_GetObjectItem(json, "code")->valueint == 200)
  83. {
  84. regist_response.code = cJSON_GetObjectItem(json, "code")->valueint;
  85. regist_response.version = cJSON_GetObjectItem(json, "version")->valueint;
  86. regist_response.platform = cJSON_GetObjectItem(json, "platform")->valueint;
  87. regist_response.networkType = cJSON_GetObjectItem(json, "networkType")->valueint;
  88. regist_response.networkProtocol = cJSON_GetObjectItem(json, "networkProtocol")->valueint;
  89. strcpy(regist_response.productId, cJSON_GetObjectItem(json, "productId")->valuestring);
  90. strcpy(regist_response.deviceId, cJSON_GetObjectItem(json, "deviceId")->valuestring);
  91. strcpy(regist_response.userId, cJSON_GetObjectItem(json, "userId")->valuestring);
  92. strcpy(regist_response.deviceSecret, cJSON_GetObjectItem(json, "deviceSecret")->valuestring);
  93. strcpy(regist_response.remoteAddress, cJSON_GetObjectItem(json, "remoteAddress")->valuestring);
  94. regist_response.remotePort = cJSON_GetObjectItem(json, "remotePort")->valueint;
  95. strcpy(regist_response.ipAddress, cJSON_GetObjectItem(json, "ipAddress")->valuestring);
  96. strcpy(regist_response.gateWay, cJSON_GetObjectItem(json, "gateWay")->valuestring);
  97. strcpy(regist_response.netMask, cJSON_GetObjectItem(json, "netMask")->valuestring);
  98. if(regist_response.platform == 1)
  99. {
  100. strcpy(regist_response.productKey, cJSON_GetObjectItem(json, "productKey")->valuestring);
  101. }
  102. else
  103. {
  104. strcpy(regist_response.productKey, regist_response.productId);
  105. }
  106. // 判断是否解析WiFi信息
  107. if(regist_response.networkType == 3)
  108. {
  109. Log_Printf_Debug("---------------------解析WiFi信息----------------------\r\n");
  110. cJSON *wifi_Array = cJSON_GetObjectItem(json, "wifi");
  111. regist_response.wifiNumber = cJSON_GetArraySize(wifi_Array);
  112. Log_Printf_Debug("wifiNumber=%d\r\n",regist_response.wifiNumber);
  113. if (cJSON_IsArray(wifi_Array))
  114. {
  115. cJSON *wifiElement = NULL;
  116. cJSON_ArrayForEach(wifiElement, wifi_Array)
  117. {
  118. // 提取wifiName
  119. cJSON *wifiName = cJSON_GetObjectItem(wifiElement, "wifiName");
  120. strcpy(regist_response.wifi[wifi_count].wifiName,wifiName->valuestring);
  121. // 提取wifiPassword
  122. cJSON *wifiPassword = cJSON_GetObjectItem(wifiElement, "wifiPassword");
  123. strcpy(regist_response.wifi[wifi_count].wifiPassword,wifiPassword->valuestring);
  124. //解析WiFi信息计数
  125. wifi_count++;
  126. }
  127. }
  128. //校验解析的WiFi信息数目是否正确
  129. if(wifi_count != regist_response.wifiNumber)
  130. {
  131. Log_Printf_Debug("wifi_count=%d\r\n",wifi_count);
  132. Log_Printf_Debug("解析wifi信息ERROR!!!\r\n");
  133. result = 0;
  134. cJSON_Delete(json);
  135. return result;
  136. }
  137. //打印解析的WiFi信息
  138. Log_Printf_Debug("解析出%d组wifi信息如下:\r\n",wifi_count);
  139. for(int i=0;i<wifi_count;i++)
  140. {
  141. Log_Printf_Debug("wifi[%d]->wifiName: %s\r\n", i,regist_response.wifi[i].wifiName);
  142. Log_Printf_Debug("wifi[%d]->wifiPassword: %s\r\n", i,regist_response.wifi[i].wifiPassword);
  143. }
  144. Log_Printf_Debug("-------------------------结束--------------------------\r\n");
  145. }
  146. result = 1;
  147. WriteRegistResponseToFlash();
  148. }
  149. else
  150. {
  151. result = 0;
  152. }
  153. cJSON_Delete(json);
  154. return result;
  155. }
  156. static uint32_t SeqOffset = 0;
  157. static char Random[20];
  158. static char Token[50];
  159. // 判断是否认证
  160. uint8_t TUORENIOT_IsAuthentication(void)
  161. {
  162. if(strlen(Token) > 0) // 已认证
  163. {
  164. return 1;
  165. }
  166. else
  167. {
  168. return 0;
  169. }
  170. }
  171. // 拼接认证报文
  172. static char StrForSignature[100];
  173. static char sign[50];
  174. static uint8_t payload[256];
  175. void TUORENIOT_PackAuthMessage(uint8_t * coap_message, uint16_t * coap_message_length)
  176. {
  177. // Log_Printf_Debug("<<STEP: 拼接认证报文\r\n");
  178. // TUORENIOT_PrintfRegistResponseStruct();
  179. SeqOffset = 888;
  180. // 初始化clientId
  181. InitClientId();
  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, "auth");
  194. // content-format
  195. CoAP_Set_Option_Short(12, 50);
  196. // accept
  197. CoAP_Set_Option_Short(17, 50);
  198. // 待签名数据
  199. // 签名相关
  200. memset(StrForSignature, 0, sizeof(StrForSignature));
  201. sprintf(StrForSignature, "clientId%sdeviceName%sproductKey%sseq%d", ClientID, regist_response.deviceId,regist_response.productId, SeqOffset);
  202. // Log_Printf_Debug("认证报文StrForSignature:\r\n%s\r\n", StrForSignature);
  203. // 签名
  204. memset(sign, 0, sizeof(sign));
  205. utils_hmac_sha1_str(StrForSignature, strlen((char * )StrForSignature), sign, regist_response.deviceSecret, strlen(regist_response.deviceSecret));
  206. // Log_Printf_Debug("签名sign:\r\n%s\r\n", sign);
  207. // payload
  208. memset(payload, 0, sizeof(payload));
  209. sprintf((char * )payload, "{\"clientId\":\"%s\",\"signmethod\":\"hmacsha1\",\"sign\":\"%s\",\"productKey\":\"%s\",\"deviceName\":\"%s\",\"seq\":\"%d\"}", ClientID, sign, regist_response.productId, regist_response.deviceId, SeqOffset);
  210. // 设置payload
  211. CoAP_Set_Payload_Str((char *)payload);
  212. Log_Printf_Debug("payload:\r\n%s\r\n", payload);
  213. // 生成报文
  214. * coap_message_length = CoAP_Get_Length();
  215. // Log_Printf_Debug("STEP: 拼接认证报文>>\r\n");
  216. }
  217. // 拼接数据报文
  218. // aes cbc
  219. static uint8_t aes_key[16] = {0};
  220. static char iv[] = "543yhjy97ae7fyfg";
  221. static char out[80];
  222. static char sha256_source[100];
  223. static char Rand2089[10] = {'\0'};
  224. static uint8_t Opt2089[20];
  225. void TUORENIOT_PackDataMessage(uint8_t * data, uint8_t data_length, uint8_t * coap_message, uint16_t * coap_message_length)
  226. {
  227. // Log_Printf_Debug("<<STEP: 拼接数据报文\r\n");
  228. // 初始化clientId
  229. InitClientId();
  230. // Log_Printf_Debug("SeqOffset:%d\r\n", SeqOffset);
  231. // 获取密钥
  232. memset(sha256_source, 0, sizeof(sha256_source));
  233. snprintf(sha256_source, sizeof(sha256_source), "%s,%s" ,regist_response.deviceSecret ,Random);
  234. // Log_Printf_Debug("sha256_source:\r\n%s\r\n", sha256_source);
  235. memset(out, 0, sizeof(out));
  236. utils_sha256(sha256_source, strlen(sha256_source), out);
  237. // Log_Printf_Debug("out:\r\n");
  238. // Log_SendHex((uint8_t *)out, strlen(out));
  239. // Log_Printf_Debug("\r\n");
  240. memset(aes_key, 0, sizeof(aes_key));
  241. memcpy(aes_key, out+8, 16); //获取key
  242. // Log_Printf_Debug("aes_key:\r\n");
  243. // Log_SendHex(aes_key, 16);
  244. // Log_Printf_Debug("\r\n");
  245. // CoAP协议
  246. CoAP_Init(coap_message);
  247. CoAP_Set_T(0);
  248. CoAP_Set_Code(2);
  249. CoAP_Set_MessageID(++SeqOffset);
  250. // option
  251. // host
  252. CoAP_Set_Option_Str(3, regist_response.remoteAddress);
  253. // port
  254. CoAP_Set_Option_Short(7, regist_response.remotePort);
  255. // path
  256. CoAP_Set_Option_Str(11, "topic");
  257. CoAP_Set_Option_Str(11, "sys");
  258. CoAP_Set_Option_Str(11, regist_response.productKey);
  259. CoAP_Set_Option_Str(11, regist_response.deviceId);
  260. CoAP_Set_Option_Str(11, "thing");
  261. CoAP_Set_Option_Str(11, "model");
  262. CoAP_Set_Option_Str(11, "up_raw");
  263. // content-format
  264. CoAP_Set_Option_Short(12, 50);
  265. // accept
  266. CoAP_Set_Option_Short(17, 50);
  267. // 2088
  268. CoAP_Set_Option_Str(2088, Token);
  269. // 2089
  270. memset(Rand2089, 0, sizeof(Rand2089));
  271. memset(Opt2089, 0, sizeof(Opt2089));
  272. my_itoa(SeqOffset, Rand2089, 10);
  273. int Opt2089_Length = utils_aes128_cbc_enc_with_length(aes_key, iv, (uint8_t *)Rand2089, strlen(Rand2089), Opt2089);
  274. CoAP_Set_Option(2089,Opt2089_Length, Opt2089);
  275. // Log_Printf_Debug("Opt2089:\r\n");
  276. // Log_SendHex(Opt2089, Opt2089_Length);
  277. // Log_Printf_Debug("\r\n");
  278. // Log_Printf_Debug("data:\r\n");
  279. // Log_SendHex(data, data_length);
  280. // Log_Printf_Debug("\r\n");
  281. // payload
  282. memset(payload, 0, sizeof(payload));
  283. int payload_length = utils_aes128_cbc_enc_with_length(aes_key, iv, data, data_length, payload);
  284. CoAP_Set_Payload(payload, payload_length);
  285. // Log_Printf_Debug("payload:\r\n");
  286. // Log_SendHex(payload, payload_length);
  287. // Log_Printf_Debug("\r\n");
  288. // 生成报文
  289. * coap_message_length = CoAP_Get_Length();
  290. // Log_Printf_Debug("STEP: 拼接数据报文>>\r\n");
  291. }
  292. // 设置Token
  293. static void set_token(char * token)
  294. {
  295. memset(Token, 0, sizeof(Token));
  296. strcpy(Token, token);
  297. }
  298. static void set_random(char * random)
  299. {
  300. memset(Random, 0, sizeof(Random));
  301. strcpy(Random, random);
  302. }
  303. static void set_seqOffset(uint32_t seqOffset)
  304. {
  305. SeqOffset = seqOffset;
  306. }
  307. // 接收数据处理
  308. static uint8_t plaintext[256]; // 明文
  309. uint8_t TUORENIOT_AnalysisMessage(uint8_t * coap_message, uint16_t coap_message_length)
  310. {
  311. // Log_Printf_Debug("coap_message(%d):\r\n", coap_message_length);
  312. // Log_SendHex(coap_message, coap_message_length);
  313. // Log_Printf_Debug("\r\n");
  314. memset(payload, 0, sizeof(payload));
  315. uint16_t payload_length = CoAP_Get_Payload(coap_message, coap_message_length, payload);
  316. Log_Printf_Debug("payload长度: %d\r\n", payload_length);
  317. // 判断是认证返回,还是数据发送返回
  318. if(payload_length == 0) // 无返回
  319. {
  320. // 清空Token,重新认证
  321. memset(Token, '\0', sizeof(Token));
  322. return 0;
  323. }
  324. else if(payload[0] == '{' && payload[payload_length-1] == '}') // 认证返回
  325. {
  326. // 解析json
  327. cJSON * cjson = cJSON_Parse((char * )payload);
  328. Log_Printf_Debug("plaintext(%d): %s\r\n",payload_length, payload);
  329. if(cJSON_HasObjectItem(cjson, "random"))
  330. {
  331. char * random = cJSON_GetObjectItem(cjson, "random")->valuestring;
  332. set_random(random);
  333. }
  334. if(cJSON_HasObjectItem(cjson, "seqOffset"))
  335. {
  336. uint16_t seqOffset = cJSON_GetObjectItem(cjson, "seqOffset")->valueint;
  337. set_seqOffset(seqOffset);
  338. }
  339. if(cJSON_HasObjectItem(cjson, "token"))
  340. {
  341. char * token = cJSON_GetObjectItem(cjson, "token")->valuestring;
  342. set_token(token);
  343. }
  344. cJSON_Delete(cjson);//清除结构体
  345. return 1;
  346. }
  347. else
  348. {
  349. // 数据发送成功返回
  350. memset(plaintext, 0, sizeof(plaintext));
  351. uint16_t plaintext_length = utils_aes128_cbc_dec(aes_key, iv, (char * )payload, payload_length, (char * )plaintext);
  352. Log_Printf_Debug("\r\nplaintext(%d): %s\r\n",plaintext_length, (char *)plaintext);
  353. return 2;
  354. }
  355. }
  356. void TUORENIOT_PrintfRegistRequestStruct(struct TUORENIOT_RegistRequestStruct * regist_params_struct)
  357. {
  358. Log_Printf("------print regist params start------\r\n");
  359. Log_Printf("version=%d\r\n", regist_params_struct->version);
  360. Log_Printf("networkType=%d\r\n", regist_params_struct->networkType);
  361. Log_Printf("networkProtocol=%d\r\n", regist_params_struct->networkProtocol);
  362. Log_Printf("productId=%s\r\n", regist_params_struct->productId);
  363. Log_Printf("deviceId=%s\r\n", regist_params_struct->deviceId);
  364. Log_Printf("userId=%s\r\n", regist_params_struct->userId);
  365. Log_Printf("sim=%s\r\n", regist_params_struct->sim);
  366. Log_Printf("netMac=%s\r\n", regist_params_struct->netMac);
  367. Log_Printf("------print regist params end------\r\n");
  368. }
  369. void TUORENIOT_PrintfRegistResponseStruct(void)
  370. {
  371. Log_Printf("------print regist result start------\r\n");
  372. Log_Printf("code=%d\r\n", regist_response.code);
  373. Log_Printf("version=%d\r\n", regist_response.version);
  374. Log_Printf("platform=%d\r\n", regist_response.platform);
  375. Log_Printf("networkType=%d\r\n", regist_response.networkType);
  376. Log_Printf("networkProtocol=%d\r\n", regist_response.networkProtocol);
  377. Log_Printf("productId=%s\r\n", regist_response.productId);
  378. Log_Printf("productKey=%s\r\n", regist_response.productKey);
  379. Log_Printf("deviceId=%s\r\n", regist_response.deviceId);
  380. Log_Printf("userId=%s\r\n", regist_response.userId);
  381. Log_Printf("deviceSecret=%s\r\n", regist_response.deviceSecret);
  382. Log_Printf("remoteAddress=%s\r\n", regist_response.remoteAddress);
  383. Log_Printf("remotePort=%d\r\n", regist_response.remotePort);
  384. Log_Printf("wifiNumber=%d\r\n", regist_response.wifiNumber);
  385. Log_Printf("ipAddress=%s\r\n", regist_response.ipAddress);
  386. Log_Printf("gateWay=%s\r\n", regist_response.gateWay);
  387. Log_Printf("netMask=%s\r\n", regist_response.netMask);
  388. Log_Printf("------print regist result end------\r\n");
  389. }
  390. // 初始化
  391. void TUORENIOT_Init(void)
  392. {
  393. // 从flash中读取注册结果
  394. ReadRegistResponseFromFlash();
  395. }
  396. // 清空flash中的注册响应
  397. void TUORENIOT_ClearRegistResponseFromFlash(void)
  398. {
  399. regist_response.code = 0;
  400. FlashWriteOperate((uint8_t*)&regist_response, sizeof(regist_response), FLASH_SAVE_ADDR);
  401. Log_Printf_Debug("清空注册数据完成\r\n");
  402. }
  403. // 从flash中读取注册响应
  404. static void ReadRegistResponseFromFlash(void)
  405. {
  406. Log_Printf_Debug("sizeof(regist_response): %d\r\n", sizeof(regist_response));
  407. //读取flash
  408. Log_Printf_Debug("读取前code:%d\r\n", regist_response.code);
  409. Log_Printf_Debug("sizeof(regist_result): %d\r\n", sizeof(regist_response));
  410. FlashReadOperate((uint8_t*)&regist_response, sizeof(regist_response), FLASH_SAVE_ADDR);
  411. Log_Printf_Debug("读取后code:%d\r\n", regist_response.code);
  412. if(regist_response.code == 200)
  413. {
  414. TUORENIOT_PrintfRegistResponseStruct();
  415. }
  416. }
  417. // 将注册响应写入到flash中
  418. static void WriteRegistResponseToFlash(void)
  419. {
  420. FlashWriteOperate((uint8_t*)&regist_response, sizeof(regist_response), FLASH_SAVE_ADDR);
  421. regist_response.code = 0;
  422. Log_Printf_Debug("写入数据完成\r\n");
  423. FlashReadOperate((uint8_t*)&regist_response, sizeof(regist_response), FLASH_SAVE_ADDR);
  424. TUORENIOT_PrintfRegistResponseStruct();
  425. }
  426. // 获取code
  427. uint8_t TUORENIOT_GetCodeOfRegistResponse(void)
  428. {
  429. return regist_response.code;
  430. }