#include "CONFIG.h" #if ESP32 #include "stm32f10x.h" #include #include #include #include #include "UDP_Client.h" #include "Timer_Module.h" #include "Log_Module.h" #include "mbedtls_util.h" #include "cJSON.h" #include "esp32.h" #include "Pump_Dicts_Util.h" #include "Regist.h" #include "PumpBusiness.h" #include "Initialize.h" #include "Tuoreniot.h" //WiFi连接参数 char WIFI_ID[50]="tuoren"; char WIFI_PASSWORD[30]="123456789"; // 测试模式 uint8_t UDPCLIENT_TestModeFlag = 0; // coap报文 static uint8_t coap_message[512]; static uint16_t coap_message_length = 0; // 待发送数据的地址和长度 static uint8_t data[128]; static uint16_t data_length; // 信号值 static struct Signal { int RSRP; int RSRQ; int RSSI; int SINR; } signal = { .RSRP = 99, .RSRQ = 99, .RSSI = 99, .SINR = 99, }; // 查询信号质量 void UDPCLIENT_QuerySignal(int * RSRP, int * RSRQ, int * RSSI, int * SINR) { *RSRP = signal.RSRP; *RSRQ = signal.RSRQ; *RSSI = signal.RSSI; *SINR = signal.SINR; } // 函数声明 static void UDPCLIENT_Process(void); // 流程 static void UDPCLIENT_SetStatus(enum UDPCLIENT_StatusEnum status); // 设置状态 static void UDPCLIENT_SetResult(enum UDPCLIENT_ResultEnum result); // 设置结果 static void goto_start(void); // 开始 static void goto_success(void); // 成功 static void goto_failure(char * _info); // 失败 static void goto_finish(void); // 结束 /******************************************* 通信流程 *******************************************/ enum Step{ STEP_NONE, // 空闲状态,无操作 STEP_START, // 开始 STEP_READY, // 模块是否唤醒 STEP_EXIT_DEEP_SLEEP, // 退出深睡眠 STEP_ENTER_DEEP_SLEEP, // 进入深睡眠 STEP_WAIT, // 等待 STEP_SET_MODE, // 设置WIFI工作模式 STEP_SELECT_AP, // 选择AP STEP_CONNECT_AP, // 连接AP STEP_QUERY_SIGNAL, // 查询WiFi信号强度 STEP_SET_CIPMODE, // 设置传输模式 STEP_CONNECT_NETWORK, // 连接TCP/UDP网络 STEP_HANDLE, // 处理数据(数据发送+等待发送结果) STEP_JUDGE_AUTH_OR_DATA,// 判断认证还是发送 STEP_JOIN_AUTH_MESSAGE, // 拼接认证报文 STEP_JOIN_DATA_MESSAGE, // 拼接数据报文 STEP_CLOSE_AP, // 断开AP连接 STEP_CLOSE_NETWORK, // 断开TCP/UDP网络 STEP_RST, // 重启WiFi模块 STEP_RESET, // 数据发送流程重置 STEP_SUCCESS, // 成功 STEP_FAILURE, // 失败 STEP_FINISH, // 流程结束 }; // 步骤跳转时的监听 static uint8_t STEP_HANDLE_times = 0; // 数据重发的次数 static uint8_t STEP_RESET_times = 0; // 流程重置的次数 static void initialize() { STEP_HANDLE_times = 0; STEP_RESET_times = 0; } static uint16_t goto_step_event(uint16_t ns) { // 重置esp32状态 esp32.reset(); // 流程控制 uint16_t step = ns; if(step == STEP_HANDLE && STEP_HANDLE_times++ >= 2) { Log_Printf_Debug("数据重发次数过多"); step = STEP_RESET; } if(step == STEP_RESET ) { //流程重置时其他步骤计数变量置0 STEP_HANDLE_times = 0; //流程重置1次时退出 if(STEP_RESET_times++ >= 1) { goto_failure("流程重置次数过多"); step = STEP_FAILURE; } } return step; } // 流程控制 static struct PCTRL_Struct pctrl = { .current_step = STEP_FINISH, .next_step = STEP_FINISH, .step_wait = STEP_WAIT, .goto_step_listener = goto_step_event, }; // 备注 static char info[40]; // 开始 static void goto_start(void) { initialize(); PCTRL_GotoStep(&pctrl, STEP_START, "开始"); } // 成功 static void goto_success(void) { UDPCLIENT_SetResult(UDPCLIENT_Result_Success); PCTRL_GotoStep(&pctrl, STEP_SUCCESS, "成功"); } // 失败 static void goto_failure(char * _info) { UDPCLIENT_SetResult(UDPCLIENT_Result_Failure); memset(info, 0, sizeof(info)); strcpy(info, _info); PCTRL_GotoStep(&pctrl, STEP_FAILURE, "失败"); Log_Printf_Debug("info:%s!\r\n", info); } // 结束 static void goto_finish(void) { UDPCLIENT_SetStatus(UDPCLIENT_Status_Done); PCTRL_GotoStep(&pctrl, STEP_FINISH, "结束"); } // 状态 static enum UDPCLIENT_StatusEnum udpclient_status = UDPCLIENT_Status_None; // 结果 static enum UDPCLIENT_ResultEnum udpclient_result = UDPCLIENT_Result_None; // 设置状态 static void UDPCLIENT_SetStatus(enum UDPCLIENT_StatusEnum status) { udpclient_status = status; } // 获取状态 enum UDPCLIENT_StatusEnum UDPCLIENT_GetStatus(void) { return udpclient_status; } // 设置结果 static void UDPCLIENT_SetResult(enum UDPCLIENT_ResultEnum result) { udpclient_result = result; } // 获取结果 enum UDPCLIENT_ResultEnum UDPCLIENT_GetResult(void) { return udpclient_result; } // 重置 enum EXECUTE_ResultEnum UDPCLIENT_Reset(void) { if(UDPCLIENT_GetStatus() == UDPCLIENT_Status_Being) { Log_Printf_Debug("发送流程重置错误!\r\n"); return EXECUTE_Result_Failure; } UDPCLIENT_SetStatus(UDPCLIENT_Status_None); UDPCLIENT_SetResult(UDPCLIENT_Result_None); return EXECUTE_Result_Success; } // 开始 enum EXECUTE_ResultEnum UDPCLIENT_Start(void) { UDPCLIENT_Reset(); if(UDPCLIENT_GetStatus() != UDPCLIENT_Status_None) { Log_Printf_Debug("发送流程启动错误!\r\n"); return EXECUTE_Result_Failure; } goto_start(); UDPCLIENT_SetStatus(UDPCLIENT_Status_Being); return EXECUTE_Result_Success; } // 流程处理,放到大循环里 void UDPCLIENT_ProcessHandle(void) { if(UDPCLIENT_GetStatus() == UDPCLIENT_Status_Being) { UDPCLIENT_Process(); } } // 发送数据的逻辑 int wifi_rssi[10]; // 各wifi信号值存储数组 static int wifi_number = 0; // wifi信息编号变量 static int wifi_location=0; // 最佳wifi信号在数组中的位置 static int select_ap_flag = 0; // 选择AP标志位 0:未选择 1:已选择 static enum Result result = Result_None; //获取最佳wifi_rssi中最佳信号位置 int get_BestWifiSignal(int* rssi, int number) { int signal=0; //假设首个wifi信号最好 int value=-99; //初始化比较值 for(int i=0; i value) && (rssi[i] != 0)) { value = rssi[i]; signal = i; } } return signal; } static void UDPCLIENT_Process(void) { switch(pctrl.current_step) { case STEP_NONE: break; // 空闲 case STEP_START: // 开始 PCTRL_GotoStep(&pctrl, STEP_EXIT_DEEP_SLEEP, "退出深休眠"); break; case STEP_EXIT_DEEP_SLEEP: // 退出深休眠 esp32.exit_deepsleep(); PCTRL_GotoStepWait(&pctrl, STEP_READY,5, "判断模块是否启动"); break; case STEP_READY: // 判断模块是否启动 result = esp32.recv_ready_with_time(5000); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_SET_MODE, "设置WiFi为Station工作模式"); } else if(result == Result_Failed) { Log_Printf_Debug("WiFi模块启动失败"); PCTRL_GotoStep(&pctrl, STEP_RST, "重启WiFi模块"); } break; case STEP_RST: result = esp32.rst(); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_SET_MODE, "设置WiFi为Station工作模式"); } else if(result == Result_Failed) { goto_failure("重启WiFi模块失败"); } break; case STEP_SET_MODE: // 设置WiFi为Station模式 result = esp32.set_mode(1); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_SELECT_AP, "选择AP"); } else if(result == Result_Failed) { Log_Printf_Debug("设置工作模式失败"); PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置"); } break; case STEP_SELECT_AP: if(select_ap_flag == 0) { if(wifi_number < regist_response.wifiNumber) { result = esp32.query_id_signal(regist_response.wifi[wifi_number].wifiName, &wifi_rssi[wifi_number]); if(result == Result_Success ||result == Result_Failed) { // Log_Printf_Debug("wifi%d的信号值RSSI=%d\r\n",wifi_number,wifi_rssi[wifi_number]); // Log_Printf_Debug("wifi_number=%d\r\n",wifi_number); wifi_number++; PCTRL_GotoStep(&pctrl, STEP_SELECT_AP, "继续选择AP"); } } else { //获取信号最佳的wifi在数组中的位置 wifi_location=get_BestWifiSignal(wifi_rssi, wifi_number); //拷贝wifi信息 strcpy(WIFI_ID,regist_response.wifi[wifi_location].wifiName); strcpy(WIFI_PASSWORD,regist_response.wifi[wifi_location].wifiPassword); //选择AP标志位置1 select_ap_flag =1; Log_Printf_Debug("选择信号最好的第%d组wifi\r\n",wifi_location); Log_Printf_Debug("WIFI_ID=%s\r\n",WIFI_ID); Log_Printf_Debug("WIFI_PASSWORD=%s\r\n",WIFI_PASSWORD); PCTRL_GotoStep(&pctrl, STEP_CONNECT_AP, "连接AP"); } } else { PCTRL_GotoStep(&pctrl, STEP_CONNECT_AP, "连接AP"); } break; case STEP_CONNECT_AP: // 连接AP result = esp32.connect_ap(WIFI_ID,WIFI_PASSWORD); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_QUERY_SIGNAL, "查询WiFi信号强度"); } else if(result == Result_Failed) { //连接AP失败时,信号值Rssi赋值 signal.RSSI = -100; //连接AP失败时,下次数据发送重新选择信号最佳的AP select_ap_flag = 0; wifi_number = 0; Log_Printf_Debug("连接AP失败"); PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置"); } break; case STEP_QUERY_SIGNAL: //查询WiFi信号强度 result = esp32.query_signal(&signal.RSSI); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_SET_CIPMODE, "设置普通传输模式"); } else if(result == Result_Failed) { Log_Printf_Debug("查询WiFi信号强度失败"); PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置"); } break; case STEP_SET_CIPMODE: //设置普通传输模式 result = esp32.set_cipmode(0); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_CLOSE_NETWORK, "关闭UDP网络"); } else if(result == Result_Failed) { Log_Printf_Debug("设置传输模式失败"); PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置"); } break; case STEP_CLOSE_NETWORK: //关闭UDP网络 result = esp32.close_network(); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_CONNECT_NETWORK, "连接UDP网络"); } else if(result == Result_Failed) { Log_Printf_Debug("关闭UDP网络失败"); PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置"); } break; case STEP_CONNECT_NETWORK: //连接UDP网络 result = esp32.connect_network("UDP", regist_response.remoteAddress,regist_response.remotePort); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "判断认证还是发送"); } else if(result == Result_Failed) { Log_Printf_Debug("连接UDP网络失败"); PCTRL_GotoStep(&pctrl, STEP_RESET, "流程重置"); } break; case STEP_JUDGE_AUTH_OR_DATA: // 判断认证还是发送 if(TUORENIOT_IsAuthentication() == 1) // 已认证 { PCTRL_GotoStep(&pctrl, STEP_JOIN_DATA_MESSAGE, "拼接数据报文"); } else { PCTRL_GotoStep(&pctrl, STEP_JOIN_AUTH_MESSAGE, "拼接认证报文"); } break; case STEP_JOIN_AUTH_MESSAGE: // 拼接认证报文 memset(coap_message, 0, sizeof(coap_message)); TUORENIOT_PackAuthMessage(coap_message, &coap_message_length); // Log_Printf_Debug("认证报文:%d\r\n", coap_message_length); // Log_SendHex(coap_message, coap_message_length); // Log_Printf_Debug("\r\n"); PCTRL_GotoStep(&pctrl, STEP_HANDLE, "发送认证报文"); break; case STEP_JOIN_DATA_MESSAGE: // 拼接数据报文 // 泵数据更新 PUMPBUSINESS_ParamsRefresh(); // 编码 memset(data, 0, sizeof(data)); PUMPDICTS_ProtocolEncode(&pump_params, data, &data_length); memset(coap_message, 0, sizeof(coap_message)); TUORENIOT_PackDataMessage(data, data_length, coap_message, &coap_message_length); // Log_Printf_Debug("数据报文:%d\r\n", coap_message_length); // Log_SendHex(coap_message, coap_message_length); // Log_Printf_Debug("\r\n"); PCTRL_GotoStep(&pctrl, STEP_HANDLE, "发送数据报文"); break; case STEP_HANDLE: result = esp32.handle_data(coap_message,coap_message_length, &coap_message_length); if(result == Result_Success) { uint8_t res = TUORENIOT_AnalysisMessage(coap_message, coap_message_length); if(res == 0) // 发送失败 { PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "重新认证"); // 重新认证 } else if(res == 1) // 认证成功 { PCTRL_GotoStep(&pctrl, STEP_JOIN_DATA_MESSAGE, "拼接数据报文"); } else if(res == 2) // 发送成功 { goto_success(); } } else if(result == Result_Failed) { PCTRL_GotoStep(&pctrl, STEP_HANDLE, "重新发送数据"); } break; case STEP_WAIT: // 等待 PCTRL_Wait(&pctrl); break; case STEP_RESET: // 发送流程重置 PCTRL_GotoStep(&pctrl, STEP_SET_MODE, "数据发送流程重置>>>>>>设置WiFi工作模式"); break; case STEP_SUCCESS: // 成功 PCTRL_GotoStep(&pctrl, STEP_ENTER_DEEP_SLEEP, "泵数据发送成功,进入深休眠"); break; case STEP_FAILURE: // 失败 goto_failure("数据发送流程失败"); PCTRL_GotoStep(&pctrl, STEP_ENTER_DEEP_SLEEP, "泵数据发送失败,进入深休眠"); break; case STEP_ENTER_DEEP_SLEEP: esp32.enter_deepsleep(); Log_Printf_Debug("WiFi模块进入深休眠模式\r\n"); goto_finish(); break; case STEP_FINISH: // 流程结束 break; default: goto_failure("步骤不存在"); break; } } #endif