#include "esp_common.h" #include "user_config.h" #include "apps/sntp.h" #include "uart.h" #include "cfg.h" #include "log.h" #include "soft_ap.h" #include "c_types.h" #include "lwip/sockets.h" #include "s2j.h" #include "jsprase.h" #include "protocol.h" #include "user_main.h" #include "ota.h" static int g_SockFd = -1; static struct sockaddr_in g_Recvaddr; static int g_isSoftAPFinish = TRUE; static int g_isCfgAPOK = FALSE; static struct station_config config; static uint8 ap_test_flag; static uint8 ap_test_time; int SoftAPBaseDecode(const char* pBaseCode, unsigned char* pDecode, int* pDecSize) { int ret = 0; if(pBaseCode == NULL || strlen(pBaseCode) == 0) { LOG_EX(LOG_Error, "Input %p Error pBaseCode\n", pBaseCode); return -ERR_INPUT_PARAMS; } if(pDecode == NULL) { LOG_EX(LOG_Error, "Input %p Error pBaseCode\n", pDecode); return -ERR_INPUT_PARAMS; } if(pDecSize == NULL) { LOG_EX(LOG_Error, "Input %p Error pBaseCode\n", pDecSize); return -ERR_INPUT_PARAMS; } ret = mbedtls_base64_decode(pDecode, *pDecSize, pDecSize, pBaseCode, strlen(pBaseCode)); if(ret != 0) { LOG_EX(LOG_Error, "Base64 Decode [%s] error: %d\n", pBaseCode, ret); return ret; } return 0; } static void __softap_rsp_status(CLOUND_API_CMD cmdId, int err) { int ret; CLOUND_API api; char* pReq; memset(&api, 0, sizeof(CLOUND_API)); api.cmdId = CLOUND_API_CMD_RSP_BASE + cmdId; api.ver = PROTOCOL_VERSION; api.cryptoType = 0; api.timeStamp = time(NULL); if(err != ERR_OK) { CLOUND_API_RSP_ERR rspErr; rspErr.errNo = err < 0 ? -err : err; rspErr.errMsg = (char*)SysGetErrName(rspErr.errNo); api.msgContent = (char*)Struct2Json(&rspErr, JE_RSP_STATUS, CRYPTO_NONE, &ret); if(ret != ERR_OK || api.msgContent == NULL) { LOG_EX(LOG_Error, "Create Rsponse Error %p: %d\n", api.msgContent, ret); return; } } pReq = (char*)Struct2Json(&api, JE_PROMAIN, CRYPTO_NONE, &ret); if(ret != ERR_OK || pReq == NULL) { LOG_EX(LOG_Error, "Create Rsponse Error %p: %d\n", pReq, ret); } LOG_EX(LOG_Debug, "Send Response: %s\n", pReq); SoftAPSendRspMsg(pReq); if(api.msgContent) { free(api.msgContent); } free(pReq); } static void __test_wifi_event_cb(System_Event_t *evt) { if (evt == NULL) { return; } switch (evt->event_id) { case EVENT_STAMODE_CONNECTED: { g_isCfgAPOK = TRUE; LOG_EX(LOG_Debug, "[connect to ssid %s, channel %d]\r\n", evt->event_info.connected.ssid, evt->event_info.connected.channel); __softap_rsp_status(CONFIG_AP, ERR_OK); wifi_set_event_handler_cb(NULL); ne_save_ssid_psk(config.ssid, config.password); HAL_CleanupDeviceSecret(); ne_cfg_set_init_type(NE_DEVICE_NORMAL); SoftAPExitCfgMode(2); #if DEVICE_YANXUAN_SWEEPER yanxuan_sweeper_connect_rsp(1); // connect network success notic mcu #else #endif vTaskDelay(1000 / portTICK_RATE_MS); system_restart(); break; } case EVENT_STAMODE_DISCONNECTED: { ap_test_flag = 0; ap_test_time++; wifi_station_disconnect(); if(ap_test_time >= 10){ g_isCfgAPOK = FALSE; __softap_rsp_status(CONFIG_AP, HalWifiCodeToUser(evt->event_info.disconnected.reason)); #if DEVICE_YANXUAN_SWEEPER yanxuan_sweeper_connect_rsp(0); // connect network fail notic mcu #endif } LOG_EX(LOG_Debug, "disconnect from ssid %s, reason %s(%d) time(%d)\n", evt->event_info.disconnected.ssid, SysGetWIFIError(HalWifiCodeToUser(evt->event_info.disconnected.reason)), evt->event_info.disconnected.reason, ap_test_time); break; } default: return; } } void soft_ap_start_test(PCFG_AP_INFO pApInfo) { int i = 0; uint32 timeout = ne_os_ticks_ms(xTaskGetTickCount()); g_isCfgAPOK = FALSE; while((ne_os_ticks_ms(xTaskGetTickCount()) - timeout < 30*1000) && (g_isCfgAPOK == FALSE) && (ap_test_time < 10)){ if(!ap_test_flag){ if(i++ % 2 != 0 && pApInfo->gbkssid && strlen(pApInfo->gbkssid) > 0) { LOG_EX(LOG_Debug, "Test GBK Encode: [%s] (%s)\n", pApInfo->gbkssid, pApInfo->gbkpasswd); SoftAPTestConnect(pApInfo->gbkssid, pApInfo->gbkpasswd, pApInfo->bssid); } else { LOG_EX(LOG_Debug, "Test UTF-8 Encoding\n"); SoftAPTestConnect(pApInfo->ssid, pApInfo->passwd, pApInfo->bssid); } } vTaskDelay(100 / portTICK_RATE_MS); } ap_test_flag = 0; ap_test_time = 0; } void SoftAPTestConnect(const char* pSSID, const char* pPasswd, const char* pBssid) { int len = 32; ap_test_flag = 1; bzero(&config, sizeof(struct station_config)); SoftAPBaseDecode(pSSID, config.ssid, &len); if(pPasswd && strlen(pPasswd) > 0) { len = 64; SoftAPBaseDecode(pPasswd, config.password, &len); } if(pBssid && strlen(pBssid) > 0) { len = 6; config.bssid_set = 1; SoftAPBaseDecode(pBssid, config.bssid, &len); } wifi_station_set_config(&config); wifi_set_event_handler_cb(__test_wifi_event_cb); LOG_EX(LOG_Debug, "WIFI Conect: AP = [%s], Password = [%s]\n", pSSID, pPasswd); IHW_LOG_BUF(LOG_Debug, "AP", config.ssid, strlen(config.ssid)); IHW_LOG_BUF(LOG_Debug, "PD", config.password, strlen(config.password)); IHW_LOG_BUF(LOG_Debug, "BD", config.bssid, 6); wifi_station_connect(); } int SoftAPSendRspMsg(char* pMsg) { int ret = sendto(g_SockFd, pMsg, strlen(pMsg), 0, (struct sockaddr *)&g_Recvaddr, sizeof(struct sockaddr_in)); if(ret == strlen(pMsg)) { return ERR_OK; } else { LOG_EX(LOG_Error, "Wish %d but send result: %d\n", strlen(pMsg), ret); return -ERR_SEND_MESSAGE; } } int SoftAPDecodeCfgApMsg(PCFG_AP_INFO pApInfo) { unsigned char ssid[33]; unsigned char password[65]; int outLen = 0; if(pApInfo == NULL) { LOG_EX(LOG_Error, "Input %p Error\n", pApInfo); return -ERR_INPUT_PARAMS; } if(pApInfo->ssid == NULL || strlen(pApInfo->ssid) == 0) { LOG_EX(LOG_Error, "Input SSID[%s] Error\n", pApInfo->ssid ? pApInfo->ssid : "NULL"); return -ERR_INPUT_PARAMS; } memset(ssid, 0, 33); memset(password, 0, 65); mbedtls_base64_decode(ssid, 32, &outLen, pApInfo->ssid, strlen(pApInfo->ssid)); if(pApInfo->passwd) { mbedtls_base64_decode(password, 64, &outLen, pApInfo->passwd, strlen(pApInfo->passwd)); free(pApInfo->passwd); } free(pApInfo->ssid); pApInfo->ssid = strdup(ssid); pApInfo->passwd = strdup(password); if(pApInfo->gbkssid != NULL && strlen(pApInfo->gbkssid) > 0) { memset(ssid, 0, 33); memset(password, 0, 65); mbedtls_base64_decode(ssid, 32, &outLen, pApInfo->gbkssid, strlen(pApInfo->gbkssid)); if(pApInfo->gbkpasswd) { mbedtls_base64_decode(password, 64, &outLen, pApInfo->gbkpasswd, strlen(pApInfo->gbkpasswd)); free(pApInfo->gbkpasswd); } free(pApInfo->gbkssid); pApInfo->gbkssid = strdup(ssid); pApInfo->gbkpasswd = strdup(password); } return ERR_OK; } void __create_udp_server(void) { int ret = 1; struct sockaddr_in addr; unsigned char* pRecBuf = (char*)malloc(512); if(pRecBuf == NULL) { LOG_EX(LOG_Error, "Malloc SoftAP Memory Error\n"); vTaskDelete(NULL); return; } g_SockFd = socket(AF_INET, SOCK_DGRAM, 0); if(g_SockFd == -1) { LOG_EX(LOG_Error, "Create UDP socket error\n"); free(pRecBuf); vTaskDelete(NULL); return; } setsockopt(g_SockFd, SOL_SOCKET, SO_REUSEADDR, &ret, sizeof(ret)); memset(&addr, 0, sizeof(addr)); addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(USR_CFG_SOFTAP(UDPSvrPort)); addr.sin_family = AF_INET; ret = bind(g_SockFd, (struct sockaddr*)&addr, sizeof(addr)); if(ret != 0) { LOG_EX(LOG_Error, "Bind UDP port error: %d\n", ret); free(pRecBuf); close(g_SockFd); vTaskDelete(NULL); return; } ap_test_time = 0; ap_test_flag = 0; g_isSoftAPFinish = FALSE; while(!g_isSoftAPFinish) { int addrlen = sizeof(addr); int nRcvBytes = 0; memset(pRecBuf, 0, 512); nRcvBytes = recvfrom(g_SockFd, pRecBuf, 512, MSG_DONTWAIT, (struct sockaddr*)&g_Recvaddr, (socklen_t*)&addrlen); if(nRcvBytes > 0) { //LOG_EX(LOG_Debug, "Recv: %s\n", recBuf); //ret = __softap_pro_decode(recBuf); LOG_EX(LOG_Debug, "Receive JSON:\n%s\n", pRecBuf); ret = ProtocolProcess(pRecBuf); } //vTaskDelay(100); } free(pRecBuf); vTaskDelete(NULL); } static void __soft_ap_server(void* pvParams) { soft_ap_init(); vTaskDelete(NULL); } static void __soft_ap_protocol(void* pParams) { __create_udp_server(); vTaskDelete(NULL); } void SoftAPEnterCfgMode(void) { if(g_isSoftAPFinish) { xTaskCreate(__soft_ap_server, "soft_ap_server", 256, NULL, 1, NULL); xTaskCreate(__soft_ap_protocol, "soft_ap_protocol", 512, NULL, 1, NULL); } } static int g_isExistRun = FALSE; static void __soft_ap_exit(void* pParams) { int delay = (int)pParams; LOG_EX(LOG_Debug, "Wait %d seconds to exit SoftAP mode\n", delay); if(g_isCfgAPOK) { while(delay--) { vTaskDelay(1000 / portTICK_RATE_MS); if(g_isExistRun == FALSE) { LOG_EX(LOG_Debug, "SoftAP mode exited\n"); vTaskDelete(NULL); return; } } wifi_connect_ap(NULL, 0, NULL, 0); LOG_EX(LOG_Debug, "SoftAP mode exited\n"); } g_isSoftAPFinish = TRUE; vTaskDelete(NULL); } void SoftAPExitCfgMode(int delaySecs) { if(g_isExistRun) { g_isExistRun = FALSE; return; } if(!g_isSoftAPFinish) { g_isExistRun = TRUE; xTaskCreate(__soft_ap_exit, "soft_ap_exit", 256, (void*)delaySecs, 1, NULL); } } int IsSoftAPMode(void) { return (g_isSoftAPFinish != TRUE); }