一、简介
二、API说明
以下 AP热点 接口位于 foundation\communication\interfaces\kits\wifi_lite\wifiservice\wifi_hotspot.h。
业务BUILD.gn中包含路径
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/interfaces/kits/wifiiot_lite",
"//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
"//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
]
2.1 EnableHotspot
功能 | 启用Wifi热点模式 |
---|
函数定义 | WifiErrorCode EnableHotspot(void) | 参数 | 无 | 返回 | 错误码 |
2.2 DisableHotspot
功能 | 禁用Wifi热点模式 |
---|
函数定义 | WifiErrorCode DisableHotspot(void) | 参数 | 无 | 返回 | 错误码 |
2.3 SetHotspotConfig
功能 | 设置指定的热点配置 |
---|
函数定义 | WifiErrorCode SetHotspotConfig(const HotspotConfig* config) | 参数 | config:热点配置参数 | 返回 | 错误码 |
2.4 GetHotspotConfig
功能 | 获取指定的热点配置 |
---|
函数定义 | WifiErrorCode GetHotspotConfig(HotspotConfig* result) | 参数 | result:获取指定的热点配置结果 | 返回 | 错误码 |
2.5 IsHotspotActive
功能 | 检查AP热点模式是否启用 |
---|
函数定义 | int IsHotspotActive(void) | 参数 | 无 | 返回 | WIFI_HOTSPOT_ACTIVE - 已启用;WIFI_HOTSPOT_NOT_ACTIVE - 未启用 |
2.6 GetStationList
功能 | 获取连接到该热点的一系列STA |
---|
函数定义 | WifiErrorCode GetStationList(StationInfo* result, unsigned int* size) | 参数 | result:表示连接到该热点的STA列表 size:表示连接到该热点的STA数量 | 返回 | 错误码 |
2.7 GetSignalLevel
功能 | 获取接收信号强度和频率 |
---|
函数定义 | int GetSignalLevel(int rssi, int band) | 参数 | rssi:信号强度 band:频率,HOTSPOT_BAND_TYPE_5G或HOTSPOT_BAND_TYPE_2G | 返回 | 获取到的信号水平 |
以下 STA联网 接口位于 foundation\communication\interfaces\kits\wifi_lite\wifiservice\wifi_device.h。
业务BUILD.gn中包含路径
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/interfaces/kits/wifiiot_lite",
"//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
"//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
]
2.8 RegisterWifiEvent
功能 | 为指定的Wi-Fi事件注册回调函数。当WifiEvent中定义的Wi-Fi事件发生时,将调用已注册的回调函数 |
---|
函数定义 | WifiErrorCode RegisterWifiEvent(WifiEvent* event) | 参数 | event:表示要注册回调的事件 | 返回 | 错误码 |
2.9 EnableWifi
功能 | 启用STA模式 |
---|
函数定义 | WifiErrorCode EnableWifi(void) | 参数 | 无 | 返回 | 错误码 |
2.10 DisableWifi
功能 | 禁用STA模式 |
---|
函数定义 | WifiErrorCode DisableWifi(void) | 参数 | 无 | 返回 | 错误码 |
2.11 IsWifiActive
功能 | 检查Wifi STA模式是否启用 |
---|
函数定义 | int IsWifiActive(void) | 参数 | 无 | 返回 | WIFI_STA_ACTIVE - 已启用;WIFI_STA_NOT_ACTIVE - 未启用 |
2.12 Scan
功能 | 开启扫描热点信息 |
---|
函数定义 | WifiErrorCode Scan(void) | 参数 | 无 | 返回 | 错误码 |
2.13 GetScanInfoList
功能 | 获取所有扫描到的热点列表 |
---|
函数定义 | WifiErrorCode GetScanInfoList(WifiScanInfo* result, unsigned int* size) | 参数 | result:被扫描到的热点数组 size:热点数组大小 | 返回 | 错误码 |
2.14 AddDeviceConfig
功能 | 配置连接到热点信息 |
---|
函数定义 | WifiErrorCode AddDeviceConfig(const WifiDeviceConfig* config, int* result) | 参数 | config:表示要连接的热点信息 result:表示生成的networkId。每个networkId匹配一个热点配置 | 返回 | 错误码 |
2.15 ConnectTo
功能 | 接到指定的热点 |
---|
函数定义 | WifiErrorCode ConnectTo(int networkId) | 参数 | networkId:表示与目标热点匹配的网络id | 返回 | 错误码 |
2.16 Disconnect
功能 | 断开Wifi连接 |
---|
函数定义 | WifiErrorCode Disconnect(void) | 参数 | 无 | 返回 | 错误码 |
2.17 GetLinkedInfo
功能 | 断开Wifi连接 |
---|
函数定义 | WifiErrorCode GetLinkedInfo(WifiLinkedInfo* result) | 参数 | result:表示目前连接中的热点信息 | 返回 | 错误码 |
2.18 GetDeviceMacAddress
功能 | 获取设备的MAC地址 |
---|
函数定义 | WifiErrorCode GetDeviceMacAddress(unsigned char* result) | 参数 | result:设备的MAC地址,6字节长度数组 | 返回 | 错误码 |
以下 LwIP 接口位于 vendor\hisi\hi3861\hi3861\third_party\lwip_sack\include\lwip/netifapi.h 和 vendor\hisi\hi3861\hi3861\third_party\lwip_sack\include\lwip/dhcp.h。
业务BUILD.gn中包含路径
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/interfaces/kits/wifiiot_lite",
"//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
"//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
]
2.19 netifapi_netif_find
功能 | 获取网络接口用于IP操作 |
---|
函数定义 | struct netif *netifapi_netif_find(const char *name) | 参数 | name:网络接口名称 | 返回 | 错误码 |
2.20 netifapi_netif_set_addr
功能 | 设置SoftAp的DHCP服务器的IP地址、子网掩码和网关参数 |
---|
函数定义 | err_t netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw) | 参数 | netif:被改变的网络接口 ipaddr:新的IP地址 netmask:新的子网掩码 gw:新的网关地址 | 返回 | 错误码 |
2.21 netifapi_dhcps_start
功能 | 启动SoftAp的DHCP服务器 |
---|
函数定义 | err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num) | 参数 | netif:LwIP网络接口 start_ip:DHCP起始地址 ip_num:IP池数量 | 返回 | 错误码 |
2.22 netifapi_netif_common
功能 | 用于以线程安全的方式调用所有与netif相关的API |
---|
函数定义 | err_t netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, netifapi_errt_fn errtfunc) | 参数 | netif:LwIP网络接口 voidfunc:如果errtfunc为NULL,将调用返回类型为void的回调 errtfunc:返回类型为err_t的回调 | 返回 | 错误码 |
2.23 dhcp_start
功能 | 启动DHCP, 获取IP |
---|
函数定义 | err_t dhcp_start(struct netif *netif) | 参数 | netif:LwIP网络接口 | 返回 | 错误码 |
三、AP模式
3.1 初始化Wi-Fi事件处理
3.1.1 注册wifi事件的回调函数
通过 RegisterWifiEvent 接口向系统注册热点状态改变事件、STA站点加入事件、STA站点退出事件
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");
3.1.2 终端设备加入
定义成功加入AP热点的终端设备数量 g_apEnableSuccess
static int g_apEnableSuccess = 0;
实现 OnHotspotStaJoinHandler() 终端设备加入处理函数。
用于绑定STA站点加入事件,当有新的STA站点加入时,该回调函数会创建 HotspotStaJoinTask ,在该任务中会调用 GetStationList 函数获取当前接入到该AP的所有STA站点信息,并打印出每个STA站点的MAC地址;
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;
}
实现 HotspotStaJoinTask() 终端设备加入处理任务
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++;
}
3.1.3 终端设备离开
实现 OnHotspotStaLeaveHandler() 终端设备离开处理函数。
用于绑定STA站点退出事件,当有STA站点退出,该回调函数会打印出退出站点的MAC地址。
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;
}
3.1.4 AP热点状态改变
实现 OnHotspotStateChangedHandler() AP热点状态改变处理函数。
用于绑定热点状态改变事件,该回调函数有一个参数 state ;
- state表示是否开启AP模式,取值为0和1,0表示已启用Wifi AP模式,1表示已禁用Wifi AP模式;
- 当已启用Wifi AP模式,该回调函数会将标志位
g_apEnableSuccess 置 1;
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");
}
}
3.2 Wi-Fi配置阶段
调用 SetHotspotConfig 接口,设置指定的热点配置。
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");
3.3 Wi-Fi启动阶段
调用 EnableHotspot 接口,使能 Wifi AP 模式。 调用 IsHotspotActive 接口,检查AP热点模式是否启用。
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");
3.4 LwIP初始阶段
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);
IP4_ADDR(&bp_ipaddr, 192, 168, 1, 1);
IP4_ADDR(&bp_netmask, 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");
}
3.5 完整代码
编译时在业务BUILD.gn中包含路径
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/interfaces/kits/wifiiot_lite",
"//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
"//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
]
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "cmsis_os2.h"
#include "ohos_init.h"
#include "wifi_device.h"
#include "wifi_hotspot.h"
#include "wifi_error_code.h"
#include "lwip/netifapi.h"
#define AP_SSID "BearPi"
#define AP_PSK "12345678"
#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)
{
osDelay(200);
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");
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");
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);
IP4_ADDR(&bp_ipaddr, 192, 168, 1, 1);
IP4_ADDR(&bp_netmask, 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");
}
while (1)
{
osDelay(1000);
}
}
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");
}
}
static void Wifi_AP_Demo(void)
{
osThreadAttr_t attr;
attr.name = "WifiAPTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 10240;
attr.priority = 25;
if (osThreadNew((osThreadFunc_t)WifiAPTask, NULL, &attr) == NULL)
{
printf("Falied to create WifiAPTask!\r\n");
}
}
APP_FEATURE_INIT(Wifi_AP_Demo);
3.6 查看打印
使用手机连接
四、STA模式
4.1 初始化Wi-Fi事件处理
4.1.1 注册wifi事件的回调函数
通过 RegisterWifiEvent 接口向系统注册扫描状态监听函数,用于接收扫描状态通知,如扫描动作是否完成等
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");
}
4.1.2 绑定连接状态监听
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断开的原因. |
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;
}
4.2 Wi-Fi启动阶段
调用 EnableWifi 接口,使能 Wifi。 调用 AddDeviceConfig 接口,配置连接的热点信息。
if (EnableWifi() != WIFI_SUCCESS)
{
printf("EnableWifi failed, error = %d\n", error);
return -1;
}
if (IsWifiActive() == 0)
{
printf("Wifi station is not actived.\n");
return -1;
}
4.3 Wi-Fi连接阶段
调用 ConnectTo 接口,连接到指定networkId的热点。 调用 WaitConnectResult 接口等待,该函数中会有15s的时间去轮询连接成功标志位 g_ConnectSuccess ,当 g_ConnectSuccess 为 1 时退出等待。
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);
}
}
4.4 Wi-Fi“Got IP”阶段
调用 netifapi_netif_find 接口,获取 netif 用于 IP 操作 调用 dhcp_start 接口,启动 DHCP, 获取 IP
if (g_lwip_netif)
{
dhcp_start(g_lwip_netif);
printf("begain to dhcp");
}
for(;;)
{
if(dhcp_is_bound(g_lwip_netif) == ERR_OK)
{
printf("<-- DHCP state:OK -->\r\n");
netifapi_netif_common(g_lwip_netif, dhcp_clients_info_show, NULL);
break;
}
printf("<-- DHCP state:Inprogress -->\r\n");
osDelay(100);
}
4.5 完整代码
编译时在业务BUILD.gn中包含路径
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/interfaces/kits/wifiiot_lite",
"//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
"//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
]
修改 SELECT_WIFI_SSID 和 SELECT_WIFI_PASSWORD 成要连接的WIFI名和密码。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/ip4_addr.h"
#include "lwip/api_shell.h"
#include "cmsis_os2.h"
#include "hos_types.h"
#include "wifi_device.h"
#include "wifiiot_errno.h"
#include "ohos_init.h"
#define DEF_TIMEOUT 15
static void WiFiInit(void);
static int WaitConnectResult(void);
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_ConnectSuccess = 0;
WifiEvent g_wifiEventHandler = {0};
WifiErrorCode error;
#define SELECT_WLAN_PORT "wlan0"
#define SELECT_WIFI_SSID "406"
#define SELECT_WIFI_PASSWORD "82069909"
#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");
WiFiInit();
if (EnableWifi() != WIFI_SUCCESS)
{
printf("EnableWifi failed, error = %d\n", error);
return -1;
}
if (IsWifiActive() == 0)
{
printf("Wifi station is not actived.\n");
return -1;
}
int result;
strcpy(select_ap_config.ssid, SELECT_WIFI_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);
}
}
if (g_lwip_netif)
{
dhcp_start(g_lwip_netif);
printf("begain to dhcp");
}
for(;;)
{
if(dhcp_is_bound(g_lwip_netif) == ERR_OK)
{
printf("<-- DHCP state:OK -->\r\n");
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.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 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 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;
}
static void WifiClientSTA(void)
{
osThreadAttr_t attr;
attr.name = "WifiSTATask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 10240;
attr.priority = 24;
if (osThreadNew((osThreadFunc_t)WifiSTATask, NULL, &attr) == NULL)
{
printf("Falied to create WifiSTATask!\n");
}
}
APP_FEATURE_INIT(WifiClientSTA);
4.6 查看打印:
五、扫描
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/ip4_addr.h"
#include "lwip/api_shell.h"
#include "cmsis_os2.h"
#include "hos_types.h"
#include "wifi_device.h"
#include "wifiiot_errno.h"
#include "ohos_init.h"
#define DEF_TIMEOUT 15
#define ONE_SECOND 1
static void WiFiInit(void);
static void WaitSacnResult(void);
static void OnWifiScanStateChangedHandler(int state, int size);
static int g_staScanSuccess = 0;
static int ssid_count = 0;
WifiEvent g_wifiEventHandler = {0};
WifiErrorCode error;
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");
WiFiInit();
if (EnableWifi() != WIFI_SUCCESS)
{
printf("EnableWifi failed, error = %d\n", error);
return -1;
}
if (IsWifiActive() == 0)
{
printf("Wifi station is not actived.\n");
return -1;
}
info = malloc(sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT);
if (info == NULL)
{
return -1;
}
while(1)
{
do{
ssid_count = 0;
g_staScanSuccess = 0;
Scan();
WaitSacnResult();
error = GetScanInfoList(info, &size);
}while(g_staScanSuccess != 1);
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");
memset(info, 0, (sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT));
osDelay(1000);
}
}
static void WiFiInit(void)
{
printf("<--Wifi Init-->\r\n");
g_wifiEventHandler.OnWifiScanStateChanged = OnWifiScanStateChangedHandler;
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 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 void WifiClientSTA(void)
{
osThreadAttr_t attr;
attr.name = "WifiSTATask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 10240;
attr.priority = 24;
if (osThreadNew((osThreadFunc_t)WifiSTATask, NULL, &attr) == NULL)
{
printf("Falied to create WifiSTATask!\n");
}
}
APP_FEATURE_INIT(WifiClientSTA);
查看打印:
? 由 Leung 写于 2021 年 12 月 14 日
? 参考:【鸿蒙2.0设备开发教程】小熊派HarmonyOS 鸿蒙·季 开发教程
|