Esp32_UDP_Client5.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. #include "CONFIG.h"
  2. #if ESP32
  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 "esp32.h"
  14. #include "Pump_Dicts_Util.h"
  15. #include "Regist.h"
  16. #include "PumpBusiness.h"
  17. #include "Initialize.h"
  18. #include "Tuoreniot.h"
  19. //WiFi连接参数
  20. char WIFI_ID[50]="tuoren";
  21. char WIFI_PASSWORD[30]="123456789";
  22. // 测试模式
  23. uint8_t UDPCLIENT_TestModeFlag = 0;
  24. // coap报文
  25. static uint8_t coap_message[512];
  26. static uint16_t coap_message_length = 0;
  27. // 待发送数据的地址和长度
  28. static uint8_t data[128];
  29. static uint16_t data_length;
  30. // 信号值
  31. static struct Signal
  32. {
  33. int RSRP;
  34. int RSRQ;
  35. int RSSI;
  36. int SINR;
  37. } signal = {
  38. .RSRP = 99,
  39. .RSRQ = 99,
  40. .RSSI = 99,
  41. .SINR = 99,
  42. };
  43. // 查询信号质量
  44. void UDPCLIENT_QuerySignal(int * RSRP, int * RSRQ, int * RSSI, int * SINR)
  45. {
  46. *RSRP = signal.RSRP;
  47. *RSRQ = signal.RSRQ;
  48. *RSSI = signal.RSSI;
  49. *SINR = signal.SINR;
  50. }
  51. // 函数声明
  52. static void UDPCLIENT_Process(void); // 流程
  53. static void UDPCLIENT_SetStatus(enum UDPCLIENT_StatusEnum status); // 设置状态
  54. static void UDPCLIENT_SetResult(enum UDPCLIENT_ResultEnum result); // 设置结果
  55. static void goto_start(void); // 开始
  56. static void goto_success(void); // 成功
  57. static void goto_failure(char * _info); // 失败
  58. static void goto_finish(void); // 结束
  59. /******************************************* 通信流程 *******************************************/
  60. enum Step{
  61. STEP_NONE, // 空闲状态,无操作
  62. STEP_START, // 开始
  63. STEP_READY, // 模块是否唤醒
  64. STEP_EXIT_DEEP_SLEEP, // 退出深睡眠
  65. STEP_ENTER_DEEP_SLEEP, // 进入深睡眠
  66. STEP_WAIT, // 等待
  67. STEP_SET_MODE, // 设置WIFI工作模式
  68. STEP_SELECT_AP, // 选择AP
  69. STEP_CONNECT_AP, // 连接AP
  70. STEP_QUERY_SIGNAL, // 查询WiFi信号强度
  71. STEP_SET_CIPMODE, // 设置传输模式
  72. STEP_CONNECT_NETWORK, // 连接TCP/UDP网络
  73. STEP_HANDLE, // 处理数据(数据发送+等待发送结果)
  74. STEP_JUDGE_AUTH_OR_DATA,// 判断认证还是发送
  75. STEP_JOIN_AUTH_MESSAGE, // 拼接认证报文
  76. STEP_JOIN_DATA_MESSAGE, // 拼接数据报文
  77. STEP_CLOSE_AP, // 断开AP连接
  78. STEP_CLOSE_NETWORK, // 断开TCP/UDP网络
  79. STEP_RST, // 重启WiFi模块
  80. STEP_RESET, // 数据发送流程重置
  81. STEP_SUCCESS, // 成功
  82. STEP_FAILURE, // 失败
  83. STEP_FINISH, // 流程结束
  84. };
  85. // 步骤跳转时的监听
  86. static uint8_t STEP_HANDLE_times = 0; // 数据重发的次数
  87. static uint8_t STEP_RESET_times = 0; // 流程重置的次数
  88. static void initialize()
  89. {
  90. STEP_HANDLE_times = 0;
  91. STEP_RESET_times = 0;
  92. }
  93. static uint16_t goto_step_event(uint16_t ns)
  94. {
  95. // 重置esp32状态
  96. esp32.reset();
  97. // 流程控制
  98. uint16_t step = ns;
  99. if(step == STEP_HANDLE && STEP_HANDLE_times++ >= 2)
  100. {
  101. Log_Printf_Debug("数据重发次数过多");
  102. step = STEP_RESET;
  103. }
  104. if(step == STEP_RESET )
  105. {
  106. //流程重置时其他步骤计数变量置0
  107. STEP_HANDLE_times = 0;
  108. //流程重置1次时退出
  109. if(STEP_RESET_times++ >= 1)
  110. {
  111. goto_failure("流程重置次数过多");
  112. step = STEP_FAILURE;
  113. }
  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. int wifi_rssi[10]; // 各wifi信号值存储数组
  212. static int wifi_number = 0; // wifi信息编号变量
  213. static int wifi_location=0; // 最佳wifi信号在数组中的位置
  214. static int select_ap_flag = 0; // 选择AP标志位 0:未选择 1:已选择
  215. static enum Result result = Result_None;
  216. //获取最佳wifi_rssi中最佳信号位置
  217. int get_BestWifiSignal(int* rssi, int number)
  218. {
  219. int signal=0; //假设首个wifi信号最好
  220. int value=-99; //初始化比较值
  221. for(int i=0; i<number; i++)
  222. {
  223. if((rssi[i] > value) && (rssi[i] != 0))
  224. {
  225. value = rssi[i];
  226. signal = i;
  227. }
  228. }
  229. return signal;
  230. }
  231. static void UDPCLIENT_Process(void)
  232. {
  233. switch(pctrl.current_step)
  234. {
  235. case STEP_NONE: break; // 空闲
  236. case STEP_START: // 开始
  237. PCTRL_GotoStep(&pctrl, STEP_EXIT_DEEP_SLEEP, "退出深休眠");
  238. break;
  239. case STEP_EXIT_DEEP_SLEEP: // 退出深休眠
  240. esp32.exit_deepsleep();
  241. PCTRL_GotoStepWait(&pctrl, STEP_READY,5, "判断模块是否启动");
  242. break;
  243. case STEP_READY: // 判断模块是否启动
  244. result = esp32.recv_ready_with_time(5000);
  245. if(result == Result_Success)
  246. {
  247. PCTRL_GotoStep(&pctrl, STEP_SET_MODE, "设置WiFi为Station工作模式");
  248. }
  249. else if(result == Result_Failed)
  250. {
  251. Log_Printf_Debug("WiFi模块启动失败");
  252. PCTRL_GotoStep(&pctrl, STEP_RST, "重启WiFi模块");
  253. }
  254. break;
  255. case STEP_RST:
  256. result = esp32.rst();
  257. if(result == Result_Success)
  258. {
  259. PCTRL_GotoStep(&pctrl, STEP_SET_MODE, "设置WiFi为Station工作模式");
  260. }
  261. else if(result == Result_Failed)
  262. {
  263. goto_failure("重启WiFi模块失败");
  264. }
  265. break;
  266. case STEP_SET_MODE: // 设置WiFi为Station模式
  267. result = esp32.set_mode(1);
  268. if(result == Result_Success)
  269. {
  270. PCTRL_GotoStep(&pctrl, STEP_SELECT_AP, "选择AP");
  271. }
  272. else if(result == Result_Failed)
  273. {
  274. Log_Printf_Debug("设置工作模式失败");
  275. PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置");
  276. }
  277. break;
  278. case STEP_SELECT_AP:
  279. if(select_ap_flag == 0)
  280. {
  281. if(wifi_number < regist_response.wifiNumber)
  282. {
  283. result = esp32.query_id_signal(regist_response.wifi[wifi_number].wifiName, &wifi_rssi[wifi_number]);
  284. if(result == Result_Success ||result == Result_Failed)
  285. {
  286. // Log_Printf_Debug("wifi%d的信号值RSSI=%d\r\n",wifi_number,wifi_rssi[wifi_number]);
  287. // Log_Printf_Debug("wifi_number=%d\r\n",wifi_number);
  288. wifi_number++;
  289. PCTRL_GotoStep(&pctrl, STEP_SELECT_AP, "继续选择AP");
  290. }
  291. }
  292. else
  293. {
  294. //获取信号最佳的wifi在数组中的位置
  295. wifi_location=get_BestWifiSignal(wifi_rssi, wifi_number);
  296. //拷贝wifi信息
  297. strcpy(WIFI_ID,regist_response.wifi[wifi_location].wifiName);
  298. strcpy(WIFI_PASSWORD,regist_response.wifi[wifi_location].wifiPassword);
  299. //选择AP标志位置1
  300. select_ap_flag =1;
  301. Log_Printf_Debug("选择信号最好的第%d组wifi\r\n",wifi_location);
  302. Log_Printf_Debug("WIFI_ID=%s\r\n",WIFI_ID);
  303. Log_Printf_Debug("WIFI_PASSWORD=%s\r\n",WIFI_PASSWORD);
  304. PCTRL_GotoStep(&pctrl, STEP_CONNECT_AP, "连接AP");
  305. }
  306. }
  307. else
  308. {
  309. PCTRL_GotoStep(&pctrl, STEP_CONNECT_AP, "连接AP");
  310. }
  311. break;
  312. case STEP_CONNECT_AP: // 连接AP
  313. result = esp32.connect_ap(WIFI_ID,WIFI_PASSWORD);
  314. if(result == Result_Success)
  315. {
  316. PCTRL_GotoStep(&pctrl, STEP_QUERY_SIGNAL, "查询WiFi信号强度");
  317. }
  318. else if(result == Result_Failed)
  319. {
  320. //连接AP失败时,信号值Rssi赋值
  321. signal.RSSI = -100;
  322. //连接AP失败时,下次数据发送重新选择信号最佳的AP
  323. select_ap_flag = 0;
  324. wifi_number = 0;
  325. Log_Printf_Debug("连接AP失败");
  326. PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置");
  327. }
  328. break;
  329. case STEP_QUERY_SIGNAL: //查询WiFi信号强度
  330. result = esp32.query_signal(&signal.RSSI);
  331. if(result == Result_Success)
  332. {
  333. PCTRL_GotoStep(&pctrl, STEP_SET_CIPMODE, "设置普通传输模式");
  334. }
  335. else if(result == Result_Failed)
  336. {
  337. Log_Printf_Debug("查询WiFi信号强度失败");
  338. PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置");
  339. }
  340. break;
  341. case STEP_SET_CIPMODE: //设置普通传输模式
  342. result = esp32.set_cipmode(0);
  343. if(result == Result_Success)
  344. {
  345. PCTRL_GotoStep(&pctrl, STEP_CLOSE_NETWORK, "关闭UDP网络");
  346. }
  347. else if(result == Result_Failed)
  348. {
  349. Log_Printf_Debug("设置传输模式失败");
  350. PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置");
  351. }
  352. break;
  353. case STEP_CLOSE_NETWORK: //关闭UDP网络
  354. result = esp32.close_network();
  355. if(result == Result_Success)
  356. {
  357. PCTRL_GotoStep(&pctrl, STEP_CONNECT_NETWORK, "连接UDP网络");
  358. }
  359. else if(result == Result_Failed)
  360. {
  361. Log_Printf_Debug("关闭UDP网络失败");
  362. PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置");
  363. }
  364. break;
  365. case STEP_CONNECT_NETWORK: //连接UDP网络
  366. result = esp32.connect_network("UDP", regist_response.remoteAddress,regist_response.remotePort);
  367. if(result == Result_Success)
  368. {
  369. PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "判断认证还是发送");
  370. }
  371. else if(result == Result_Failed)
  372. {
  373. Log_Printf_Debug("连接UDP网络失败");
  374. PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置");
  375. }
  376. break;
  377. case STEP_JUDGE_AUTH_OR_DATA: // 判断认证还是发送
  378. if(TUORENIOT_IsAuthentication() == 1) // 已认证
  379. {
  380. PCTRL_GotoStep(&pctrl, STEP_JOIN_DATA_MESSAGE, "拼接数据报文");
  381. }
  382. else
  383. {
  384. PCTRL_GotoStep(&pctrl, STEP_JOIN_AUTH_MESSAGE, "拼接认证报文");
  385. }
  386. break;
  387. case STEP_JOIN_AUTH_MESSAGE: // 拼接认证报文
  388. memset(coap_message, 0, sizeof(coap_message));
  389. TUORENIOT_PackAuthMessage(coap_message, &coap_message_length);
  390. // Log_Printf_Debug("认证报文:%d\r\n", coap_message_length);
  391. // Log_SendHex(coap_message, coap_message_length);
  392. // Log_Printf_Debug("\r\n");
  393. PCTRL_GotoStep(&pctrl, STEP_HANDLE, "发送认证报文");
  394. break;
  395. case STEP_JOIN_DATA_MESSAGE: // 拼接数据报文
  396. // 泵数据更新
  397. PUMPBUSINESS_ParamsRefresh();
  398. // 编码
  399. memset(data, 0, sizeof(data));
  400. PUMPDICTS_ProtocolEncode(&pump_params, data, &data_length);
  401. memset(coap_message, 0, sizeof(coap_message));
  402. TUORENIOT_PackDataMessage(data, data_length, coap_message, &coap_message_length);
  403. // Log_Printf_Debug("数据报文:%d\r\n", coap_message_length);
  404. // Log_SendHex(coap_message, coap_message_length);
  405. // Log_Printf_Debug("\r\n");
  406. PCTRL_GotoStep(&pctrl, STEP_HANDLE, "发送数据报文");
  407. break;
  408. case STEP_HANDLE:
  409. result = esp32.handle_data(coap_message,coap_message_length, &coap_message_length);
  410. if(result == Result_Success)
  411. {
  412. uint8_t res = TUORENIOT_AnalysisMessage(coap_message, coap_message_length);
  413. if(res == 0) // 发送失败
  414. {
  415. PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "重新认证"); // 重新认证
  416. }
  417. else if(res == 1) // 认证成功
  418. {
  419. PCTRL_GotoStep(&pctrl, STEP_JOIN_DATA_MESSAGE, "拼接数据报文");
  420. }
  421. else if(res == 2) // 发送成功
  422. {
  423. goto_success();
  424. }
  425. }
  426. else if(result == Result_Failed)
  427. {
  428. PCTRL_GotoStep(&pctrl, STEP_HANDLE, "重新发送数据");
  429. }
  430. break;
  431. case STEP_WAIT: // 等待
  432. PCTRL_Wait(&pctrl);
  433. break;
  434. case STEP_RESET: // 发送流程重置
  435. PCTRL_GotoStep(&pctrl, STEP_SET_MODE, "数据发送流程重置>>>>>>设置WiFi工作模式");
  436. break;
  437. case STEP_SUCCESS: // 成功
  438. PCTRL_GotoStep(&pctrl, STEP_ENTER_DEEP_SLEEP, "泵数据发送成功,进入深休眠");
  439. break;
  440. case STEP_FAILURE: // 失败
  441. goto_failure("数据发送流程失败");
  442. PCTRL_GotoStep(&pctrl, STEP_ENTER_DEEP_SLEEP, "泵数据发送失败,进入深休眠");
  443. break;
  444. case STEP_ENTER_DEEP_SLEEP:
  445. esp32.enter_deepsleep();
  446. Log_Printf_Debug("WiFi模块进入深休眠模式\r\n");
  447. goto_finish();
  448. break;
  449. case STEP_FINISH: // 流程结束
  450. break;
  451. default: goto_failure("步骤不存在");
  452. break;
  453. }
  454. }
  455. #endif