EC800M_UDP_Client5.c 11 KB

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