BC260Y_UDP_Client5.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. #include "CONFIG.h"
  2. #if BC260Y
  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 "bc260y.h"
  14. #include "Pump_Dicts_Util.h"
  15. #include "Regist.h"
  16. #include "PumpBusiness.h"
  17. #include "Initialize.h"
  18. #include "Tuoreniot.h"
  19. // 测试模式
  20. uint8_t UDPCLIENT_TestModeFlag = 0;
  21. // socket ID
  22. static uint8_t connectID = 1;
  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_START, // 开始
  61. STEP_EXIT_SLEEP, // 退出睡眠
  62. STEP_ENTER_SLEEP, // 进入睡眠
  63. STEP_WAIT, // 等待
  64. STEP_STATE, // 查询状态
  65. STEP_OPEN, // 打开
  66. STEP_OPEN_WAIT_RESULT, // 等待打开结果
  67. STEP_JUDGE_AUTH_OR_DATA, // 判断认证还是发送
  68. STEP_JOIN_AUTH_MESSAGE, // 拼接认证报文
  69. STEP_JOIN_DATA_MESSAGE, // 拼接数据报文
  70. STEP_QUERY_SLEEP, // 查询休眠
  71. STEP_SET_SLEEP, // 开启休眠
  72. STEP_QUERY_QENG_SERVINGCELL, // 查询信号质量
  73. STEP_QUERY_ID, //查询SIM卡号
  74. STEP_SET_QISDE_0, // 关闭发送回显
  75. STEP_SET_QISDE_1,
  76. STEP_SEND, // 发送
  77. STEP_RECV, // 等待发送结果
  78. STEP_QUERY_CFUN,
  79. STEP_SET_CFUN_0, // 设置最小功能模式
  80. STEP_WAIT_SET_CFUN_0, // 等待设置最小功能模式
  81. STEP_SET_CFUN_1, // 设置全功能模式
  82. STEP_WAIT_SET_CFUN_1, // 等待设置全功能模式结果
  83. STEP_SET_CGREG_2, // 设置ps域允许上报网络注册和位置信息
  84. STEP_QUERY_CGREG, // 查询网络注册状态
  85. STEP_DATAFORMAT,//配置发送格式
  86. STEP_CLOSE, // 关闭
  87. STEP_SUCCESS, // 成功
  88. STEP_FAILURE, // 失败
  89. STEP_FINISH, // 流程结束
  90. STEP_VERIFY_REGIST,//验证注册
  91. STEP_VERIFY_INITIALIZE, // 验证初始化
  92. STEP_QUERY_SOCKET, // 查询连接
  93. STEP_QUERY_DNS, // 查询DNS
  94. STEP_SET_DNS, // 设置DNS
  95. STEP_QUERY_CFUN_DNS, // 设置完dns后,查询功能模式
  96. STEP_SET_CFUN_0_DNS, // 设置完dns后,设置最小功能模式
  97. };
  98. // 步骤跳转时的监听
  99. static uint8_t STEP_JOIN_AUTH_MESSAGE_times = 0; // 认证的次数
  100. static uint8_t STEP_SET_CFUN_1_times = 0; // 全功能模式的次数
  101. static void initialize()
  102. {
  103. STEP_JOIN_AUTH_MESSAGE_times = 0;
  104. STEP_SET_CFUN_1_times = 0;
  105. }
  106. static uint16_t goto_step_event(uint16_t ns)
  107. {
  108. // 重置bc260y状态
  109. bc260y.reset();
  110. // 流程控制
  111. uint16_t step = ns;
  112. if(step == STEP_JOIN_AUTH_MESSAGE && STEP_JOIN_AUTH_MESSAGE_times++ >= 1)
  113. {
  114. goto_failure("认证次数过多");
  115. step = STEP_FAILURE;
  116. }
  117. else if(step == STEP_SET_CFUN_1 && STEP_SET_CFUN_1_times++ >= 2)
  118. {
  119. goto_failure("重新联网次数过多");
  120. step = STEP_FAILURE;
  121. }
  122. return step;
  123. }
  124. // 流程控制
  125. static struct PCTRL_Struct pctrl = {
  126. .current_step = STEP_FINISH,
  127. .next_step = STEP_FINISH,
  128. .step_wait = STEP_WAIT,
  129. .goto_step_listener = goto_step_event,
  130. };
  131. // 备注
  132. static char info[40];
  133. // 开始
  134. static void goto_start(void)
  135. {
  136. initialize();
  137. PCTRL_GotoStep(&pctrl, STEP_START, "开始");
  138. }
  139. // 成功
  140. static void goto_success(void)
  141. {
  142. UDPCLIENT_SetResult(UDPCLIENT_Result_Success);
  143. PCTRL_GotoStep(&pctrl, STEP_SUCCESS, "成功");
  144. }
  145. // 失败
  146. static void goto_failure(char * _info)
  147. {
  148. UDPCLIENT_SetResult(UDPCLIENT_Result_Failure);
  149. memset(info, 0, sizeof(info));
  150. strcpy(info, _info);
  151. PCTRL_GotoStep(&pctrl, STEP_FAILURE, "失败");
  152. Log_Printf_Debug("info:%s!\r\n", info);
  153. }
  154. // 结束
  155. static void goto_finish(void)
  156. {
  157. UDPCLIENT_SetStatus(UDPCLIENT_Status_Done);
  158. PCTRL_GotoStep(&pctrl, STEP_FINISH, "结束");
  159. }
  160. // 状态
  161. static enum UDPCLIENT_StatusEnum udpclient_status = UDPCLIENT_Status_None;
  162. // 结果
  163. static enum UDPCLIENT_ResultEnum udpclient_result = UDPCLIENT_Result_None;
  164. // 设置状态
  165. static void UDPCLIENT_SetStatus(enum UDPCLIENT_StatusEnum status)
  166. {
  167. udpclient_status = status;
  168. }
  169. // 获取状态
  170. enum UDPCLIENT_StatusEnum UDPCLIENT_GetStatus(void)
  171. {
  172. return udpclient_status;
  173. }
  174. // 设置结果
  175. static void UDPCLIENT_SetResult(enum UDPCLIENT_ResultEnum result)
  176. {
  177. udpclient_result = result;
  178. }
  179. // 获取结果
  180. enum UDPCLIENT_ResultEnum UDPCLIENT_GetResult(void)
  181. {
  182. return udpclient_result;
  183. }
  184. // 重置
  185. enum EXECUTE_ResultEnum UDPCLIENT_Reset(void)
  186. {
  187. if(UDPCLIENT_GetStatus() == UDPCLIENT_Status_Being)
  188. {
  189. Log_Printf_Debug("发送流程重置错误!\r\n");
  190. return EXECUTE_Result_Failure;
  191. }
  192. UDPCLIENT_SetStatus(UDPCLIENT_Status_None);
  193. UDPCLIENT_SetResult(UDPCLIENT_Result_None);
  194. return EXECUTE_Result_Success;
  195. }
  196. // 开始
  197. enum EXECUTE_ResultEnum UDPCLIENT_Start(void)
  198. {
  199. UDPCLIENT_Reset();
  200. if(UDPCLIENT_GetStatus() != UDPCLIENT_Status_None)
  201. {
  202. Log_Printf_Debug("发送流程启动错误!\r\n");
  203. return EXECUTE_Result_Failure;
  204. }
  205. goto_start();
  206. UDPCLIENT_SetStatus(UDPCLIENT_Status_Being);
  207. return EXECUTE_Result_Success;
  208. }
  209. // 流程处理,放到大循环里
  210. void UDPCLIENT_ProcessHandle(void)
  211. {
  212. if(UDPCLIENT_GetStatus() == UDPCLIENT_Status_Being)
  213. {
  214. UDPCLIENT_Process();
  215. }
  216. }
  217. //// 发送数据的逻辑
  218. static enum Result result = Result_None;
  219. static uint8_t cgreg_n;
  220. static uint8_t cgreg_stat;
  221. static uint16_t cgreg_lac;
  222. static uint32_t cgreg_ci;
  223. //static uint8_t query_cgreg_times = 0; // 查询网络状态的次数
  224. static uint16_t socket_err = 0;
  225. // dns
  226. static char pridnsaddr[20];
  227. static uint8_t cfun_mode = 0;
  228. static uint8_t connectstate = 0;
  229. // 开启回显的标志
  230. static void UDPCLIENT_Process(void)
  231. {
  232. // 流程
  233. switch(pctrl.current_step)
  234. {
  235. case STEP_START: // 开始
  236. PCTRL_GotoStep(&pctrl, STEP_EXIT_SLEEP, "退出休眠");
  237. break;
  238. case STEP_EXIT_SLEEP: // 退出休眠
  239. result = bc260y.exit_sleep_2();
  240. if(result == Result_Success)
  241. {
  242. PCTRL_GotoStep(&pctrl, STEP_SET_QISDE_1, "开启回显");
  243. }
  244. else if(result == Result_Failed)
  245. {
  246. goto_failure("退出休眠失败");
  247. }
  248. break;
  249. case STEP_SET_QISDE_1: // 开启回显
  250. result = bc260y.set_qisde(1);
  251. if(result == Result_Success)
  252. {
  253. PCTRL_GotoStep(&pctrl, STEP_SET_SLEEP, "设置休眠模式");
  254. }
  255. else if(result == Result_Failed)
  256. {
  257. goto_failure("开启回显失败");
  258. }
  259. break;
  260. case STEP_SET_SLEEP: // 设置休眠模式
  261. result = bc260y.set_sleep(2);
  262. if(result == Result_Success)
  263. {
  264. PCTRL_GotoStep(&pctrl, STEP_DATAFORMAT, "配置发送格式");
  265. }
  266. else if(result == Result_Failed)
  267. {
  268. goto_failure("设置休眠模式失败");
  269. }
  270. break;
  271. case STEP_DATAFORMAT: // 配置发送格式
  272. result = bc260y.dataformat(1);
  273. if(result == Result_Success)
  274. {
  275. PCTRL_GotoStep(&pctrl, STEP_QUERY_CFUN, "查询功能模式");
  276. }
  277. else if(result == Result_Failed)
  278. {
  279. goto_failure("配置发送格式失败");
  280. }
  281. break;
  282. case STEP_QUERY_CFUN: // 查询功能模式
  283. result = bc260y.query_cfun(&cfun_mode);
  284. if(result == Result_Success)
  285. {
  286. if(cfun_mode == 0)
  287. {
  288. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_1, "设置全功能模式");
  289. }
  290. else
  291. {
  292. PCTRL_GotoStep(&pctrl, STEP_QUERY_DNS, "查询DNS");
  293. memset(pridnsaddr, 0, sizeof(pridnsaddr));
  294. }
  295. }
  296. else if(result == Result_Failed)
  297. {
  298. goto_failure("查询功能模式失败");
  299. }
  300. break;
  301. case STEP_SET_CFUN_0:
  302. result=bc260y.set_cfun(0);//设置最小功能模式
  303. if(result == Result_Success)
  304. {
  305. if(UDPCLIENT_GetResult() != UDPCLIENT_Result_None)
  306. {
  307. goto_finish();
  308. }
  309. else
  310. {
  311. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_1, "设置全功能模式");
  312. }
  313. }
  314. else if(result == Result_Failed)
  315. {
  316. goto_failure("设置最小功能模式失败");
  317. goto_finish();
  318. }
  319. break;
  320. case STEP_SET_CFUN_1: // 设置全功能模式
  321. result = bc260y.set_cfun(1);
  322. if(result == Result_Success)
  323. {
  324. PCTRL_GotoStep(&pctrl, STEP_QUERY_DNS, "查询DNS");
  325. memset(pridnsaddr, 0, sizeof(pridnsaddr));
  326. }
  327. else if(result == Result_Failed)
  328. {
  329. goto_failure("设置全功能模式失败");
  330. }
  331. break;
  332. case STEP_QUERY_DNS: // 查询DNS
  333. result = bc260y.query_dns(pridnsaddr);
  334. if(result == Result_Success)
  335. {
  336. if(strlen(pridnsaddr) <= 1)
  337. {
  338. PCTRL_GotoStep(&pctrl, STEP_SET_DNS, "设置DNS");
  339. }
  340. else
  341. {
  342. PCTRL_GotoStep(&pctrl, STEP_SET_CGREG_2, "设置ps域");
  343. }
  344. }
  345. else if(result == Result_Failed)
  346. {
  347. goto_failure("查询DNS失败");
  348. }
  349. break;
  350. case STEP_SET_DNS:
  351. result = bc260y.set_dns("114.114.114.114", "8.8.8.8"); // 设置DNS
  352. if(result == Result_Success)
  353. {
  354. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "设置完DNS,设置最小功能模式");
  355. }
  356. else if(result == Result_Failed)
  357. {
  358. goto_failure("设置DNS失败");
  359. }
  360. break;
  361. case STEP_SET_CGREG_2: // 设置ps域
  362. result = bc260y.set_cereg(2);
  363. if(result == Result_Success)
  364. {
  365. PCTRL_GotoStep(&pctrl, STEP_QUERY_ID, "查询SIM卡号");
  366. }
  367. else if(result == Result_Failed)
  368. {
  369. goto_failure("设置ps域失败");
  370. }
  371. break;
  372. case STEP_QUERY_ID: //查询SIM卡号
  373. result = bc260y.query_qccid(pump_params.sim);
  374. if(result == Result_Success)
  375. {
  376. PCTRL_GotoStep(&pctrl, STEP_QUERY_CGREG, "查询ps域");
  377. }
  378. else if(result == Result_Failed)
  379. {
  380. goto_failure("查询SIM卡号失败");
  381. }
  382. break;
  383. case STEP_QUERY_CGREG: // 查询ps域
  384. result = bc260y.query_cereg(&cgreg_n, &cgreg_stat, &cgreg_lac, &cgreg_ci);
  385. if(result == Result_Success)
  386. {
  387. if(cgreg_stat == 1)
  388. {
  389. // 下一步
  390. if(UDPCLIENT_TestModeFlag == 0)
  391. {
  392. PCTRL_GotoStep(&pctrl, STEP_QUERY_SOCKET, "查询连接");
  393. }
  394. else
  395. {
  396. PCTRL_GotoStep(&pctrl, STEP_QUERY_QENG_SERVINGCELL, "查询信号质量");
  397. }
  398. }
  399. else
  400. {
  401. goto_failure("网络注册失败");
  402. }
  403. }
  404. else if(result == Result_Failed)
  405. {
  406. goto_failure("查询ps域失败");
  407. }
  408. break;
  409. case STEP_QUERY_QENG_SERVINGCELL: // 查询信号质量
  410. result = bc260y.qeng_servingcell(&signal.RSRP, &signal.RSRQ, &signal.RSSI, &signal.SINR);
  411. if(result == Result_Success)
  412. {
  413. PCTRL_GotoStep(&pctrl, STEP_QUERY_SOCKET, "查询连接");
  414. }
  415. else if(result == Result_Failed)
  416. {
  417. goto_failure("查询信号质量失败");
  418. }
  419. break;
  420. case STEP_QUERY_SOCKET: // 查询连接
  421. result =bc260y.query_socket_state(connectID,&connectstate);
  422. if(result == Result_Success)
  423. {
  424. if(connectstate==2)
  425. {
  426. PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "判断认证或发送");
  427. }
  428. else
  429. {
  430. PCTRL_GotoStep(&pctrl, STEP_CLOSE, "关闭连接");
  431. }
  432. }
  433. else if(result == Result_Failed)
  434. {
  435. goto_failure("查询UDP连接失败");
  436. }
  437. break;
  438. case STEP_CLOSE: // 关闭连接
  439. result = bc260y.close_socket(connectID);
  440. if(result == Result_Success)
  441. {
  442. PCTRL_GotoStep(&pctrl, STEP_OPEN, "打开客户端");
  443. }
  444. else if(result == Result_Failed)
  445. {
  446. goto_failure("关闭连接失败");
  447. }
  448. break;
  449. case STEP_OPEN: // 打开客户端
  450. result = bc260y.open_socket(connectID, "UDP", regist_response.remoteAddress, regist_response.remotePort, 1, &socket_err);
  451. if(result == Result_Success)
  452. {
  453. if(socket_err == 0)
  454. {
  455. PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "判断认证或发送");
  456. }
  457. else
  458. {
  459. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "打开客户端失败,设置最小功能模式");
  460. }
  461. }
  462. else if(result == Result_Failed)
  463. {
  464. goto_failure("打开客户端失败");
  465. }
  466. break;
  467. case STEP_JUDGE_AUTH_OR_DATA: // 判断认证或发送
  468. if(TUORENIOT_IsAuthentication() == 1) // 已认证
  469. {
  470. PCTRL_GotoStep(&pctrl, STEP_JOIN_DATA_MESSAGE, "拼接数据报文");
  471. }
  472. else
  473. {
  474. PCTRL_GotoStep(&pctrl, STEP_JOIN_AUTH_MESSAGE, "拼接认证报文");
  475. }
  476. break;
  477. case STEP_JOIN_AUTH_MESSAGE: // 拼接认证报文
  478. memset(coap_message, 0, sizeof(coap_message));
  479. TUORENIOT_PackAuthMessage(coap_message, &coap_message_length);
  480. // Log_Printf_Debug("认证报文:%d\r\n", coap_message_length);
  481. // Log_SendHex(coap_message, coap_message_length);
  482. // Log_Printf_Debug("\r\n");
  483. PCTRL_GotoStep(&pctrl, STEP_SEND, "发送认证报文");
  484. break;
  485. case STEP_JOIN_DATA_MESSAGE: // 拼接数据报文
  486. pump_params.lac = cgreg_lac;
  487. pump_params.ci = cgreg_ci;
  488. PUMPBUSINESS_ParamsRefresh();
  489. // 编码
  490. memset(data, 0, sizeof(data));
  491. PUMPDICTS_ProtocolEncode(&pump_params, data, &data_length);
  492. memset(coap_message, 0, sizeof(coap_message));
  493. TUORENIOT_PackDataMessage(data, data_length, coap_message, &coap_message_length);
  494. // Log_Printf_Debug("数据报文:%d\r\n", coap_message_length);
  495. // Log_SendHex(coap_message, coap_message_length);
  496. // Log_Printf_Debug("\r\n");
  497. PCTRL_GotoStep(&pctrl, STEP_SEND, "发送数据报文");
  498. break;
  499. case STEP_SEND: // 发送send
  500. result = bc260y.send_rai(connectID, coap_message, coap_message_length, 2);
  501. if(result == Result_Success)
  502. {
  503. memset(coap_message, 0, sizeof(coap_message));
  504. PCTRL_GotoStep(&pctrl, STEP_RECV, "等待接收数据");
  505. }
  506. else if(result == Result_Failed)
  507. {
  508. goto_failure("发送send失败");
  509. }
  510. break;
  511. case STEP_RECV: // 等待结果
  512. result = bc260y.recv_with_time(connectID, coap_message, &coap_message_length, 10000);
  513. if(result == Result_Success)
  514. {
  515. uint8_t res = TUORENIOT_AnalysisMessage(coap_message, coap_message_length);
  516. if(res == 0) // 发送失败
  517. {
  518. PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "重新认证"); // 重新认证
  519. }
  520. else if(res == 1) // 认证成功
  521. {
  522. PCTRL_GotoStep(&pctrl, STEP_JOIN_DATA_MESSAGE, "拼接数据报文");
  523. }
  524. else if(res == 2) // 发送成功
  525. {
  526. goto_success();
  527. }
  528. }
  529. else if(result == Result_Failed)
  530. {
  531. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "重新发送,设置最小功能模式");
  532. }
  533. break;
  534. case STEP_WAIT: // 等待
  535. PCTRL_Wait(&pctrl);
  536. break;
  537. case STEP_SUCCESS: // 成功
  538. goto_finish();
  539. break;
  540. case STEP_FAILURE: // 失败
  541. PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "失败,设置最小功能模式");
  542. break;
  543. case STEP_FINISH: // 结束流程
  544. break;
  545. default:
  546. goto_failure("步骤不存在");
  547. break;
  548. }
  549. }
  550. #endif