Ec800m_Regist.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. #include "CONFIG.h"
  2. #if EC800M
  3. #include "stm32f10x.h"
  4. #include "Regist.h"
  5. #include "FlashSetup.h"
  6. #include <stdio.h>
  7. #include <stdarg.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include "cJSON.h"
  11. #include "mbedtls_util.h"
  12. #include "Log_Module.h"
  13. #include "At_Module.h"
  14. #include "Common_Util.h"
  15. #include "Tuoreniot.h"
  16. #include "ec800m.h"
  17. // 泵号
  18. extern uint8_t mcu_id[8];
  19. // socket ID
  20. static uint8_t connectID = 2;
  21. // 注册参数
  22. static struct TUORENIOT_RegistRequestStruct regist_request = {
  23. .version = 1,
  24. .platform = "aliyun",
  25. .networkProtocol = "CoAP",
  26. .deviceId = "3431228A1936013C",
  27. .userId = 4562
  28. };
  29. /**
  30. *
  31. *注册参数信息打包
  32. */
  33. void TUORENIOT_PackRegistRequest(uint8_t * pack_data, uint16_t * pack_data_length, struct TUORENIOT_RegistRequestStruct * registParams)
  34. {
  35. Log_Printf_Debug("mcu_id: %s\r\n", mcu_id);
  36. // 设置deviceId
  37. bytesToHex(registParams->deviceId, mcu_id, sizeof(mcu_id));
  38. sprintf((char *)(pack_data + 2), "{\"platform\":\"%s\",\"connectionType\":\"%s\",\"deviceId\":\"%s\"}",
  39. registParams->platform, registParams->networkProtocol, registParams->deviceId); // 拼接AT指令
  40. Log_Printf_Debug("%s\r\n", (char *)(pack_data + 2));
  41. uint16_t datalen = utils_aes128_ECB_base64_enc_with_length(regist_key, (pack_data + 2));
  42. pack_data[0] = datalen>>8;//头2个字节赋值数据长度
  43. pack_data[1] = datalen;
  44. * pack_data_length = datalen + 2;
  45. }
  46. // 函数声明
  47. static void REGIST_Process(void); // 注册流程
  48. static void REGIST_SetStatus(enum REGIST_StatusEnum status); // 设置注册状态
  49. static void REGIST_SetResult(enum REGIST_ResultEnum result); // 设置注册结果
  50. static void goto_start(void); // 开始
  51. static void goto_success(void); // 成功
  52. static void goto_failure(char * _info); // 失败
  53. static void goto_finish(void); // 结束
  54. // 流程
  55. enum Step{
  56. STEP_START, // 开始
  57. STEP_EXIT_SLEEP, // 退出睡眠
  58. STEP_ENTER_SLEEP, // 进入睡眠
  59. STEP_WAIT, // 等待
  60. STEP_STATE, // 查询状态
  61. STEP_OPEN, // 打开
  62. STEP_OPEN_WAIT_RESULT, // 等待打开结果
  63. STEP_JUDGE_AUTH_OR_DATA, // 判断认证还是发送
  64. STEP_JOIN_AUTH_MESSAGE, // 拼接认证报文
  65. STEP_JOIN_DATA_MESSAGE, // 拼接数据报文
  66. STEP_QUERY_SLEEP, // 查询休眠
  67. STEP_SET_SLEEP, // 开启休眠
  68. STEP_QUERY_QENG_SERVINGCELL, // 查询信号质量
  69. STEP_SET_QISDE_0, // 关闭发送回显
  70. STEP_SEND, // 发送
  71. STEP_RECV, // 等待发送结果
  72. STEP_SET_CFUN_0, // 设置最小功能模式
  73. STEP_WAIT_SET_CFUN_0, // 等待设置最小功能模式
  74. STEP_SET_CFUN_1, // 设置全功能模式
  75. STEP_WAIT_SET_CFUN_1, // 等待设置全功能模式结果
  76. STEP_SET_CGREG_2, // 设置ps域允许上报网络注册和位置信息
  77. STEP_QUERY_CGREG, // 查询网络注册状态
  78. STEP_CLOSE, // 关闭
  79. STEP_SUCCESS, // 成功
  80. STEP_FAILURE, // 失败
  81. STEP_FINISH, // 流程结束
  82. STEP_VERIFY_REGIST, // 验证注册
  83. STEP_VERIFY_INITIALIZE, // 验证初始化
  84. };
  85. // 步骤跳转时的监听
  86. static uint8_t STEP_QUERY_CGREG_times = 0; // 查询网络状态的次数
  87. static void initialize()
  88. {
  89. STEP_QUERY_CGREG_times = 0;
  90. }
  91. static uint16_t goto_step_event(uint16_t ns)
  92. {
  93. // 重置ec800m状态
  94. ec800m.reset();
  95. // 流程控制
  96. uint16_t step = ns;
  97. if(ns == STEP_QUERY_CGREG && STEP_QUERY_CGREG_times++ >= 20)
  98. {
  99. goto_failure("查询网络状态的次数过多,联网失败");
  100. step = STEP_FAILURE;
  101. }
  102. return step;
  103. }
  104. // 流程控制
  105. static struct PCTRL_Struct pctrl = {
  106. .current_step = STEP_FINISH,
  107. .next_step = STEP_FINISH,
  108. .step_wait = STEP_WAIT,
  109. .goto_step_listener = goto_step_event,
  110. };
  111. // 备注
  112. static char info[40];
  113. // 开始
  114. static void goto_start(void)
  115. {
  116. initialize();
  117. PCTRL_GotoStep(&pctrl, STEP_START, "开始");
  118. }
  119. // 成功
  120. static void goto_success(void)
  121. {
  122. REGIST_SetResult(REGIST_Result_Success);
  123. PCTRL_GotoStep(&pctrl, STEP_SUCCESS, "成功");
  124. }
  125. // 失败
  126. static void goto_failure(char * _info)
  127. {
  128. REGIST_SetResult(REGIST_Result_Failure);
  129. memset(info, 0, sizeof(info));
  130. strcpy(info, _info);
  131. PCTRL_GotoStep(&pctrl, STEP_FAILURE, "失败");
  132. Log_Printf_Debug("info:%s!\r\n", info);
  133. }
  134. // 结束
  135. static void goto_finish(void)
  136. {
  137. REGIST_SetStatus(REGIST_Status_Done);
  138. PCTRL_GotoStep(&pctrl, STEP_FINISH, "结束");
  139. }
  140. // 注册状态
  141. static enum REGIST_StatusEnum regist_status = REGIST_Status_None;
  142. // 注册结果
  143. static enum REGIST_ResultEnum regist_result = REGIST_Result_None;
  144. // 设置注册状态
  145. static void REGIST_SetStatus(enum REGIST_StatusEnum status)
  146. {
  147. regist_status = status;
  148. }
  149. // 获取注册状态
  150. enum REGIST_StatusEnum REGIST_GetStatus(void)
  151. {
  152. return regist_status;
  153. }
  154. // 设置注册结果
  155. static void REGIST_SetResult(enum REGIST_ResultEnum result)
  156. {
  157. regist_result = result;
  158. }
  159. // 获取注册结果
  160. enum REGIST_ResultEnum REGIST_GetResult(void)
  161. {
  162. return regist_result;
  163. }
  164. // 重置注册
  165. enum EXECUTE_ResultEnum REGIST_Reset(void)
  166. {
  167. if(REGIST_GetStatus() == REGIST_Status_Being)
  168. {
  169. Log_Printf_Debug("注册流程重置错误!\r\n");
  170. return EXECUTE_Result_Failure;
  171. }
  172. REGIST_SetStatus(REGIST_Status_None);
  173. REGIST_SetResult(REGIST_Result_None);
  174. return EXECUTE_Result_Success;
  175. }
  176. // 开始注册
  177. enum EXECUTE_ResultEnum REGIST_Start(void)
  178. {
  179. REGIST_Reset();
  180. if(REGIST_GetStatus() != REGIST_Status_None)
  181. {
  182. Log_Printf_Debug("注册流程启动错误!\r\n");
  183. return EXECUTE_Result_Failure;
  184. }
  185. goto_start();
  186. REGIST_SetStatus(REGIST_Status_Being);
  187. return EXECUTE_Result_Success;
  188. }
  189. // 注册流程处理,放到大循环里
  190. void REGIST_ProcessHandle(void)
  191. {
  192. if(REGIST_GetStatus() == REGIST_Status_Being)
  193. {
  194. REGIST_Process();
  195. }
  196. }
  197. // 发送数据的逻辑
  198. static enum Result result = Result_None;
  199. static uint8_t cgreg_n;
  200. static uint8_t cgreg_stat;
  201. static uint16_t cgreg_lac;
  202. static uint32_t cgreg_ci;
  203. static uint16_t socket_err = 0;
  204. static void REGIST_Process(void)
  205. {
  206. // 流程
  207. switch(pctrl.current_step)
  208. {
  209. case STEP_START: // 开始
  210. PCTRL_GotoStep(&pctrl, STEP_EXIT_SLEEP, "退出休眠");
  211. break;
  212. case STEP_EXIT_SLEEP: // 退出休眠
  213. ec800m.exit_sleep();
  214. PCTRL_GotoStepWait(&pctrl, STEP_SET_SLEEP, 3, "设置休眠模式");
  215. break;
  216. case STEP_SET_SLEEP: // 设置休眠模式
  217. result = ec800m.set_sleep(1);
  218. if(result != Result_None)
  219. {
  220. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_1, "设置全功能模式");
  221. }
  222. else if(result == Result_Failed)
  223. {
  224. goto_failure("设置休眠模式失败");
  225. }
  226. break;
  227. case STEP_SET_CFUN_1: // 设置全功能模式
  228. result = ec800m.set_cfun(1);
  229. if(result == Result_Success)
  230. {
  231. PCTRL_GotoStep(&pctrl, STEP_SET_CGREG_2, "设置ps域");
  232. }
  233. else if(result == Result_Failed)
  234. {
  235. goto_failure("设置全功能模式失败");
  236. }
  237. break;
  238. case STEP_SET_CGREG_2: // 设置ps域
  239. result = ec800m.set_cgreg(2);
  240. if(result == Result_Success)
  241. {
  242. PCTRL_GotoStep(&pctrl, STEP_QUERY_CGREG, "查询ps域");
  243. }
  244. else if(result == Result_Failed)
  245. {
  246. goto_failure("设置ps域失败");
  247. }
  248. break;
  249. case STEP_QUERY_CGREG: // 查询ps域
  250. result = ec800m.query_cgreg(&cgreg_n, &cgreg_stat, &cgreg_lac, &cgreg_ci);
  251. if(result == Result_Success)
  252. {
  253. if(cgreg_stat == 1)
  254. {
  255. PCTRL_GotoStep(&pctrl, STEP_CLOSE, "断开tcp连接");
  256. }
  257. else
  258. {
  259. PCTRL_GotoWait(&pctrl, 500);
  260. }
  261. }
  262. else if(result == Result_Failed)
  263. {
  264. goto_failure("查询ps域失败");
  265. }
  266. break;
  267. case STEP_CLOSE: // 关闭连接
  268. result = ec800m.close_socket(connectID);
  269. if(result == Result_Success)
  270. {
  271. if(REGIST_GetResult() != REGIST_Result_None)
  272. {
  273. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "设置最小功能模式");
  274. }
  275. else
  276. {
  277. PCTRL_GotoStep(&pctrl, STEP_SET_QISDE_0, "关闭发送回显");
  278. }
  279. }
  280. else if(result == Result_Failed)
  281. {
  282. goto_failure("断开tcp连接失败");
  283. }
  284. break;
  285. case STEP_SET_QISDE_0: // 关闭发送回显
  286. result = ec800m.set_qisde(0);
  287. if(result == Result_Success)
  288. {
  289. PCTRL_GotoStep(&pctrl, STEP_OPEN, "连接tcp");
  290. }
  291. else if(result == Result_Failed)
  292. {
  293. goto_failure("关闭发送回显失败");
  294. }
  295. break;
  296. case STEP_OPEN: // 打开客户端
  297. result=ec800m.open_socket(connectID, "TCP", REGIST_SERVER, REGIST_PORT, 1, &socket_err);
  298. if(result == Result_Success)
  299. {
  300. PCTRL_GotoStep(&pctrl, STEP_SEND, "发送数据");
  301. // 打包注册请求
  302. memset(regist_data, 0, sizeof(regist_data));
  303. TUORENIOT_PackRegistRequest(regist_data, &regist_data_length, &regist_request);
  304. Log_Printf_Debug("regist_data: \r\n");
  305. Log_SendHex(regist_data, regist_data_length);
  306. Log_Printf_Debug("\r\n");
  307. TUORENIOT_PrintfRegistRequestStruct(&regist_request);
  308. }
  309. else if(result == Result_Failed)
  310. {
  311. goto_failure("连接tcp失败");
  312. }
  313. break;
  314. case STEP_SEND: // 发送send
  315. result = ec800m.send(connectID, regist_data, regist_data_length);
  316. if(result == Result_Success)
  317. {
  318. PCTRL_GotoStep(&pctrl, STEP_RECV, "等待结果");
  319. memset(regist_data, 0, sizeof(regist_data));
  320. }
  321. else if(result == Result_Failed)
  322. {
  323. goto_failure("发送数据失败");
  324. }
  325. break;
  326. case STEP_RECV: // 等待结果
  327. result = ec800m.recv_with_time(connectID, regist_data, &regist_data_length, 10000);
  328. if(result == Result_Success)
  329. {
  330. uint8_t res = TUORENIOT_AnalysisRegistData(regist_data, regist_data_length);
  331. if(res == 1) // 成功
  332. {
  333. goto_success();
  334. }
  335. else // 失败
  336. {
  337. goto_failure("解析失败");
  338. }
  339. PCTRL_GotoStep(&pctrl, STEP_CLOSE, "断开tcp连接");
  340. }
  341. else if(result == Result_Failed)
  342. {
  343. goto_failure("等待结果失败");
  344. }
  345. break;
  346. case STEP_SET_CFUN_0: // 设置最小功能模式
  347. result = ec800m.set_cfun(0);
  348. if(result != Result_None)
  349. {
  350. PCTRL_GotoStep(&pctrl, STEP_ENTER_SLEEP, "进入睡眠");
  351. }
  352. break;
  353. case STEP_ENTER_SLEEP: // 进入睡眠
  354. ec800m.enter_sleep();
  355. goto_finish();
  356. break;
  357. case STEP_WAIT: // 等待
  358. PCTRL_Wait(&pctrl);
  359. break;
  360. case STEP_SUCCESS: // 成功
  361. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "设置最小功能模式");
  362. break;
  363. case STEP_FAILURE: // 失败
  364. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "设置最小功能模式");
  365. break;
  366. case STEP_FINISH: // 结束流程
  367. break;
  368. default:
  369. goto_failure("步骤不存在");
  370. break;
  371. }
  372. }
  373. #endif