429 lines
10 KiB
C
429 lines
10 KiB
C
#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);
|
|
}
|