【FFH】OpenHarmony 设备开发(一)-WIFI连接 原创 精华

X丶昕雪
发布于 2022-9-1 23:48
浏览
3收藏

WIFI

wifi在我们的日常开发中必不可少,想要开发鸿蒙小车联网操作,想要使开发板不再局限于终端串口操作,更离不开wifi,本篇文章将详细介绍hi3861的wifi开发步骤及介绍.

本文主要介绍如何令hi3861开机自动连接wifi

代码介绍

第一步先在applications\sample\wifi-iot\下路径创建WIFI_demo业务代码文件夹,在文件夹内创建业务代码和BUILD.gn编译脚本.
【FFH】OpenHarmony 设备开发(一)-WIFI连接-鸿蒙开发者社区

业务代码中的头文件引用

hi_wifi_api.h和netifapi.h保存了一些wifi的API接口,ip_addr.h则是存放了wifi需使用到的一些宏定义.
ohos_init.h和cmsis_os2.h是应用初始化和线程创建必不可少的头文件,当我们使用到线程和SYS_RUN()都要包括这两个头文件.

#include <unistd.h>
#include "hi_wifi_api.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"
#include "ohos_init.h"
#include "cmsis_os2.h"

编译脚本代码

编译脚本将目标名为Xu_WIFI.c打包成名为Xu_WIFI_demo的静态库,随后在app路径下的BUILD.gn调用该库,调用格式为"业务代码文件夹名:静态库名".
include_dirs为头文件的存放地址,我们在使用ubuntu开发时,遇到不知道存放路径的头文件或者宏定义时,可以使用指令grep 头文件名 -* nR find . -name 头文件名进行搜索
业务代码文件夹内的BUILD.gn代码:

static_library("Xu_WIFI_demo") {
    sources = [
        "Xu_WIFI.c"
    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//base/iot_hardware/peripheral/interfaces/kits",
        "//ohos_bundles/@ohos/device_soc_hisilicon/hi3861v100/sdk_liteos/include",
        "//ohos_bundles/@ohos/device_soc_hisilicon/hi3861v100/sdk_liteos/third_party/lwip_sack/include",
    ]
}

app路径下的BUILD.gn代码:
【FFH】OpenHarmony 设备开发(一)-WIFI连接-鸿蒙开发者社区
【FFH】OpenHarmony 设备开发(一)-WIFI连接-鸿蒙开发者社区

业务代码

在业务代码中主要由主函数、连接函数、线程函数三大函数构成,在主函数中编写WIFI初始化、WIFI扫描等操作,连接函数中可以确认需要连接的WIFI的账号密钥以及加密方式。
主函数代码:
WIFI开启的流程:

  1. WIFI初始化
  2. 使能注册回调函数
  3. 获取网络接口进行IP的操作
  4. 扫描WIFI
  5. 获取WIFI扫描结果
  6. 连接WiFi
#define APP_INIT_VAP_NUM 2
#define APP_INIT_USR_NUM 2

static struct netif *g_lwip_netif = NULL;

int hi_wifi_start_sta(void)
{
    int ret;
    char ifname[WIFI_IFNAME_MAX_SIZE + 1] = {0};
    int len = sizeof(ifname);
    const unsigned char wifi_vap_res_num = APP_INIT_VAP_NUM;
    const unsigned char wifi_user_res_num = APP_INIT_USR_NUM;
    unsigned int num = WIFI_SCAN_AP_LIMIT;

    // ret = hi_wifi_init(wifi_vap_res_num, wifi_user_res_num); // WiFi初始化
    // if (ret != HISI_OK)
    // {
    //     return -1;
    // }

    ret = hi_wifi_sta_start(ifname, &len); // sta初始化
    if (ret != HISI_OK)
    {
        return -1;
    }

    /* 注册回调函数接口*/
    ret = hi_wifi_register_event_callback(wifi_wpa_event_cb);
    if (ret != HISI_OK)
    {
        printf("register wifi event callback failed\n");
    }

    /* 获取网络接口进行IP的操作 */
    g_lwip_netif = netifapi_netif_find(ifname);
    if (g_lwip_netif == NULL)
    {
        printf("%s: get netif failed\n", __FUNCTION__);
        return -1;
    }

    /* 扫描WIFI */
    ret = hi_wifi_sta_scan();
    if (ret != HISI_OK)
    {
        return -1;
    }

    sleep(5); /* sleep 5s, waiting for scan result. */

    //创建pst_results存放WiFi扫描结果
    hi_wifi_ap_info *pst_results = malloc(sizeof(hi_wifi_ap_info) * WIFI_SCAN_AP_LIMIT);
    if (pst_results == NULL)
    {
        return -1;
    }

    //获取station扫描结果
    ret = hi_wifi_sta_scan_results(pst_results, &num);
    if (ret != HISI_OK)
    {
        free(pst_results);
        return -1;
    }

    //打印WIFI扫描结果
    for (unsigned int loop = 0; (loop < num) && (loop < WIFI_SCAN_AP_LIMIT); loop++)
    {
        printf("SSID: %s\n", pst_results[loop].ssid);
    }
    free(pst_results);

    /* 进行WIFI连接 */
    ret = hi_wifi_start_connect();
    if (ret != 0)
    {
        return -1;
    }

    return 0;
}

注册回调函数:


/* 清理IP,网关和子网掩码 */
void hi_sta_reset_addr(struct netif *pst_lwip_netif)
{
    ip4_addr_t st_gw;
    ip4_addr_t st_ipaddr;
    ip4_addr_t st_netmask;

    if (pst_lwip_netif == NULL)
    {
        printf("hisi_reset_addr::Null param of netdev\r\n");
        return;
    }

    IP4_ADDR(&st_gw, 0, 0, 0, 0);
    IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
    IP4_ADDR(&st_netmask, 0, 0, 0, 0);

    netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw);
}

//注册回调函数
void wifi_wpa_event_cb(const hi_wifi_event *hisi_event)
{
    if (hisi_event == NULL)
        return;

    switch (hisi_event->event)
    {
    case HI_WIFI_EVT_SCAN_DONE:		//STA扫描完成
        printf("WiFi: Scan results available\n");
        break;
    case HI_WIFI_EVT_CONNECTED:
        printf("WiFi: Connected\n");		//wifi已连接
        netifapi_dhcp_start(g_lwip_netif);  //接口功能启动网络接口的DHCP协商
        break;
    case HI_WIFI_EVT_DISCONNECTED:
        printf("WiFi: Disconnected\n");
        netifapi_dhcp_stop(g_lwip_netif);		//关闭wifi
        hi_sta_reset_addr(g_lwip_netif);	//清理IP,网关和子网掩码 
        break;
    case HI_WIFI_EVT_WPS_TIMEOUT:
        printf("WiFi: wps is timeout\n");	//WPS事件超时
        break;
    default:
        break;
    }
}

连接函数:
连接的步骤:

  1. 创建hi_wifi_assoc_request结构体变量
  2. hi_wifi_assoc_request结构体成员初始化:ssid,加密方式,密钥
  3. 使用hi_wifi_sta_connect连接WiFi,其中的实参为hi_wifi_assoc_request变量的地址

int hi_wifi_start_connect(void)
{
    int ret;
    errno_t rc;
    hi_wifi_assoc_request assoc_req = {0};

    /* copy SSID to assoc_req */
    //第三参数为ssid,第四参数为ssid数据长度
    rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, "M20P", 4);
    if (rc != EOK)
    {
        return -1;
    }

    //开放WIFI
    // assoc_req.auth = HI_WIFI_SECURITY_OPEN;

    // WIFI加密方式
    assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;

    /* WIFI密钥 */
    memcpy(assoc_req.key, "12345678", 8);

    // WIFI连接
    ret = hi_wifi_sta_connect(&assoc_req);
    if (ret != HISI_OK)
    {
        return -1;
    }

    return 0;
}

线程任务创建:
我们需要创建线程时,首先需要创建osThreadAttr_t结构体变量,下一步便是初始化该结构体变量,在此步初始化中的关键是线程名称、任务栈大小和线程优先级,再下一步便使用osThreadNew()将该结构体变量注册,最后SYS_RUN()运行该线程.

//线程代码段
void *hi_wifi_text(const char *arg)
{
    printf("******************************\n");
    hi_wifi_start_sta();

    printf("******************************\n");
}
//创建线程
void wifi_demo(void)
{
    osThreadAttr_t attr;

    attr.name = "WIFITask";     //线程名称
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 4096;     //任务栈大小
    attr.priority = 25;     //线程优先级
	
//第一参数为线程代码段函数的名称
    if (osThreadNew((osThreadFunc_t)hi_wifi_text, NULL, &attr) == NULL)
    {
        printf("[LedExample] Falied to create LedTask!\n");
    }
}
//运行wifi_demo线程
SYS_RUN(wifi_demo);

效果图:
【FFH】OpenHarmony 设备开发(一)-WIFI连接-鸿蒙开发者社区
【FFH】OpenHarmony 设备开发(一)-WIFI连接-鸿蒙开发者社区

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-9-1 23:49:14修改
2
收藏 3
回复
举报
3条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

非hi3861可以使用这个吗?

回复
2022-9-2 10:48:12
X丶昕雪
X丶昕雪 回复了 红叶亦知秋
非hi3861可以使用这个吗?

轻量系统都可以移植使用。不同厂商的板子提供的api可能会有略微改变,移植时可以关注一下api接口

已于2022-9-2 11:04:28修改
回复
2022-9-2 11:00:53
红叶亦知秋
红叶亦知秋 回复了 X丶昕雪
轻量系统都可以移植使用。不同厂商的板子提供的api可能会有略微改变,移植时可以关注一下api接口

好的,感谢回复

回复
2022-9-2 11:16:17
回复
    相关推荐