EC800M_UDP_Client5.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. #include "CONFIG.h"
  2. #if EC800M
  3. #include "stm32f10x.h"
  4. #include <stdio.h>
  5. #include <stdarg.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include "UDP_Client.h"
  9. #include "Timer_Module.h"
  10. #include "Log_Module.h"
  11. #include "mbedtls_util.h"
  12. #include "cJSON.h"
  13. #include "Pump_Dicts_Util.h"
  14. #include "Regist.h"
  15. #include "PumpBusiness.h"
  16. #include "Initialize.h"
  17. #include "Tuoreniot.h"
  18. #include "ec800m.h"
  19. // 测试模式
  20. uint8_t UDPCLIENT_TestModeFlag = 0;
  21. // socket ID
  22. static uint8_t connectID = 5;
  23. // coap报文
  24. static uint8_t coap_message[512];
  25. static uint16_t coap_message_length = 0;
  26. // 待发送数据的地址和长度
  27. static uint8_t data[128];
  28. static uint16_t data_length;
  29. // 信号值
  30. static struct Signal
  31. {
  32. int RSRP;
  33. int RSRQ;
  34. int RSSI;
  35. int SINR;
  36. } signal = {
  37. .RSRP = 99,
  38. .RSRQ = 99,
  39. .RSSI = 99,
  40. .SINR = 99,
  41. };
  42. // 查询信号质量
  43. void UDPCLIENT_QuerySignal(int * RSRP, int * RSRQ, int * RSSI, int * SINR)
  44. {
  45. *RSRP = signal.RSRP;
  46. *RSRQ = signal.RSRQ;
  47. *RSSI = signal.RSSI;
  48. *SINR = signal.SINR;
  49. }
  50. // 函数声明
  51. static void UDPCLIENT_Process(void); // 流程
  52. static void UDPCLIENT_SetStatus(enum UDPCLIENT_StatusEnum status); // 设置状态
  53. static void UDPCLIENT_SetResult(enum UDPCLIENT_ResultEnum result); // 设置结果
  54. static void goto_start(void); // 开始
  55. static void goto_success(void); // 成功
  56. static void goto_failure(char * _info); // 失败
  57. static void goto_finish(void); // 结束
  58. // 流程
  59. enum Step{
  60. STEP_NONE, // 空闲状态,无操作
  61. STEP_START, // 开始
  62. STEP_EXIT_SLEEP, // 退出睡眠
  63. STEP_ENTER_SLEEP, // 进入睡眠
  64. STEP_WAIT, // 等待
  65. STEP_STATE, // 查询状态
  66. STEP_OPEN, // 打开
  67. STEP_OPEN_WAIT_RESULT, // 等待打开结果
  68. STEP_JUDGE_AUTH_OR_DATA, // 判断认证还是发送
  69. STEP_JOIN_AUTH_MESSAGE, // 拼接认证报文
  70. STEP_JOIN_DATA_MESSAGE, // 拼接数据报文
  71. STEP_QUERY_SLEEP, // 查询休眠
  72. STEP_SET_SLEEP, // 开启休眠
  73. STEP_QUERY_QENG_SERVINGCELL, // 查询信号质量
  74. STEP_SET_QISDE_0, // 关闭发送回显
  75. STEP_SEND, // 发送
  76. STEP_RECV, // 等待发送结果
  77. STEP_SET_CFUN_0, // 设置最小功能模式
  78. STEP_WAIT_SET_CFUN_0, // 等待设置最小功能模式
  79. STEP_SET_CFUN_1, // 设置全功能模式
  80. STEP_WAIT_SET_CFUN_1, // 等待设置全功能模式结果
  81. STEP_SET_CGREG_2, // 设置ps域允许上报网络注册和位置信息
  82. STEP_QUERY_CGREG, // 查询网络注册状态
  83. STEP_CLOSE, // 关闭
  84. STEP_SUCCESS, // 成功
  85. STEP_FAILURE, // 失败
  86. STEP_FINISH, // 流程结束
  87. STEP_VERIFY_REGIST, // 验证注册
  88. STEP_VERIFY_INITIALIZE, // 验证初始化
  89. };
  90. // 步骤跳转时的监听
  91. static uint8_t STEP_JOIN_AUTH_MESSAGE_times = 0; // 认证的次数
  92. static uint8_t STEP_QUERY_CGREG_times = 0; // 查询网络状态的次数
  93. static void initialize()
  94. {
  95. STEP_JOIN_AUTH_MESSAGE_times = 0;
  96. STEP_QUERY_CGREG_times = 0;
  97. }
  98. static uint16_t goto_step_event(uint16_t ns)
  99. {
  100. // 重置ec800m状态
  101. ec800m.reset();
  102. // 流程控制
  103. uint16_t step = ns;
  104. if(ns == STEP_JOIN_AUTH_MESSAGE && STEP_JOIN_AUTH_MESSAGE_times++ >= 1)
  105. {
  106. goto_failure("认证次数过多");
  107. step = STEP_FAILURE;
  108. }
  109. else if(ns == STEP_QUERY_CGREG && STEP_QUERY_CGREG_times++ >= 20)
  110. {
  111. goto_failure("查询网络状态的次数过多,联网失败");
  112. step = STEP_FAILURE;
  113. }
  114. return step;
  115. }
  116. // 流程控制
  117. static struct PCTRL_Struct pctrl = {
  118. .current_step = STEP_FINISH,
  119. .next_step = STEP_FINISH,
  120. .step_wait = STEP_WAIT,
  121. .goto_step_listener = goto_step_event,
  122. };
  123. // 备注
  124. static char info[40];
  125. // 开始
  126. static void goto_start(void)
  127. {
  128. initialize();
  129. PCTRL_GotoStep(&pctrl, STEP_START, "开始");
  130. }
  131. // 成功
  132. static void goto_success(void)
  133. {
  134. UDPCLIENT_SetResult(UDPCLIENT_Result_Success);
  135. PCTRL_GotoStep(&pctrl, STEP_SUCCESS, "成功");
  136. }
  137. // 失败
  138. static void goto_failure(char * _info)
  139. {
  140. UDPCLIENT_SetResult(UDPCLIENT_Result_Failure);
  141. memset(info, 0, sizeof(info));
  142. strcpy(info, _info);
  143. PCTRL_GotoStep(&pctrl, STEP_FAILURE, "失败");
  144. Log_Printf_Debug("info:%s!\r\n", info);
  145. }
  146. // 结束
  147. static void goto_finish(void)
  148. {
  149. UDPCLIENT_SetStatus(UDPCLIENT_Status_Done);
  150. PCTRL_GotoStep(&pctrl, STEP_FINISH, "结束");
  151. }
  152. // 状态
  153. static enum UDPCLIENT_StatusEnum udpclient_status = UDPCLIENT_Status_None;
  154. // 结果
  155. static enum UDPCLIENT_ResultEnum udpclient_result = UDPCLIENT_Result_None;
  156. // 设置状态
  157. static void UDPCLIENT_SetStatus(enum UDPCLIENT_StatusEnum status)
  158. {
  159. udpclient_status = status;
  160. }
  161. // 获取状态
  162. enum UDPCLIENT_StatusEnum UDPCLIENT_GetStatus(void)
  163. {
  164. return udpclient_status;
  165. }
  166. // 设置结果
  167. static void UDPCLIENT_SetResult(enum UDPCLIENT_ResultEnum result)
  168. {
  169. udpclient_result = result;
  170. }
  171. // 获取结果
  172. enum UDPCLIENT_ResultEnum UDPCLIENT_GetResult(void)
  173. {
  174. return udpclient_result;
  175. }
  176. // 重置
  177. enum EXECUTE_ResultEnum UDPCLIENT_Reset(void)
  178. {
  179. if(UDPCLIENT_GetStatus() == UDPCLIENT_Status_Being)
  180. {
  181. Log_Printf_Debug("发送流程重置错误!\r\n");
  182. return EXECUTE_Result_Failure;
  183. }
  184. UDPCLIENT_SetStatus(UDPCLIENT_Status_None);
  185. UDPCLIENT_SetResult(UDPCLIENT_Result_None);
  186. return EXECUTE_Result_Success;
  187. }
  188. // 开始
  189. enum EXECUTE_ResultEnum UDPCLIENT_Start(void)
  190. {
  191. UDPCLIENT_Reset();
  192. if(UDPCLIENT_GetStatus() != UDPCLIENT_Status_None)
  193. {
  194. Log_Printf_Debug("发送流程启动错误!\r\n");
  195. return EXECUTE_Result_Failure;
  196. }
  197. goto_start();
  198. UDPCLIENT_SetStatus(UDPCLIENT_Status_Being);
  199. return EXECUTE_Result_Success;
  200. }
  201. // 流程处理,放到大循环里
  202. void UDPCLIENT_ProcessHandle(void)
  203. {
  204. if(UDPCLIENT_GetStatus() == UDPCLIENT_Status_Being)
  205. {
  206. UDPCLIENT_Process();
  207. }
  208. }
  209. // 发送数据的逻辑
  210. static enum Result result = Result_None;
  211. static uint8_t cgreg_n;
  212. static uint8_t cgreg_stat;
  213. static uint16_t cgreg_lac;
  214. static uint32_t cgreg_ci;
  215. static uint16_t socket_err = 0;
  216. static void UDPCLIENT_Process(void)
  217. {
  218. // 流程
  219. switch(pctrl.current_step)
  220. {
  221. case STEP_NONE: // 空闲
  222. break;
  223. case STEP_START: // 开始
  224. PCTRL_GotoStep(&pctrl, STEP_EXIT_SLEEP, "退出休眠");
  225. break;
  226. case STEP_EXIT_SLEEP: // 退出休眠
  227. ec800m.exit_sleep();
  228. PCTRL_GotoStepWait(&pctrl, STEP_SET_SLEEP, 3, "设置休眠模式");
  229. break;
  230. case STEP_SET_SLEEP: // 设置休眠模式
  231. result = ec800m.set_sleep(1);
  232. if(result != Result_None)
  233. {
  234. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_1, "设置全功能模式");
  235. }
  236. else if(result == Result_Failed)
  237. {
  238. goto_failure("设置休眠模式失败");
  239. }
  240. break;
  241. case STEP_SET_CFUN_1: // 设置全功能模式
  242. result = ec800m.set_cfun(1);
  243. if(result == Result_Success)
  244. {
  245. PCTRL_GotoStep(&pctrl, STEP_SET_CGREG_2, "设置ps域");
  246. }
  247. else if(result == Result_Failed)
  248. {
  249. goto_failure("设置全功能模式失败");
  250. }
  251. break;
  252. case STEP_SET_CGREG_2: // 设置ps域
  253. result = ec800m.set_cgreg(2);
  254. if(result == Result_Success)
  255. {
  256. PCTRL_GotoStep(&pctrl, STEP_QUERY_CGREG, "查询ps域");
  257. }
  258. else if(result == Result_Failed)
  259. {
  260. goto_failure("设置ps域失败");
  261. }
  262. break;
  263. case STEP_QUERY_CGREG: // 查询ps域
  264. result = ec800m.query_cgreg(&cgreg_n, &cgreg_stat, &cgreg_lac, &cgreg_ci);
  265. if(result == Result_Success)
  266. {
  267. if(cgreg_stat == 1)
  268. {
  269. // 下一步
  270. if(UDPCLIENT_TestModeFlag == 0)
  271. {
  272. PCTRL_GotoStep(&pctrl, STEP_CLOSE, "关闭连接");
  273. }
  274. else
  275. {
  276. PCTRL_GotoStep(&pctrl, STEP_QUERY_QENG_SERVINGCELL, "查询信号质量");
  277. }
  278. }
  279. else
  280. {
  281. PCTRL_GotoWait(&pctrl, 500);
  282. }
  283. }
  284. else if(result == Result_Failed)
  285. {
  286. goto_failure("查询ps域失败");
  287. }
  288. break;
  289. case STEP_QUERY_QENG_SERVINGCELL: // 查询信号质量
  290. result = ec800m.qeng_servingcell(&signal.RSRP, &signal.RSRQ, &signal.RSSI, &signal.SINR);
  291. if(result == Result_Success)
  292. {
  293. PCTRL_GotoStep(&pctrl, STEP_CLOSE, "关闭连接");
  294. }
  295. else if(result == Result_Failed)
  296. {
  297. goto_failure("查询信号质量失败");
  298. }
  299. break;
  300. case STEP_CLOSE: // 关闭连接
  301. result = ec800m.close_socket(connectID);
  302. if(result == Result_Success)
  303. {
  304. PCTRL_GotoStep(&pctrl, STEP_SET_QISDE_0, "关闭发送回显");
  305. }
  306. else if(result == Result_Failed)
  307. {
  308. goto_failure("关闭连接失败");
  309. }
  310. break;
  311. case STEP_SET_QISDE_0: // 关闭发送回显
  312. result = ec800m.set_qisde(0);
  313. if(result == Result_Success)
  314. {
  315. PCTRL_GotoStep(&pctrl, STEP_OPEN, "打开客户端");
  316. }
  317. else if(result == Result_Failed)
  318. {
  319. goto_failure("关闭发送回显失败");
  320. }
  321. break;
  322. case STEP_OPEN: // 打开客户端
  323. result = ec800m.open_socket(connectID, "UDP", regist_response.remoteAddress, regist_response.remotePort, 1, &socket_err);
  324. if(result == Result_Success)
  325. {
  326. if(socket_err == 0)
  327. {
  328. PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "判断认证还是发送");
  329. }
  330. else
  331. {
  332. goto_failure("客户端打开错误");
  333. }
  334. }
  335. else if(result == Result_Failed)
  336. {
  337. goto_failure("打开客户端失败");
  338. }
  339. break;
  340. case STEP_JUDGE_AUTH_OR_DATA: // 判断认证还是发送
  341. if(TUORENIOT_IsAuthentication() == 1) // 已认证
  342. {
  343. PCTRL_GotoStep(&pctrl, STEP_JOIN_DATA_MESSAGE, "拼接数据报文");
  344. }
  345. else
  346. {
  347. PCTRL_GotoStep(&pctrl, STEP_JOIN_AUTH_MESSAGE, "拼接认证报文");
  348. }
  349. break;
  350. case STEP_JOIN_AUTH_MESSAGE: // 拼接认证报文
  351. memset(coap_message, 0, sizeof(coap_message));
  352. TUORENIOT_PackAuthMessage(coap_message, &coap_message_length);
  353. // Log_Printf_Debug("认证报文:%d\r\n", coap_message_length);
  354. // Log_SendHex(coap_message, coap_message_length);
  355. // Log_Printf_Debug("\r\n");
  356. PCTRL_GotoStep(&pctrl, STEP_SEND, "发送认证报文");
  357. break;
  358. case STEP_JOIN_DATA_MESSAGE: // 拼接数据报文
  359. pump_params.lac = cgreg_lac;
  360. pump_params.ci = cgreg_ci;
  361. PUMPBUSINESS_ParamsRefresh();
  362. // 编码
  363. memset(data, 0, sizeof(data));
  364. PUMPDICTS_ProtocolEncode(&pump_params, data, &data_length);
  365. memset(coap_message, 0, sizeof(coap_message));
  366. TUORENIOT_PackDataMessage(data, data_length, coap_message, &coap_message_length);
  367. // Log_Printf_Debug("数据报文:%d\r\n", coap_message_length);
  368. // Log_SendHex(coap_message, coap_message_length);
  369. // Log_Printf_Debug("\r\n");
  370. PCTRL_GotoStep(&pctrl, STEP_SEND, "发送数据报文");
  371. break;
  372. case STEP_SEND: // 发送send
  373. result = ec800m.send(connectID, coap_message, coap_message_length);
  374. if(result == Result_Success)
  375. {
  376. PCTRL_GotoStep(&pctrl, STEP_RECV, "等待接收数据");
  377. }
  378. else if(result == Result_Failed)
  379. {
  380. goto_failure("发送send失败");
  381. }
  382. break;
  383. case STEP_RECV: // 等待结果
  384. result = ec800m.recv_with_time(connectID, coap_message, &coap_message_length, 10000);
  385. if(result == Result_Success)
  386. {
  387. uint8_t res = TUORENIOT_AnalysisMessage(coap_message, coap_message_length);
  388. if(res == 0) // 发送失败
  389. {
  390. PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "重新认证"); // 重新认证
  391. }
  392. else if(res == 1) // 认证成功
  393. {
  394. PCTRL_GotoStep(&pctrl, STEP_JOIN_DATA_MESSAGE, "拼接数据报文");
  395. }
  396. else if(res == 2) // 发送成功
  397. {
  398. goto_success();
  399. }
  400. }
  401. else if(result == Result_Failed)
  402. {
  403. goto_failure("等待结果失败");
  404. }
  405. break;
  406. case STEP_SET_CFUN_0: // 设置最小功能模式
  407. result = ec800m.set_cfun(0);
  408. if(result != Result_None)
  409. {
  410. PCTRL_GotoStep(&pctrl, STEP_ENTER_SLEEP, "进入睡眠");
  411. }
  412. break;
  413. case STEP_ENTER_SLEEP: // 进入睡眠
  414. ec800m.enter_sleep();
  415. goto_finish();
  416. break;
  417. case STEP_WAIT: // 等待
  418. PCTRL_Wait(&pctrl);
  419. break;
  420. case STEP_SUCCESS: // 成功
  421. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "设置最小功能模式");
  422. break;
  423. case STEP_FAILURE: // 失败
  424. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "设置最小功能模式");
  425. break;
  426. case STEP_FINISH: // 结束流程
  427. break;
  428. default:
  429. goto_failure("步骤不存在");
  430. break;
  431. }
  432. }
  433. #endif