第2讲 Hi3861的WiFi实验-AP模式

2023-11-06

引言

在本文中,带大家编写一个程序,测试Hi3861的WiFi-AP模式,进一步熟悉相关API的使用。

请先按照本专栏第一讲中的第四部分准备好实验环境。

一、编写程序

首先,打开 DevEco Device Tool ,在鸿蒙项目 hispark_pegasus_312 的文件夹applications/sample/wifi-iot/app/experiment下创建一个新文件夹C01_wifi_ap

然后,在文件夹C01_wifi_ap新建一个文件:wifi_ap_test.c。下面,我们就在这个文件中编写程序。

1.1 头文件

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "wifi_hotspot.h"
#include "netifapi.h"

1.2 宏定义

#define AP_SSID "Hi3861-AP"   //Hi3861 WiFi热点的名称
#define AP_PSK  "12345678"    //Hi3861 WiFi热点的密码

1.3 全局变量

//WiFi事件回调函数结构体
WifiEvent g_wifiEventHandler = {0};  
//网络接口结构体指针
static struct netif *g_lwip_netif = NULL; 
//Hi3861的WiFi-AP模式的状态, 1: 打开, 0: 关闭
static volatile int g_hotspotStarted = 0; 
//接入Hi3861的WiFi热点的站点数
static volatile int g_joinedStations = 0;  

1.4 函数

1.4.1 子函数

函数原型 功能描述
int WiFiEventHandlerRegister(void) 对WiFi事件的回调函数进行注册。
void PrintStationInfo(StationInfo* info) 打印接入/离开WiFi热点的WiFi设备的信息。
int ChangeHotspotIpAddr(void) 更改Hi3861-WiFi-AP的地址信息。
int StartHotspot(const HotspotConfig* config) 开启Hi3861的WiFi热点。
int StopHotspot(void) 关闭Hi3861的WiFi热点。

这些子函数主要就是通过调用之前介绍的API来实现的,它们又在任务函数或WiFi事件的回调函数中被调用。

1、函数:PrintStationInfo

//打印站点的信息
static void PrintStationInfo(StationInfo* info)
{
    static char macAddress[32] = {0};
    unsigned char* mac = info->macAddress;
    
    if (!info) return;
    snprintf(macAddress, sizeof(macAddress), 
    		"%02X:%02X:%02X:%02X:%02X:%02X",
             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    printf("PrintStationInfo: mac=%s, reason=%d \r\n", macAddress, info->disconnectedReason);
}

在这个函数中调用了函数snprintf,这个函数的作用是:按照第3个参数所规定的格式,把最后6个参数(MAC地址的6个字节)变成字符串,并把这个字符赋值给第一个参数。

2、函数:ChangeHotspotIpAddr

//更改Hi3861-WiFi-AP的地址信息
static int ChangeHotspotIpAddr(void)
{
    int errCode = 0;

    ip4_addr_t ipaddr;   //IP地址
    ip4_addr_t gateway;  //网关
    ip4_addr_t netmask;  //子网掩码

    g_lwip_netif = netifapi_netif_find("ap0");

    if(g_lwip_netif) 
    {
        //停止WiFi热点的DHCP服务器
        printf("\r\n");
        printf("Stopping DHCP server ...... \r\n");
        errCode = netifapi_dhcps_stop(g_lwip_netif);
        if(errCode != ERR_OK)
        {
            printf("Error!!! errCode = %d \r\n", errCode);
            return -1;
        }
        printf("Succeed! \r\n");

        //设置WiFi热点的地址信息
        printf("Changing IP address ...... \r\n");
        IP4_ADDR(&ipaddr,  192, 168, 3, 1);    
        IP4_ADDR(&gateway, 192, 168, 3, 1);     
        IP4_ADDR(&netmask, 255, 255, 255, 0);   
        errCode = netifapi_netif_set_addr(g_lwip_netif, &ipaddr, &netmask, &gateway);
        if(errCode != ERR_OK)
        {
            printf("Error!!! errCode = %d \r\n", errCode);
            return -1;
        }
        printf("Succeed! IP: 192.168.3.1 \r\n");

        //启动WiFi热点的DHCP服务器
        printf("Starting DHCP server ...... \r\n");
        errCode = netifapi_dhcps_start(g_lwip_netif, 0, 0); 
        if(errCode != ERR_OK)
        { 
            printf("Error!!! errCode = %d \r\n", errCode);
            return -1;
        }
        printf("Succeed! \r\n");
    }
    else
    {
        printf("Error!!! g_lwip_netif is NULL!!! \r\n");
        return -1;
    }

    return 0;
}

函数中的IP4_ADDR是在头文件ip4_addr.h中定义的一个带参数的宏,其作用是:是把分成4个数的地址合成为一个按大端模式存放的32bit无符号整数。

1.4.2 WiFi事件回调函数

在AP模式下,有三种WiFi事件。所以,我们要相应编写三个回调函数,分别对这三种WiFi事件进行处理。

函数原型 功能描述
void OnHotspotStateChangedHandler(int state) 回调函数,WiFi事件:Hi3861-AP模式的状态发生改变(打开/关闭)
void OnHotspotStaJoinHandler(StationInfo* info) 回调函数,WiFi事件:有站点接入Hi3861的WiFi热点
void OnHotspotStaLeaveHandler(StationInfo* info) 回调函数,WiFi事件:有站点离开Hi3861的WiFi热点

1.4.3 任务函数和任务入口函数

可以把任务函数理解成这个程序中的主函数;任务入口函数就是把任务函数创建成一个任务,并使之进入就绪状态,接受操作系统的调度。

函数原型 功能描述
void WifiHotspotTaskFun(void) 任务函数
void WifiHotspotTaskEntry(void) 任务入口函数

任务函数的基本流程如下图所示:

在这里插入图片描述

步骤Step3-3并不是必须的,如果不更改WiFi的地址信息,WiFi热点的默认IP地址是:192.168.5.1。

任务函数的代码如下:

//任务函数
static void WifiHotspotTaskFun(void)
{
    int errCode = 0;
    int timeout;
    
    HotspotConfig config = {0};  //WiFi热点的配置参数结构体

    //Step1: 准备WiFi热点的配置参数
    strcpy(config.ssid, AP_SSID);             //Hi3861 WiFi热点的名称
    strcpy(config.preSharedKey, AP_PSK);      //Hi3861 WiFi热点的密码
    config.securityType = WIFI_SEC_TYPE_PSK;  //Hi3861 WiFi热点的加密类型
    config.band = HOTSPOT_BAND_TYPE_2G;       //Hi3861 WiFi热点的频段
    config.channelNum = 7;                    //Hi3861 WiFi热点的信道

    while(1)
    {
        //Step2: 注册WiFi事件的回调函数
        printf("\r\n");
        WiFiEventHandlerRegister();

        //Step3: 开启Hi3861的WiFi热点
        printf("\r\n");
        printf("starting AP ...\r\n");
        StartHotspot(&config);

        //Step4: 延时
        printf("\r\n");
        printf("Please connect this hotspot with your mobile phone ...\r\n");
        printf("\r\n");
        for(timeout=120; timeout>0; timeout--)
        {
            osDelay(100);
            if(timeout == 10)
            {
                printf("\r\n");
                printf("Hotspot will be closed after %d s ...... \r\n", timeout);
            }
        }

        //Step5: 关闭WiFi热点
        StopHotspot();

        //Step6: 注销WiFi事件的回调函数
        printf("\r\n");
        printf("UnRegister WifiEvent ...... \r\n");
        errCode = UnRegisterWifiEvent(&g_wifiEventHandler);
        if(errCode != WIFI_SUCCESS)
        {
            printf("Error!!! errCode = %d \r\n", errCode);
        }
        printf("Succeed! \r\n");

        //Step7: 延时
        for(timeout=30; timeout>0; timeout--)
        {
            osDelay(100);
            if(timeout < 10)
            {
                printf("Hotspot will be opened after %d s ...... \r\n", timeout);
            }
        }
    }
}

二、编写/修改编译脚本

1、在文件夹C01_wifi_ap新建一个文件:BUILD.gn。这个编译脚本的内容如下:

static_library("C01_wifi_ap") {
    sources = [
        "wifi_ap_test.c",
    ]
    
    include_dirs = [
        "//utils/native/lite/include",
        "//device/hisilicon/hispark_pegasus/hi3861_adapter/kal/cmsis",
        "//foundation/communication/wifi_lite/interfaces/wifiservice",
        "//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/lwip_sack/include/lwip", 
    ]
}

2、修改文件夹applications/sample/wifi-iot/app下的文件BUILD.gn

import("//build/lite/config/component/lite_component.gni")

lite_component("app") {
    features = [
        "startup",
        "experiment/C01_wifi_ap",
    ]
}

三、编译、烧写

略。参考:《鸿蒙设备开发之Hello World》第三、四部分。

四、测试

1、烧写完毕后,参考《鸿蒙设备开发之Hello World》第五部分,启动测试程序。测试程序将按照任务函数的流程在终端窗口中打印输出一些信息,如下图所示:

在这里插入图片描述

2、当看到上图最后一条提示信息后,你就可以在手机的WiFi设置里看到Hi3861的WiFi热点。用手机连接这个WiFi热点,终端输出如下图所示:

在这里插入图片描述

mac是手机的MAC地址,active stations是当前接入WiFi热点的设备的数量。

当手机从Hi3861的WiFi热点断开时,终端输出如下图所示:

在这里插入图片描述

3、当即将关闭WiFi热点时,终端输出下图所示第一条提示信息,然后在10s后关闭DHCP服务、关闭AP模式、注销WiFi事件回调函数。

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第2讲 Hi3861的WiFi实验-AP模式 的相关文章

  • 「C++学习笔记」面向.Net Core的(C++)CLR类库非专业入门(+使用Opencv)

    关键词 C CLR Net Core Net Famework Opencv C 目录 什么是CLR类库 本文说明 创建Demo程序 调用dll 通过项目引用 通过dll文件引用 其他还没完全清楚的坑 有关C CLI这块的资料真的很少而且都
  • 如何看待ChatGPT

    如何看待ChatGPT 如何看待ChatGPT 语言学家乔姆斯基说 这是一个抄袭的机器 欺骗性机器 ChatGPT使用大量文本数据进行训练 然后以一种令人信服的修饰语句展现 这使得它和人的互动能力更加契合 但是仍然不是一个充满创造力的智能机
  • 微信小程序之拨打电话

    微信小程序拨打电话功能的实现是采用wx makePhoneCall 具体方法如下 wxml lt view gt 电话 15888888888 lt view data ph 15888888888 bindtap callPhone gt
  • 【Android 12 AOSP学习】Android 12源码下载编译

    一 搭建环境 liunx系统 Ubuntu20 04 Android系统 12 1 安装 Repo 下载Repo前先安装 curl 库 sudo apt get install curl 下载好 curl 库后 设置清华源下载 Repo 然
  • 前端 JavaScript 提取 JSON 数据

    原文地址 假如我们从后端接收到了以下 JSON 数据 id 1 name Xu Albter age 18 使用 JSON parse 方法处理以上数据 将其转换为 JavaScript 对象 var obj JSON parse id 1
  • select函数缺陷分析

    与poll和epoll不同 select函数是事件为单位组织文件描述符 监视的行为较为单一 函数原型 int select int nfds fd set readfds fd set writefds fd set exceptfds s
  • 链表应用:两数相加

    关于链表 链表是一种极其重要的数据结构 因为对指针和抽象思维的要求较高 一度成为身边同学最痛恨的对象 我在将这里演示如何使用链表制作一个可以按位储存数字的容器 鉴于本人亦初学者 有错误请各位在评论区指正 这里还是以介绍链表为主 算法部分苦于

随机推荐

  • SpringCloud和微服务介绍

    SpringCloud介绍 微服务架构是什么 微服务实例的开发 服务的注册与发现 负载均衡 服务容错 API网关 分布式配置中心 调试 部署 持续集成 SpringCloud介绍 SpringCloud是在SpringBoot的基础上构建的
  • 一个完整详细的二维SVR案例分析过程

    文章目录 案例介绍 数据预处理 函数拟合仿真 SVR建模 模型调参 案例介绍 首先 此次案例是以油气开发为背景 选取加粗样式其中重要的两个参数含油饱和度和孔隙度分别作为此次案例的自变量和因变量进行试验 按照正常的案例分析步骤进行操作 此次为
  • 神经网络(ANN)

    算法介绍 概念 人工神经网络是由具有适应性的简单单元组成的广泛并行互连的网络 它的组织能够模拟生物神经神经系统对真实世界物体所作出的交互反应 在实际应用中 80 90 的人工神经网络模型是采用误差反转算法或其变形形式的网络模型 一个神经网络
  • 小程序的配置文件和小程序的模板语法

    微信小程序 小程序的配置文件 一个小程序应用程序会包括 会有最基本的两种配置文件 一种是全局的 app json 一种是页面自己的 page json 注意 配置文件中不可以出行注释 1 1 全局配置文件 app json app json
  • 主题模型(Topic Model)与LDA算法

    Topic Model 主题模型 Topic Model 是以非监督学习的方式对文档的隐含语义结构 latent semantic structure 进行聚类 clustering 的统计模型 主题模型认为在词 word 与文档 docu
  • 第十三章:QT多线程(QThread)

    回顾 第一章 Qt的概述 第二章 在Ubuntu编写第一个Qt程序 第三章 Qt的字符串和字符编码 第四章 Qt的信号和槽 第五章 Qt容器窗口 父窗口 第六章 面向对象的Qt编程 第七章 Qt设计师使用 designer 第八章 Qt创造
  • Unittest框架多个testcase之间全局变量的调用

    unittest模块进行接口自动化的时候遇到以下场景 新增 修改 查看 删除一个项目配置流程 但是每次用真实数据请求 数据库就会增加很多脏数据 所以就产生了数据一条龙服务 从新增到删除 涉及到了Unittest下个接口需要调用上个接口的返回
  • mysql数据库访问控制查询_MySQL ------ 管理用户对数据库的访问控制(GRANT 与 REVOKE)(二十九)...

    数据库服务器通常包含着关键的数据 所以为了确保这些数据的安全和完整需要要利用访问控制 MySQL服务器的安全基础是 用户应该对他们需要的数据具有适当的访问权 既不能多也不能少 即用户不能对过多的数据具有访问权 访问控制 需要给用户提供他们所
  • 电子计算机的发展史

    1 电子计算机元器件变化 继电器 真空管 晶体管 2 计算机的出现背景 20世纪人口暴增 科学与工程进步迅速 航天计划成形 以上导致数据的复杂度急剧上升 计算量暴增 对于计算的自动化 高速有迫切的需求 3 电子计算机的发展 1945年 哈佛
  • antd table合并行或者列(动态添加合并行、列)

    antd table合并行或者列 动态添加合并行 列 表头只支持列合并 使用 column 里的 colSpan 进行设置 表格支持行 列合并 使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时 设置的
  • Ubuntu系统安装企业微信和微信

    一 Ubuntu16 04安装企业微信 1 安装git工具 sudo apt install wget g git 2 安装deepin wine git clone https gitee com wszqkzqk deepin wine
  • UE4 行为树装饰器(Decorator)简单实用说明(1)

    在行为树标准模型中 条件语句为 Task 叶节点 除成功和失败外不执行任何操作 虽然也可以使用传统的条件 tasks 但还是强烈推荐您使用 Decorator 系统作为条件语句 使用 decorators 而非 tasks 作为条件语句有多
  • 光猫超级账号密码、宽带账号密码 获取

    光猫超级账号密码 宽带账号密码 获取 目的与起因 租房宽带是电信的 Ipv6 之前笔记本使用 Ipv6 地址可以直接被手机通过移动网络无需中转进行远程桌面连接的 目前尝试了在局域网内是可以实现的 应该是电信屏蔽了3389端口 在光猫路由器修
  • tcp 序列号

    父 tcp 状态 from异常流程 个人渣记录仅为自己搜索用的博客 CSDN博客 转载请注明出处 6 TCP6 TCP 协议 序号和确认号 tcp 最终确认序号 Allen 的博客 CSDN博客6 TCP 接下来的内容是学习后续内容的基础
  • Python Pandas 数据拼接/排序/重置

    Pandas 数据拼接 排序 重置 一 数据拼接 1 1 行拼接 纵向 第 0 维 pd concat df1 df2 1 2 列拼接 横向 第 1 维 pd concat df1 df2 axis 1 二 排序 2 1 从小到大排序 默认
  • CMake设置MSVC工程MT/MTd/MD/MDd

    文章目录 0 前言 1 如何设置 1 1 CMakeLists代码 1 2 要点1 POLICY 1 3 要点2 set property 0 前言 在MSVC工程上右键 gt 属性 找到配置属性 gt C C gt 代码生成 gt 运行库
  • 设计模式精讲-抽象工厂方法模式

    设计模式 抽象工厂方法模式 定义 示例 应用场景 优点 定义 提供一个创建一系列相关或互相依赖对象的接口 而无需指定它们具体的类 定义和图不理解的 可以先看下面的示例 回头再去理解 示例 以数据库为例 1 变化的部分 Mysq Oracle
  • 在LDAP中使用角色(Role)和组(Group)来管理用户

    LDAP 轻量级目录服务器 越来越被广泛的使用 特别是在管理海量用户信息和管理身份认证信息的时候 LDAP被国内大多数企业所使用 从中国电信 中 国移动 新浪 和许多省市政府部门都使用LDAP来管理用户身份的信息 下面重点介绍在LDAP中管
  • 【JavaEE】多线程(四)

    多线程 四 在开始讲之前 我们先来回顾回顾前三篇所讲过的内容 线程的概念 并发编程 多进程 比较重 频繁创建销毁 开销大 Thread的使用 创建线程 继承Thread 实现Runnable 继承Thread 匿名内部类 实现Runnabl
  • 第2讲 Hi3861的WiFi实验-AP模式

    引言 在本文中 带大家编写一个程序 测试Hi3861的WiFi AP模式 进一步熟悉相关API的使用 请先按照本专栏第一讲中的第四部分准备好实验环境 一 编写程序 首先 打开 DevEco Device Tool 在鸿蒙项目 hispark