esp8266-std/soft_ap/softap_protocol.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);
}