鸿蒙Hi3861学习十四-Huawei LiteOS-M(AP模式)

一、简介

        参看上一章:鸿蒙Hi3861学习十四-Huawei LiteOS-M(STA模式)_t_guest的博客-CSDN博客

二、API介绍

      RegisterWifiEvent

        函数功能:

        为指定的WIFI事件注册回调函数。当WIFIEVENT中定义的WIFI事件发生时,将调用已注册的回调函数。

        函数原型:

WifiErrorCode RegisterWifiEvent(WifiEvent* event)

        参数:

        event:相关事件,结构体为WifiEvent。

typedef struct {
    /** Connection state change */
    void (*OnWifiConnectionChanged)(int state, WifiLinkedInfo* info);
    /** Scan state change */
    void (*OnWifiScanStateChanged)(int state, int size);
    /** Hotspot state change */
    void (*OnHotspotStateChanged)(int state);
    /** Station connected */
    void (*OnHotspotStaJoin)(StationInfo* info);
    /** Station disconnected */
    void (*OnHotspotStaLeave)(StationInfo* info);
} WifiEvent;

         OnWifiConnectionChanged:网络连接状态改变回调。与STA有关。具体含义见上一章。

        OnWifiScanStateChanged:扫描结果回调。与STA有关。具体含义见上一章。

        OnHotspotStateChanged:热点状态改变回调,即热点创建时的回调与AP有关。state热点状态。WIFI_HOTSPOT_ACTIVE(1)热点已创建成功。WIFI_HOTSPOT_NOT_ACTIVE(0)热点已关闭。

        OnHotspotStaJoin有STA连接回调与AP有关。info为连接上的STA相关信息。

typedef struct {
    /** MAC address. For its length, see {@link WIFI_MAC_LEN}. */
    unsigned char macAddress[WIFI_MAC_LEN];
    unsigned short disconnectedReason;
} StationInfo;

         macAddress:MAC地址

        disconnectedReason:断连原因

        OnHotspotStaLeaveSTA断开连接的回调,与AP有关。indo为连接上的STA相关信息。

        返回值:

        WIFI_SUCCESS:成功

        其他值:失败

        实例:

    WifiEvent g_wifiEventHandler = {0};

    //注册wifi事件的回调函数
    g_wifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoinHandler;  //STA连接的回调
    g_wifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeaveHandler;    //STA断开连接的回调
    g_wifiEventHandler.OnHotspotStateChanged = OnHotspotStateChangedHandler;    //热点状态改变的回调
    error = RegisterWifiEvent(&g_wifiEventHandler); //注册任务

     SetHotspotConfig

        函数功能:

        设置指定的热点配置

        函数原型:

WifiErrorCode SetHotspotConfig(const HotspotConfig* config)

        参数:

        config:热点配置参数。结构体类型为:HotspotConfig

typedef struct {
    /** Service set ID (SSID). For its length, see {@link WIFI_MAX_SSID_LEN}. */
    char ssid[WIFI_MAX_SSID_LEN];
    /** Security type */
    int securityType;
    /** Frequency band */
    int band;
    /** Channel number */
    int channelNum;
    /** Key. For its length, see {@link WIFI_MAX_SSID_LEN}. */
    char preSharedKey[WIFI_MAX_KEY_LEN];
} HotspotConfig;

         ssid:热点名

        securityType:加密类型,具体如下:

typedef enum {
    /** Invalid security type */
    WIFI_SEC_TYPE_INVALID = -1,
    /** Open */
    WIFI_SEC_TYPE_OPEN,
    /** Wired Equivalent Privacy (WEP) */
    WIFI_SEC_TYPE_WEP,
    /** Pre-shared key (PSK) */
    WIFI_SEC_TYPE_PSK,
    /** Simultaneous Authentication of Equals (SAE) */
    WIFI_SEC_TYPE_SAE,
} WifiSecurityType;

         band:带宽。2.4G还是5G

        channelNum:通道号

        preSharedKey:加密密钥。可不填。

        返回值:

        WIFI_SUCCESS:成功

        其他值:失败

        实例:

    WifiErrorCode error;
    HotspotConfig config = {0};

    strcpy(config.ssid, "Harmony_test_ap");   //设置SSID
    strcpy(config.preSharedKey, "0987654321");    //设置密码
    config.securityType = WIFI_SEC_TYPE_PSK;    //加密类型
    config.band = HOTSPOT_BAND_TYPE_2G; //频率类型
    config.channelNum = 7;  //信道

    error = SetHotspotConfig(&config);  //配置热点

      EnableHotspot

        函数功能:

        启用WIFI热点模式

        函数原型:

WifiErrorCode EnableHotspot(void)

        参数:

        无

        返回值:

        WIFI_SUCCESS:成功

        其他值:失败

        实例:

WifiErrorCode error;
error = EnableHotspot();    //使能热点

      IsHotspotActive

        函数功能:

        检查AP热点模式是否启用

        函数原型:

int IsHotspotActive(void)

        参数:

        无

        返回值:

#define WIFI_HOTSPOT_NOT_ACTIVE 0
#define WIFI_HOTSPOT_ACTIVE 1

        其他值:失败

        实例:

 if (IsHotspotActive() == WIFI_HOTSPOT_NOT_ACTIVE)
{}

      netifapi_netif_find

        函数功能:

        获取网络接口用于IP操作

        函数原型:

struct netif *netifapi_netif_find(const char *name);

        参数:

        name:网络接口名称。STA为“wlan0”AP为“ap0”。为什么是这俩,还没搞清楚。搞清楚后会回来补充。

        返回值:

        NULL:失败

        其他值:网络接口值。netif:LwIP网络接口

        实例:

struct netif *g_lwip_netif = NULL;
g_lwip_netif = netifapi_netif_find("ap0");  //获取网络借口,用于IP操作

      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:网络接口。netifapi_netif_find获得。

        ipaddr:自身IP地址

        netmask:子网掩码

        gw:网关IP

        返回值:

        ERR_OK:成功

        其他值:失败

        实例:

struct netif *g_lwip_netif = NULL;
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); //设置IP

      netifapi_dhcps_start

        函数功能:

        启动SoftAp的DHCP服务器

        函数原型:

err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num)

        参数:

        netif:网络接口。netifapi_netif_find获得。

        start_ip:DHCP起始地址,默认0,自动分配

        ip_num:IP池数量,默认0,自动分配

        返回值:

        ERR_OK:成功

        其他值:失败

        实例:


struct netif *g_lwip_netif = NULL;
err_t ret = netifapi_dhcps_start(g_lwip_netif, 0, 0); //启动DHCP

      GetStationList

        函数功能:

        获取连接到该热点的一系列STA信息。注:该函数不能在OnHotspotStaJoin回调中使用

        函数原型:

WifiErrorCode GetStationList(StationInfo* result, unsigned int* size)

        参数:

        result:输出值,STA信息列表。

        size:输出值,列表中STA的数量

        返回值:

        WIFI_SUCCESS:成功

        其他值:失败

        实例:

StationInfo stainfo[WIFI_MAX_STA_NUM] = {0};
unsigned int size = 0;

error = GetStationList(stainfo, &size);

三、实例

        这里创建一个名为“Harmony_test_ap”的热点,供STA连接。

        在BUILD.gn中添加如下代码:

include_dirs = [
        "//utild/native/lite/include",
        "//base/iot_hardware/interfaces/kits/wifiiot_lite",
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
        "//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
        "src",
    ]
#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 LOG_I(fmt, args...)   printf("<%8ld> - [AP]:"fmt"\r\n",osKernelGetTickCount(),##args);
#define LOG_E(fmt, args...)   printf("<%8ld>-[AP_ERR]>>>>>>>>>>>>:"fmt"\r\n",osKernelGetTickCount(), ##args);

#define AP_SSID "Harmony_test_ap"
#define AP_PSK  "123123123"

#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;
WifiEvent g_wifiEventHandler = {0};
WifiErrorCode error;

/*STA加入的任务*/
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)
    {
        LOG_E("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]);
        LOG_I("HotspotSta[%d]: macAddress=%s.\r\n", i, macAddress);
    }
}

/*STA连接的回调*/
static void OnHotspotStaJoinHandler(StationInfo *info)
{
    if (info == NULL)
    {
        LOG_E("HotspotStaJoin:info is null.\r\n");
    }
    else
    {
        LOG_I("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)
        {
            LOG_E("HotspotStaJoin:create task fail!\r\n");
        }
    }
    return;
}

/*STA断开连接的回调*/
static void OnHotspotStaLeaveHandler(StationInfo *info)
{
    if (info == NULL) {
        LOG_E("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]);
        LOG_I("HotspotStaLeave: macAddress=%s, reason=%d.\r\n", macAddress, info->disconnectedReason);
    }
    return;
}

/*热点状态改变的回调*/
static void OnHotspotStateChangedHandler(int state)
{
    LOG_I("HotspotStateChanged:state is %d.\r\n", state);
    if (state == WIFI_HOTSPOT_ACTIVE) {
        LOG_I("wifi hotspot active.\r\n");
    } else {
        LOG_I("wifi hotspot noactive.\r\n");
    }
}

/*WIFI AP 任务*/
static BOOL WifiAPTask(void)
{
    //延时2S便于查看日志
    osDelay(200);

    //注册wifi事件的回调函数
    g_wifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoinHandler;  //STA连接的回调
    g_wifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeaveHandler;    //STA断开连接的回调
    g_wifiEventHandler.OnHotspotStateChanged = OnHotspotStateChangedHandler;    //热点状态改变的回调
    error = RegisterWifiEvent(&g_wifiEventHandler); //注册任务
    if (error != WIFI_SUCCESS)
    {
        LOG_E("RegisterWifiEvent failed, error = %d.\r\n",error);
        return -1;
    }
    LOG_I("RegisterWifiEvent succeed!\r\n");
    //设置指定的热点配置
    HotspotConfig config = {0};

    strcpy(config.ssid, AP_SSID);   //设置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)
    {
        LOG_E("SetHotspotConfig failed, error = %d.\r\n", error);
        return -1;
    }
    LOG_I("SetHotspotConfig succeed!\r\n");

    //启动wifi热点模式
    error = EnableHotspot();    //使能热点
    if (error != WIFI_SUCCESS)
    {
        LOG_E("EnableHotspot failed, error = %d.\r\n", error);
        return -1;
    }
    LOG_I("EnableHotspot succeed!\r\n");

    //检查热点模式是否使能
    if (IsHotspotActive() == WIFI_HOTSPOT_NOT_ACTIVE)
    {
        LOG_E("Wifi station is not actived.\r\n");
        return -1;
    }
    LOG_I("Wifi station is actived!\r\n");

    //启动dhcp
    g_lwip_netif = netifapi_netif_find("ap0");  //获取网络借口,用于IP操作
    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); //设置IP
        if(ret != ERR_OK)
        {
            LOG_E("netifapi_netif_set_addr failed, error = %d.\r\n", ret);
            return -1;
        }
        LOG_I("netifapi_netif_set_addr succeed!\r\n");

        ret = netifapi_dhcps_start(g_lwip_netif, 0, 0); //启动DHCP
        if(ret != ERR_OK)
        { 
            LOG_E("netifapi_dhcp_start failed, error = %d.\r\n", ret);
            return -1;
        }
        LOG_I("netifapi_dhcps_start succeed!\r\n");

    }

    while(1)
    {
        osDelay(100);
    }
    return 0;
}

/*AP任务创建*/
void drv_ap_task_init(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)
    {
        LOG_E("Falied to create WifiAPTask!\r\n");
    }
}

        看结果:

         这里是用手机连接的,看一下手机界面的相关属性。

         可以看到,IP地址、MAC地址、加密类型、频率都与在程序里设置的相同。

猜你喜欢

转载自blog.csdn.net/qq_26226375/article/details/130615854
今日推荐