HarmonyOS新手入门设备开发的“芯”路历程
官方文帐中将鸿蒙小熊派开发板从采用的模组到芯片都介绍了一遍。开发板采用的芯片是Hi3861V100芯片。
Hi3861V100是一款高度集成的2.4GHz SoC WiFi芯片,集成IEEE 802.11b/g/n基带和RF电路,RF电路包括功率放大器PA、低 噪声放大器LNA、RF balun、天线开关以及电源管理等模块;支持20MHz标准带宽和5MHz/10MHz窄带宽,提供最大72.2Mbit/s 物理层速率。Hi3861V100 WiFi基带支持正交频分复用(OFDM)技术,并向下兼容直接序列扩频(DSSS)和补码键控(CCK)技术,支 持IEEE 802.11 b/g/n协议的各种数据速率。 Hi3861V100芯片集成高性能32bit微处理器、硬件安全引擎以及丰富的外设接口,外设接口包括SPI、UART、I2C、PWM、 GPIO和多路ADC,同时支持高速SDIO2.0 Slave接口,最高时钟可达50MHz;芯片内置SRAM和Flash,可独立运行,并支持 在Flash上运行程序。 Hi3861V100支持HUAWEI LiteOS和第三方组件,并配套提供开放、易用的开发和调试运行环境。 Hi3861V100芯片适应于智能家电等物联网智能终端领域。
更多的可以去官方社区账号专栏看。本文主要总结鸿蒙的wifi接口
Hi3861V100、Hi3861LV100 通过API(Application Programming Interface)面向开发者提供Wi-Fi功能的开发和应用接口,包括芯片初始化、资源配置、Station创建和配置、扫描、关联以及去关联、状态查询等一系列功能, 框架结构如图所示。
APP应用开发层:用户基于API接口的二次开发。
Example示例:SDK提供的功能开发示例。
API接口:提供基于SDK的通用接口。
LWIP协议栈:网络协议栈。
WPA SUPPLICANT(含HOSTAPD):Wi-Fi管理模块。
Wi-Fi驱动:802.11协议实现模块。
Platform平台:提供SoC系统板级支持包(包括:芯片和外围设备驱动、操作系统以及系统管理)
鸿蒙系统代码的API文件在如下路径:
foundation\communication\interfaces\kits\wifi_lite\wifiservice\wifi_device.h foundation\communication\interfaces\kits\wifi_lite\wifiservice\wifi_hotspot.h
1. RegisterWifiEvent()
WifiErrorCode RegisterWifiEvent (WifiEvent * event)
描述: 为指定的Wi-Fi事件注册回调函数。当WifiEvent中定义的Wi-Fi事件发生时,将调用已注册的回调函数
参数:
名字 | 描述 |
---|---|
event | 表示要注册回调的事件 |
2. EnableHotspot()
WifiErrorCode EnableHotspot (void )
描述: 启用Wifi热点模式
3. SetHotspotConfig()
WifiErrorCode SetHotspotConfig(const HotspotConfig* config)
描述: 设置指定的热点配置
4. IsHotspotActive()
int IsHotspotActive(void);
描述: 检查AP热点模式是否启用
5. GetStationList()
WifiErrorCode GetStationList(StationInfo* result, unsigned int* size)
描述: 获取连接到该热点的一系列STA
参数:
名字 | 描述 |
---|---|
result | 表示连接到该热点的STA列表 |
size | 表示连接到该热点的STA数量 |
6. EnableWifi()
WifiErrorCode EnableWifi (void )
描述: 启用STA模式
7. AddDeviceConfig()
WifiErrorCode AddDeviceConfig (const WifiDeviceConfig * config, int * result )
描述: 添加用于配置连接的热点信息,此函数生成一个networkId
参数:
名字 | 描述 |
---|---|
config | 表示要连接的热点信息 |
result | 表示生成的networkId。每个networkId匹配一个热点配置 |
8. ConnectTo()
WifiErrorCode ConnectTo (int networkId)
描述: 连接到指定networkId的热点
9. netifapi_netif_find()
struct netif *netifapi_netif_find(const char *name);
描述: 获取netif用于IP操作
10. dhcp_start()
err_t dhcp_start(n)
描述:启动DHCP, 获取IP
AP:无线接入点,是一个无线网络的创建者,是网络的中心节点。一般家庭或办公室使用的无线路由器就是一个AP。
STA站点:就是每一个连接到无线网络中的终端(如笔记本电脑、PDA及其它可以联网的用户设备)都可称为一个站点。
AP模式: Access Point,提供无线接入服务,允许其它无线设备接入,提供数据访问,一般的无线路由/网桥工作在该模式下。AP和AP之间允许相互连接。
在此模式下,手机、PAD、电脑等设备可以直接连上模块,可以很方便对用户设备进行控制。
Sta模式: Station, 类似于无线终端,sta本身并不接受无线的接入,它可以连接到AP,一般无线网卡即工作在该模式。
这是一种基本的组网方式,由一个AP和许多STA组成。其特点是AP处于中心地位,STA之间的相互通信都通过AP转发完成。该模式下,WIFI模块工作在STA(CLIENT)模式。通过适当的设置,COM的数据与WIFI的网路数据相互转换。
鸿蒙设备完成Wifi热点的扫描需要以下几步
RegisterWifiEvent
接口向系统注册热点状态改变事件、STA站点加入事件、STA站点退出事件OnHotspotStateChangedHandler
用于绑定热点状态改变事件,该回调函数有一个参数 state ;其中state表示是否开启AP模式,取值为0和1,0表示已启用Wifi AP模式,1表示已禁用Wifi AP模式;
OnHotspotStaLeaveHandler
用于绑定STA站点退出事件,当有STA站点退出,该回调函数会打印出退出站点的MAC地址;
OnHotspotStaJoinHandler
用于绑定STA站点加入事件,当有新的STA站点加入时,该回调函数会创建 HotspotStaJoinTask,在该任务中会调用 GetStationList 函数获取当前接入到该AP的所有STA站点信息,并打印出每个STA站点的MAC地址;
调用 SetHotspotConfig
接口,设置指定的热点配置;
调用 EnableHotspot
接口,使能 Wifi AP 模式;
调用 IsHotspotActive
接口,检查AP热点模式是否启用;
调用 netifapi_netif_set_addr
函数设置网卡信息;
调用 netifapi_dhcps_start
函数启动dhcp服务;
鸿蒙设备完成Wifi热点的连接需要以下几步
RegisterWifiEvent
接口向系统注册扫描状态监听函数,用于接收扫描状态通知,如扫描动作是否完成等OnWifiConnectionChangedHandler
用于绑定连接状态监听函数,该回调函数有两个参数 state 和 info ;state表示扫描状态,取值为0和1,1表示热点连接成功;info表示Wi-Fi连接信息,包含以下参数:名字 | 描述 |
---|---|
ssid [WIFI_MAX_SSID_LEN] | 连接的热点名称. |
bssid [WIFI_MAC_LEN] | MAC地址. |
rssi | 接收信号强度(RSSI). |
connState | Wifi连接状态. |
disconnectedReason | Wi-Fi断开的原因. |
EnableWifi
接口,使能 Wifi。AddDeviceConfig
接口,配置连接的热点信息。ConnectTo
接口,连接到指定networkId的热点。WaitConnectResult
接口等待,该函数中会有15s的时间去轮询连接成功标志位 g_ConnectSuccess
,当g_ConnectSuccess
为 1 时退出等待。netifapi_netif_find
接口,获取 netif 用于 IP 操作dhcp_start
接口,启动 DHCP, 获取 IP此模式下并不能联网,只是能够将终端连接到设备而已。如需联网应该采用AP+STA模式。
主任务函数
#define AP_SSID "BearPi"
#define AP_PSK "0987654321"
#define ONE_SECOND 1
#define DEF_TIMEOUT 15
static void OnHotspotStaJoinHandler(StationInfo *info);
static void OnHotspotStateChangedHandler(int state);
static void OnHotspotStaLeaveHandler(StationInfo *info);
static struct netif *g_lwip_netif = NULL;
static int g_apEnableSuccess = 0;
WifiEvent g_wifiEventHandler = {0};
WifiErrorCode error;
static BOOL WifiAPTask(void)
{
//延时2S便于查看日志
osDelay(200);
//注册wifi事件的回调函数
g_wifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoinHandler;
g_wifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeaveHandler;
g_wifiEventHandler.OnHotspotStateChanged = OnHotspotStateChangedHandler;
error = RegisterWifiEvent(&g_wifiEventHandler);
if (error != WIFI_SUCCESS)
{
printf("RegisterWifiEvent failed, error = %d.\r\n",error);
return -1;
}
printf("RegisterWifiEvent succeed!\r\n");
//设置指定的热点配置
HotspotConfig config = {0};
strcpy(config.ssid, AP_SSID);
strcpy(config.preSharedKey, AP_PSK);
config.securityType = WIFI_SEC_TYPE_PSK;
config.band = HOTSPOT_BAND_TYPE_2G;
config.channelNum = 7;
error = SetHotspotConfig(&config);
if (error != WIFI_SUCCESS)
{
printf("SetHotspotConfig failed, error = %d.\r\n", error);
return -1;
}
printf("SetHotspotConfig succeed!\r\n");
//启动wifi热点模式
error = EnableHotspot();
if (error != WIFI_SUCCESS)
{
printf("EnableHotspot failed, error = %d.\r\n", error);
return -1;
}
printf("EnableHotspot succeed!\r\n");
//检查热点模式是否使能
if (IsHotspotActive() == WIFI_HOTSPOT_NOT_ACTIVE)
{
printf("Wifi station is not actived.\r\n");
return -1;
}
printf("Wifi station is actived!\r\n");
//启动dhcp
g_lwip_netif = netifapi_netif_find("ap0");
if (g_lwip_netif)
{
ip4_addr_t bp_gw;
ip4_addr_t bp_ipaddr;
ip4_addr_t bp_netmask;
IP4_ADDR(&bp_gw, 192, 168, 1, 1); /* input your gateway for example: 192.168.1.1 */
IP4_ADDR(&bp_ipaddr, 192, 168, 1, 1); /* input your IP for example: 192.168.1.1 */
IP4_ADDR(&bp_netmask, 255, 255, 255, 0); /* input your netmask for example: 255.255.255.0 */
err_t ret = netifapi_netif_set_addr(g_lwip_netif, &bp_ipaddr, &bp_netmask, &bp_gw);
if(ret != ERR_OK)
{
printf("netifapi_netif_set_addr failed, error = %d.\r\n", ret);
return -1;
}
printf("netifapi_netif_set_addr succeed!\r\n");
ret = netifapi_dhcps_start(g_lwip_netif, 0, 0);
if(ret != ERR_OK)
{
printf("netifapi_dhcp_start failed, error = %d.\r\n", ret);
return -1;
}
printf("netifapi_dhcps_start succeed!\r\n");
}
/****************以下为UDP服务器代码***************/
//在sock_fd 进行监听
int sock_fd;
//服务端地址信息
struct sockaddr_in server_sock;
//创建socket
if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("socket is error.\r\n");
return -1;
}
bzero(&server_sock, sizeof(server_sock));
server_sock.sin_family = AF_INET;
server_sock.sin_addr.s_addr = htonl(INADDR_ANY);
server_sock.sin_port = htons(8888);
//调用bind函数绑定socket和地址
if (bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)) == -1)
{
perror("bind is error.\r\n");
return -1;
}
int ret;
char recvBuf[512] = {0};
//客户端地址信息
struct sockaddr_in client_addr;
int size_client_addr= sizeof(struct sockaddr_in);
while (1)
{
printf("Waiting to receive data...\r\n");
memset(recvBuf, 0, sizeof(recvBuf));
ret = recvfrom(sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr*)&client_addr,(socklen_t*)&size_client_addr);
if(ret < 0)
{
printf("UDP server receive failed!\r\n");
return -1;
}
printf("receive %d bytes of data from ipaddr = %s, port = %d.\r\n", ret, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
printf("data is %s\r\n",recvBuf);
ret = sendto(sock_fd, recvBuf, strlen(recvBuf), 0, (struct sockaddr *)&client_addr, sizeof(client_addr));
if (ret < 0)
{
printf("UDP server send failed!\r\n");
return -1;
}
}
/*********************END********************/
}
回调函数
课程上说是获取站点列表函数在回调函数中调用得不到结果,所以写了个任务函数在回调函数中调用。
static void HotspotStaJoinTask(void)
{
static char macAddress[32] = {0};
StationInfo stainfo[WIFI_MAX_STA_NUM] = {0};
StationInfo *sta_list_node = NULL;
unsigned int size = WIFI_MAX_STA_NUM;
error = GetStationList(stainfo, &size);
if (error != WIFI_SUCCESS) {
printf("HotspotStaJoin:get list fail, error is %d.\r\n", error);
return;
}
sta_list_node = stainfo;
for (uint32_t i = 0; i < size; i++, sta_list_node++) {
unsigned char* mac = sta_list_node->macAddress;
snprintf(macAddress, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
printf("HotspotSta[%d]: macAddress=%s.\r\n",i, macAddress);
}
g_apEnableSuccess++;
}
static void OnHotspotStaJoinHandler(StationInfo *info)
{
if (info == NULL) {
printf("HotspotStaJoin:info is null.\r\n");
}
else {
printf("New Sta Join\n");
osThreadAttr_t attr;
attr.name = "HotspotStaJoinTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 2048;
attr.priority = 24;
if (osThreadNew((osThreadFunc_t)HotspotStaJoinTask, NULL, &attr) == NULL) {
printf("HotspotStaJoin:create task fail!\r\n");
}
}
return;
}
static void OnHotspotStaLeaveHandler(StationInfo *info)
{
if (info == NULL) {
printf("HotspotStaLeave:info is null.\r\n");
}
else {
static char macAddress[32] = {0};
unsigned char* mac = info->macAddress;
snprintf(macAddress, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
printf("HotspotStaLeave: macAddress=%s, reason=%d.\r\n", macAddress, info->disconnectedReason);
g_apEnableSuccess--;
}
return;
}
static void OnHotspotStateChangedHandler(int state)
{
printf("HotspotStateChanged:state is %d.\r\n", state);
if (state == WIFI_HOTSPOT_ACTIVE) {
printf("wifi hotspot active.\r\n");
} else {
printf("wifi hotspot noactive.\r\n");
}
}
1.修改BUILD.gn
修改 applications\BearPi\BearPi-HM_Nano\sample
路径下 BUILD.gn 文件,指定 wifi_ap 参与编译。
2.编译
Linux终端或者MobaXterm的会话连接内,进入代码目录执行 python build.py BearPi-HM_Nano
进行编译。
3.烧录
使用HiBurn工具,波特率设置为2000000.
选择对应的com口和要烧录的文件,勾选auto burn。点击connect,再点开发板复位按键。进行烧录。
4.运行结果
通过MobaXterm的串口工具查看。用手机连一下试试。
此模式下设备能联网,但是不能够将终端连接到设备。如需联网应该采用AP+STA模式。
相关声明
#define DEF_TIMEOUT 15
#define ONE_SECOND 1
static void WiFiInit(void);
static void WaitSacnResult(void);
static int WaitConnectResult(void);
static void OnWifiScanStateChangedHandler(int state, int size);
static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info);
static void OnHotspotStaJoinHandler(StationInfo *info);
static void OnHotspotStateChangedHandler(int state);
static void OnHotspotStaLeaveHandler(StationInfo *info);
static int g_staScanSuccess = 0;
static int g_ConnectSuccess = 0;
static int ssid_count = 0;
WifiEvent g_wifiEventHandler = {0};
WifiErrorCode error;
#define SELECT_WLAN_PORT "wlan0"
#define SELECT_WIFI_SSID "your wifi ssid"//这里改成要连接的热点账号和对应密码
#define SELECT_WIFI_PASSWORD "your wifi password"
#define SELECT_WIFI_SECURITYTYPE WIFI_SEC_TYPE_PSK
主任务函数
static BOOL WifiSTATask(void)
{
WifiScanInfo *info = NULL;
unsigned int size = WIFI_SCAN_HOTSPOT_LIMIT;
static struct netif *g_lwip_netif = NULL;
WifiDeviceConfig select_ap_config = {0};
osDelay(200);
printf("<--System Init-->\r\n");
//初始化WIFI,将回调函数绑定写到这里了
WiFiInit();
//使能WIFI
if (EnableWifi() != WIFI_SUCCESS)
{
printf("EnableWifi failed, error = %d\n", error);
return -1;
}
//判断WIFI是否激活
if (IsWifiActive() == 0)
{
printf("Wifi station is not actived.\n");
return -1;
}
//分配空间,保存WiFi信息
info = malloc(sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT);
if (info == NULL)
{
return -1;
}
//轮询查找WiFi列表
do{
//重置标志位
ssid_count = 0;
g_staScanSuccess = 0;
//开始扫描
Scan();
//等待扫描结果
WaitSacnResult();
//获取扫描列表
error = GetScanInfoList(info, &size);
}while(g_staScanSuccess != 1);
//打印WiFi列表
printf("********************\r\n");
for(uint8_t i = 0; i < ssid_count; i++)
{
printf("no:%03d, ssid:%-30s, rssi:%5d\r\n", i+1, info[i].ssid, info[i].rssi/100);
}
printf("********************\r\n");
//连接指定的WiFi热点
for(uint8_t i = 0; i < ssid_count; i++)
{
if (strcmp(SELECT_WIFI_SSID, info[i].ssid) == 0)
{
int result;
printf("Select:%3d wireless, Waiting...\r\n", i+1);
//拷贝要连接的热点信息
strcpy(select_ap_config.ssid, info[i].ssid);
strcpy(select_ap_config.preSharedKey, SELECT_WIFI_PASSWORD);
select_ap_config.securityType = SELECT_WIFI_SECURITYTYPE;
if (AddDeviceConfig(&select_ap_config, &result) == WIFI_SUCCESS)
{
if (ConnectTo(result) == WIFI_SUCCESS && WaitConnectResult() == 1)
{
printf("WiFi connect succeed!\r\n");
g_lwip_netif = netifapi_netif_find(SELECT_WLAN_PORT);
break;
}
}
}
if(i == ssid_count-1)
{
printf("ERROR: No wifi as expected\r\n");
while(1) osDelay(100);
}
}
//启动DHCP
if (g_lwip_netif)
{
dhcp_start(g_lwip_netif);
printf("begain to dhcp");
}
//等待DHCP
for(;;)
{
if(dhcp_is_bound(g_lwip_netif) == ERR_OK)
{
printf("<-- DHCP state:OK -->\r\n");
//打印获取到的IP信息
netifapi_netif_common(g_lwip_netif, dhcp_clients_info_show, NULL);
break;
}
printf("<-- DHCP state:Inprogress -->\r\n");
osDelay(100);
}
//执行其他操作
for(;;)
{
osDelay(100);
}
}
回调函数
将回调函数的注册绑定写到了初始化函数里。
static void WiFiInit(void)
{
printf("<--Wifi Init-->\r\n");
g_wifiEventHandler.OnWifiScanStateChanged = OnWifiScanStateChangedHandler;
g_wifiEventHandler.OnWifiConnectionChanged = OnWifiConnectionChangedHandler;
g_wifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoinHandler;
g_wifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeaveHandler;
g_wifiEventHandler.OnHotspotStateChanged = OnHotspotStateChangedHandler;
error = RegisterWifiEvent(&g_wifiEventHandler);
if (error != WIFI_SUCCESS)
{
printf("register wifi event fail!\r\n");
}
else
{
printf("register wifi event succeed!\r\n");
}
}
static void OnWifiScanStateChangedHandler(int state, int size)
{
(void)state;
if (size > 0)
{
ssid_count = size;
g_staScanSuccess = 1;
}
return;
}
static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info)
{
(void)info;
if (state > 0)
{
g_ConnectSuccess = 1;
printf("callback function for wifi connect\r\n");
}
else
{
printf("connect error,please check password\r\n");
}
return;
}
static void OnHotspotStaJoinHandler(StationInfo *info)
{
(void)info;
printf("STA join AP\n");
return;
}
static void OnHotspotStaLeaveHandler(StationInfo *info)
{
(void)info;
printf("HotspotStaLeave:info is null.\n");
return;
}
static void OnHotspotStateChangedHandler(int state)
{
printf("HotspotStateChanged:state is %d.\n", state);
return;
}
static void WaitSacnResult(void)
{
int scanTimeout = DEF_TIMEOUT;
while (scanTimeout > 0)
{
sleep(ONE_SECOND);
scanTimeout--;
if (g_staScanSuccess == 1)
{
printf("WaitSacnResult:wait success[%d]s\n", (DEF_TIMEOUT - scanTimeout));
break;
}
}
if (scanTimeout <= 0)
{
printf("WaitSacnResult:timeout!\n");
}
}
static int WaitConnectResult(void)
{
int ConnectTimeout = DEF_TIMEOUT;
while (ConnectTimeout > 0)
{
sleep(1);
ConnectTimeout--;
if (g_ConnectSuccess == 1)
{
printf("WaitConnectResult:wait success[%d]s\n", (DEF_TIMEOUT - ConnectTimeout));
break;
}
}
if (ConnectTimeout <= 0)
{
printf("WaitConnectResult:timeout!\n");
return 0;
}
return 1;
}
1.修改BUILD.gn
修改 applications\BearPi\BearPi-HM_Nano\sample
路径下 BUILD.gn 文件,指定 wifi_sta_connect
参与编译。
2.编译
Linux终端或者MobaXterm的会话连接内,进入代码目录执行 python build.py BearPi-HM_Nano
进行编译。
3.烧录
使用HiBurn工具,波特率设置为2000000.
选择对应的com口和要烧录的文件,勾选auto burn。点击connect,再点开发板复位按键。进行烧录。
4.运行结果
通过MobaXterm的串口工具查看。
ready to OS start
sdk ver:Hi3861V100R001C00SPC025 2020-09-03 18:10:00
formatting spiffs...
FileSystem mount ok.
wifi init success!
00 00:00:00 0 196 D 0/HIVIEW: hilog init success.
00 00:00:00 0 196 D 0/HIVIEW: log limit init success.
00 00:00:00 0 196 I 1/SAMGR: Bootstrap core services(count:3).
00 00:00:00 0 196 I 1/SAMGR: Init service:0x4af9bc TaskPool:0xfa724
00 00:00:00 0 196 I 1/SAMGR: Init service:0x4af9e0 TaskPool:0xfad94
00 00:00:00 0 196 I 1/SAMGR: Init service:0x4afaf0 TaskPool:0xfaf54
00 00:00:00 0 228 I 1/SAMGR: Init service 0x4af9e0 <time: 0ms> success!
00 00:00:00 0 128 I 1/SAMGR: Init service 0x4af9bc <time: 0ms> success!
00 00:00:00 0 72 D 0/HIVIEW: hiview init success.
00 00:00:00 0 72 I 1/SAMGR: Init service 0x4afaf0 <time: 0ms> success!
00 00:00:00 0 72 I 1/SAMGR: Initialized all core system services!
00 00:00:00 0 128 I 1/SAMGR: Bootstrap system and application services(count:0).
00 00:00:00 0 128 I 1/SAMGR: Initialized all system and application services!
00 00:00:00 0 128 I 1/SAMGR: Bootstrap dynamic registered services(count:0).
<--System Init-->
<--Wifi Init-->
register wifi event succeed!
+NOTICE:SCANFINISH
WaitSacnResult:wait success[1]s
********************
no:001, ssid:HONOR 70 Pro , rssi: -48
no:002, ssid:FAST_3886 , rssi: -51
********************
Select: 1 wireless, Waiting...
+NOTICE:CONNECTED
callback function for wifi connect
WaitConnectResult:wait success[1]s
WiFi connect succeed!
begain to dhcp<-- DHCP state:Inprogress -->
<-- DHCP state:OK -->
server :
server_id : 192.168.244.147
mask : 255.255.255.0, 1
gw : 192.168.244.147
T0 : 3599
T1 : 1799
T2 : 3149
clients <1> :
mac_idx mac addr state lease tries rto
0 3c11317c4ad7 192.168.244.27 10 0 1 4