目录
HarmonyOS无线联网开发
AP及STA介绍参考:
WiFi AP热点
参考:
AP热点API介绍
wifi_device.h接口简介
接口名 |
功能描述 |
RegisterWifiEvent |
要注册回调的事件 |
此处介绍一个AP热点中用到的一个api,完整介绍参见下面的STA联网部分,源码在foundation\communication\interfaces\kits\wifi_lite\wifiservice\wifi_device.h
路径下
RegisterWifiEvent()
描述:
为指定的Wi-Fi事件注册回调函数。当WifiEvent中定义的Wi-Fi事件发生时,将调用已注册的回调函数
参数:
wifi_hotspot.h接口简介
这个wifi_hotspot.h中包含声明AP热点相关接口函数。
接口名 |
功能描述 |
EnableHotspot |
启用AP热点模式 |
DisableHotspot |
禁用AP热点模式 |
SetHotspotConfig |
设置指定的热点配置 |
GetHotspotConfig |
获取指定的热点配置 |
lsHotspotActive |
检查AP热点模式是否启用 |
GetStationList |
获取连接到该热点的一系列STA |
GetSignalLevel |
获取接收信号强度和频率 |
源码在foundation\communication\interfaces\kits\wifi_lite\wifiservice\wifi_hotspot.h
路径下
EnableHotspot()
描述:
启用Wifi热点模式
SetHotspotConfig()
描述:
设置指定的热点配置
IsHotspotActive()
描述:
检查AP热点模式是否启用
GetStationList()
描述:
获取连接到该热点的一系列STA
参数:
名字 |
描述 |
result |
表示连接到该热点的STA列表 |
size |
表示连接到该热点的STA数量 |
netifapi.h接口简介
源码在vendor\hisi\hi3861\hi3861\third_party\lwip_sack\include\lwip\netifapi.h
路径下
netifapi_netif_find()
参数:
描述:
获取netif用于IP操作
netifapi_netif_set_addr()
参数:
名字 |
描述 |
netif |
表示要更改的网络接口 |
ipaddr |
表示新的IP地址 |
netmask |
表示新的网络掩码 |
gw |
表示新的默认网关IP地址 |
描述:
用于更改网络接口(包括网络掩码和默认网关)的IP
netifapi_dhcps_start()
参数:
名字 |
描述 |
netif |
表示lwIP网络接口 |
start_ip |
表示DHCPv4地址池的起始ip地址 |
ip_num |
表示需要在池中的ip地址数 |
描述:
在netif上启动DHCPv4服务器。当需要在netif上启动DHCPv4服务器时,只应调用一次
AP热点创建代码解读
补充说明:之前在梅科尔工作室-#14天鸿蒙设备开发实战#环境搭建笔记-开源基础软件社区-51CTO.COM一文,在部署环境->简易步骤中的在Ubuntu上获取源码的两种方法中,一种是从华为hpm网站上下载源码,另一种是从gitee仓库中clone下来,两种方法前者的代码更新速度要比后者的代码更新速度慢,如果通过前者获取的源码没有找到相应的案例,可以在gitee仓库上查找,或者直接使用后者获取源码,通过git pull
命令从仓库中拉取代码进行更新。目前(2022.8.9)本文所需的案例两种方法获取的源码均有提供,因此继续使用第一种方法获取的源码进行开发(建议使用第二种方法,前面提到的那篇博文已进行补充)。
源码在applications\BearPi\BearPi-HM_Nano\sample\D1_iot_wifi_ap\wifi_ap.c
路径 下,以下添加了部分注释:
#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 "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)
{
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");
}
int sock_fd;
struct sockaddr_in server_sock;
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);
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;
}
}
}
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);
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
- 245.
- 246.
- 247.
- 248.
- 249.
- 250.
- 251.
修改applications\BearPi\BearPi-HM_Nano\sample
路径下的BUILD.gn文件,指定wifi_ap
,编译、烧录(与之前不同的是为了提高烧录速度,波特率设置2000000或3000000,设置大了可能不稳定但是能提高下载速度),之后打印日志
日志结果如下:

如果无法打印出站点信息,则需要将vendor\hisi\hi3861\hi3861_adapter\hals\communication\wifi_lite\wifiservice\source\wifi_hotspot.c
目录下的178行staNum的值改为WIFI_MAX_STA_NUM或者直接写6(原值是0),即unsigned int staNum = WIFI_MAX_STA_NUM;
,之后才能通过GetStationList打印出站点信息。 通过hpm官网下载的源码需要修改,通过gitee仓库下载的源码是已经修改过的。
WiFi STA联网
参考:
STA联网相关API介绍
wifi_device.h接口简介
这个wifi_device.h中包含声明STA联网相关接口函数。
接口名 |
功能描述 |
RegisterWifiEvent |
要注册回调的事件 |
EnableWifi |
启用Wifi STA模式 |
DisableWifi |
禁用Wifi STA模式 |
lsWifiActive |
检查Wifi STA模式是否启用 |
Scan |
扫描热点信息 |
GetScanInfoList |
获取所有扫描到的热点列表 |
AddDeviceConfig |
配置连接到热点信息 |
GetDeviceConfigs |
获取配置连接到热点信息 |
RemoveDevice |
删除指定的热点配置信息 |
ConnectTo |
连接到指定的热点 |
Disconnect |
断开Wifi连接 |
GetLinkedInfo |
获取热点连接信息 |
GetDeviceMacAddress |
获取设备的MAC地址 |
源码在foundation\communication\interfaces\kits\wifi_lite\wifiservice\wifi_device.h
路径下
RegisterWifiEvent()
描述:
为指定的Wi-Fi事件注册回调函数。当WifiEvent中定义的Wi-Fi事件发生时,将调用已注册的回调函数
参数:
EnableWifi()
描述:
启用STA模式
AddDeviceConfig()
描述:
添加用于配置连接到热点信息,此函数生成一个networkId
参数:
名字 |
描述 |
config |
表示要连接的热点信息. |
result |
表示生成的networkId。每个networkId匹配一个热点配置 |
ConnectTo()
描述:
连接到指定networkId的热点
参数:
名字 |
描述 |
networkId |
表示与目标热点匹配的网络id. |
dhcp.h接口简介
dhcp_start()
描述:
启动DHCP, 获取IP
STA联网代码解读
源码在applications\BearPi\BearPi-HM_Nano\sample\D2_iot_wifi_sta_connect\wifi_sta_connect.c
路径下,一下添加了部分注释:
修改applications\BearPi\BearPi-HM_Nano\sample
路径下的BUILD.gn文件,指定wifi_sta_connect
,编译、烧录(与之前不同的是为了提高烧录速度,波特率设置2000000或3000000,设置大了可能不稳定但是能提高下载速度),之后打印日志
日志结果如下:

本章学习中的两个案例源码见附件。
感悟
本章的学习内容较少,整体的难度也不是很大,但是对于其中涉及到的一些相关概念花了不少时间去理解,现在也是似懂非懂的,毕竟是零基础学习,基础概念是一大拦路虎,好在大多都能在网上找到相关解释,看来学习过程打牢基础是很有必要的。截至目前鸿蒙设备开发实战的学习还有最后两章,学习速度需要加快,继续加油!!!
跟着楼主文章走一遍看到了不少新的东西,感谢分享。
楼主是如何知道源码在哪的?
和案例同目录的BUILD.gn文件里面指定了所依赖的.h文件路径,可以从里面找一下