一、优缺点分析
- 一键配网比起传统AP配网技术,简化了连接操作与连接步骤,操作更加简单和加快了连接速度。
- 很多路由器不支持UDP广播功能,例如wifi放大器、或者一些默认关闭UDP广播的路由器,会导致发广播包失败,导致WIFI设备无法获取到广播包。
- 当5G和2.4G同频的时候,如果当前手机连接的是5G频段,那发出来的广播包是5G的,而目前所有WIFI设备都只支持2.4G,导致无法获取广播包。
- 就算经历千辛万险获取到路由器名字和密码,很多路由器由于不支持局域网通讯(例如路由器的访客网络)
- 当前环境下面有几个路由器名字都是一样的,导致手机和WIFI设备不是连接在同一个路由器下面,都会导致wifi设备广播的MAC地址无法被手机APP获取到,进而导致绑定失败
二、代码分析
Smartconfig 接口位于 ESP8266_NONOS_SDK/include/smartconfig.h。
Step 1) 包含头文件
#include "wb_protocol.h"
#include "ip_addr.h"
#include "smartconfig.h"
#include "user_smartconfig.h"
#include "user_esp_platform.h"
#include "mscp_wifi.h"
Step 2) 相关定义
static os_timer_t s_smartConfigCheckIpTimer;
static os_timer_t s_tcpPingTimer;
static os_timer_t s_tcpLongTimeTimer;
const uint16 SMART_CONFIG_CHEAK_IP_TIMER = 15000;
const uint16 SMART_PLATFORM_PING_PERIOD = 30000;
const uint16 SMART_PLATFORM_LONG_TIME_PERIOD = 60000;
Step 3) 初始化函数
void ICACHE_FLASH_ATTR
SmartConfig(void)
{
//获取WIFI默认SSID和密码
wifi_station_get_config_default(&s_softap);
//WIFI配置
wifi_station_set_config(&s_softap);
wifi_station_disconnect();
wifi_station_connect();
//进入自动识别是否接入网络
startSmartConfigCheckIpTimer();
}
Step 4) 相关回调函数
/**
@brief 开始进入自动识别是否接入网络
@param 无
@return 无
*/
static void ICACHE_FLASH_ATTR
startSmartConfigCheckIpTimer(void)
{
os_timer_disarm(&s_smartConfigCheckIpTimer);
os_timer_setfn(&s_smartConfigCheckIpTimer, (os_timer_func_t *) SmartConfigCheckIpTimerCallback, NULL);
os_timer_arm(&s_smartConfigCheckIpTimer, SMART_CONFIG_CHEAK_IP_TIMER, true);
}
/**
@brief 停止进入自动识别是否接入网络
@param 无
@return 无
*/
static void ICACHE_FLASH_ATTR
stopSmartConfigCheckIpTimer(void)
{
os_timer_disarm(&s_smartConfigCheckIpTimer);
}
/**
@brief 进入自动识别是否接入网络
@param resetFlag -[in] 重启标志
@return 无
*/
static void ICACHE_FLASH_ATTR
SmartConfigCheckIpTimerCallback(void)
{
static uint8 connect_status = 0;
if(wifi_station_get_connect_status() == STATION_GOT_IP)
{
//连接上次路由器成功
connect_status = 0;
wifi_set_opmode_current(STATIONAP_MODE);// 设置为 STA+AP模式
}
else
{
//连接上次路由器失败
if(connect_status == 0)
{
connect_status = 1;
//进入Smartconfig
user_smartConfig_start();
os_printf("\n ========================================================== \n ");
os_printf(" Err : Reason, unable to connect to router ! \n \n");
os_printf(" wifi ssid : %s \n", s_softap.ssid);
os_printf(" wifi password : %s \n", s_softap.password);
os_printf(" ========================================================== \n ");
}
}
}
Step 5) Smartconfig函数
/**
@brief 一键配网切换到AP配网的定时器的回调函数
@param resetFlag -[in] 重启标志
@return 无
*/
static void ICACHE_FLASH_ATTR
user_smartConfig_start(void)
{
smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS);
wifi_set_opmode(STATION_MODE);
smartconfig_start(smartconfig_done);
os_printf("\n smartconfig_start(smartconfig_done); \n");
}
void ICACHE_FLASH_ATTR
smartconfig_done(sc_status status, void *pdata)
{
switch (status) {
//连接未开始,请勿在此阶段开始连接
case SC_STATUS_WAIT:
os_printf("SC_STATUS_WAIT\n");
break;
//发现信道
case SC_STATUS_FIND_CHANNEL:
os_printf("SC_STATUS_FIND_CHANNEL\n");
//开启长时间未连接重新进入Smartconfig
startSendLongTimeTimer();
break;
//得到wifi名字和密码
case SC_STATUS_GETTING_SSID_PSWD:
os_printf("SC_STATUS_GETTING_SSID_PSWD\n");
sc_type *type = pdata;
if (*type == SC_TYPE_ESPTOUCH) {
os_printf("SC_TYPE:SC_TYPE_ESPTOUCH\n");
} else {
os_printf("SC_TYPE:SC_TYPE_AIRKISS\n");
}
//关闭长时间未连接重新进入Smartconfig
stopSendLongTimeTimer();
break;
case SC_STATUS_LINK:
os_printf("SC_STATUS_LINK\n");
struct station_config *sta_conf = pdata;
s_softap = *sta_conf;
wifi_station_set_config(sta_conf);
wifi_station_disconnect();
wifi_station_connect();
//开启超时定时器
startSendPingTimer();
break;
//成功获取到IP,连接路由完成。
case SC_STATUS_LINK_OVER:
os_printf("SC_STATUS_LINK_OVER \n\n");
if (pdata != NULL) {
uint8 phone_ip[4] = { 0 };
os_memcpy(phone_ip, (uint8*) pdata, 4);
os_printf("Phone ip: %d.%d.%d.%d\n", phone_ip[0], phone_ip[1], phone_ip[2], phone_ip[3]);
}
//停止超时定时器
stopSendPingTimer();
//停止配置
smartconfig_stop();
//切换WIFI模式
wifi_set_opmode(STATIONAP_MODE);
break;
default:
os_printf("\n ========================================================== \n ");
os_printf("\n Err: Smartconfig mode failed !! \n");
os_printf("\n ========================================================== \n ");
startSendPingTimer();
break;
}
}
Step 6) 连接超时回调函数
/**
@brief 开始发送PING的定时器
@param 无
@return 无
*/
static void ICACHE_FLASH_ATTR
startSendPingTimer(void)
{
os_timer_disarm(&s_tcpPingTimer);
os_timer_setfn(&s_tcpPingTimer, (os_timer_func_t *) sendPingTimerCallback, NULL);
os_timer_arm(&s_tcpPingTimer, SMART_PLATFORM_PING_PERIOD, false);
}
/**
@brief 停止发送PING的定时器
@param 无
@return 无
*/
static void ICACHE_FLASH_ATTR
stopSendPingTimer(void)
{
os_timer_disarm(&s_tcpPingTimer);
}
/**
@brief 发送PING定时器的回调函数
@param 无
@return 无
*/
static void ICACHE_FLASH_ATTR
sendPingTimerCallback(void)
{
//停止配置
smartconfig_stop();
user_smartConfig_start();
os_printf("\n ========================================================== \n ");
os_printf("\n Err: Smartconfig Connect Timeout !! ");
os_printf("\n ========================================================== \n ");
}
• 由 ChiKong_Tam 写于 2020 年 7 月 23 日
• 参考:【ESP8266】NONOS_第2篇:一键配网smartconfig原理及应用
• 参考:设备配网技术之AirKiss微信配网_fengfeng0328的博客-CS…_CSDN博客