当前位置: 首页 > news >正文

物联网设备WIFI模块实现

问题

如何在设备上进行 Wifi 编程?

LwIp (Light Weight IP) 简介

LwIp 是轻量化的 TCP/IP,是一个小型开源的 TCP/IP 协议栈

LwIp 的设计目标是用较少的资源实现较完整的 TCP/IP 协议栈

LwIp 能在操作系统中运行,也能在无操作系统的情况下独立运行

LwIp 提供了 Socket API 和 Netconn API

LwIp 的主要特性

支持 ARP,ICMP,IGMP

支持 UDP,TCP,IP (可移植网络通信框架)

支持 DNS,PPP,SNMP

支持 DHCP,可动态分配 IP 地址 (WIFI 支持)

BearPi-Nano 联网能力

BearPi-Nano 基于 Hi3861 芯片构造,而 Hi3861 自身具备 Wifi 能力

AP 模式

  • 工作于 Wifi 热点模式,可被其他设备以 Wifi 方式连接

STA 模式

  • 工作于 Wifi 连接模式,可连接到指定 Wifi 热点

Wifi 模块接口设计

涉及的 OH 系统接口

Wifi 热点连接流程

Wifi 联网关键函数实现

 

 

 

 

Wifi 模块实现

wifi_connect.h

#ifndef WIFI_CONNECT_H
#define WIFI_CONNTCE_H

int Wifi_Init(void);
int Wifi_Connect(const char* ssid, const char* password);
int Wifi_Start(void);
void Wifi_Stop(void);
int Wifi_IsOk(void);
char* Wifi_IpAddr(void);

#endif

wifi_connect.c

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

#include "wifi_connect.h"
#include "wifi_device.h"
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/ip4_addr.h"
#include "lwip/api_shell.h"
#include "lwip/dhcp.h"

#define WIFI_TIMMEOUT  20
#define WLAN_PORT      "wlan0"

static WifiEvent g_WifiEventHandler = {0};
static int g_WaitResult = 0;
static struct netif* g_LwipNeif = NULL;

void ClearWaitResult(void)
{
    g_WaitResult = 0;
}

void SetWaitResult(int result)
{
    g_WaitResult = result;
}

int GetWaitResult(void)
{
    return g_WaitResult;
}

void ToWait(int timeout)
{
    while((GetWaitResult() == 0) && timeout--)
    {
        sleep(1);
    }
}

void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
{
    (void)info;
    g_WaitResult = state;
}

void OnWifiScanStateChanged(int state, int size)
{
    (void)state;
    (void)size;
}

void OnHotspotStateChanged(int state)
{
    (void)state;
}

void OnHotspotStaJoin(StationInfo* info)
{
    (void)info;
}

void OnHotspotStaLeave(StationInfo* info)
{
    (void)info;
}

int Wifi_Init(void)
{
    g_WifiEventHandler.OnWifiScanStateChanged = OnWifiScanStateChanged;
    g_WifiEventHandler.OnWifiConnectionChanged = OnWifiConnectionChanged;
    g_WifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoin;
    g_WifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeave;
    g_WifiEventHandler.OnHotspotStateChanged = OnHotspotStateChanged;

    return RegisterWifiEvent(&g_WifiEventHandler);

}

int Wifi_Connect(const char* ssid, const char* password)
{
    int ret = WIFI_SUCCESS;

    if(!Wifi_IsOk())
    {
        ret = (ssid && password) ? EnableWifi() : ERROR_WIFI_UNKNOWN;

        if(ret == WIFI_SUCCESS)
        {
            WifiDeviceConfig config = {0};
            int result = 0;

            config.securityType = WIFI_SEC_TYPE_PSK;
            strcpy(config.ssid, ssid);
            strcpy(config.preSharedKey, password);

            ret += AddDeviceConfig(&config, &result);
            ret += ConnectTo(result);

            if(ret == WIFI_SUCCESS)
            {
                ClearWaitResult();
                ToWait(WIFI_TIMMEOUT);
                ret = (GetWaitResult() != 0) ? WIFI_SUCCESS : ERROR_WIFI_UNKNOWN;
            }
            else
            {
                ret = ERROR_WIFI_UNKNOWN;
            }
        }
    }

    return ret;
}

int Wifi_Start(void)
{
    int ret = WIFI_SUCCESS;

    if(!Wifi_IsOk())
    {
        g_LwipNeif = netifapi_netif_find(WLAN_PORT);

        if(g_LwipNeif != NULL)
        {
            if(dhcp_start(g_LwipNeif) == ERR_OK)
            {
                int i = WIFI_TIMMEOUT;

                while(((ret = dhcp_is_bound(g_LwipNeif)) != ERR_OK) && i--)
                {
                    usleep(200 * 1000);
                }
            }

            if(ret != WIFI_SUCCESS)
            {
                Wifi_Stop();
            }
        }
        else
        {
            ret = ERROR_WIFI_UNKNOWN;
        }
    }

    return ret;
}

void Wifi_Stop(void)
{
    dhcp_stop(g_LwipNeif);
    g_LwipNeif = NULL;
}

int Wifi_IsOk(void)
{
    return !!g_LwipNeif;
}

char* Wifi_IpAddr(void)
{
    char* ret = NULL;

    if(Wifi_IsOk())
    {
        ip4_addr_t addr = {0};
        ip4_addr_t mask = {0};
        ip4_addr_t gw = {0};

        netif_get_addr(g_LwipNeif, &addr, &mask, &gw);

        if((addr.addr != 0) && (addr.addr != -1))
        {
            ret = ip4addr_ntoa(&addr);
        }
        else
        {
            Wifi_Stop();
        }
    }

    return ret;
}

main_entry.c

#include <stdio.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifi_connect.h"
 
static void* Task_Iniit(const char* arg)
{
	Wifi_Init();
    Wifi_Connect("wifi_test", "12345678");
    Wifi_Start();

    if(Wifi_IsOk)
    {
        printf("addr = %s\n", Wifi_IpAddr());
    }
	
	return arg;
}
 
static void Main_Entry(void)
{
    osThreadAttr_t attr = {0};
 
    attr.name = "Task_Iniit";
    attr.stack_size = 4 * 1024;
    attr.priority = 20;
 
    if(osThreadNew((osThreadFunc_t)Task_Iniit, NULL, &attr) == NULL)
	{
		printf("failed to create task!\n");
	}
}
 
SYS_RUN(Main_Entry);

测试结果如下图所示

Hi3861成功连上 Wifi, IP 为192.168.137.48

课后思考

有了 Wifi 模块后,接下来应该干啥? 

相关文章:

  • 做PHP网站前端网站进不去/淘宝关键词排名是怎么做的
  • 最专业的医疗网站建设/上海全网推广
  • phpstudy做网站/个人网页生成器
  • wordpress地址 灰色/视频号视频怎么看下载链接
  • 网站策划书内容/百度推广竞价
  • 淘宝网站的建设目的是什么/济南百度快照推广公司
  • java计算机毕业设计学生宿舍管理系统源程序+mysql+系统+lw文档+远程调试
  • WEB前端网页设计 HTML CSS 网页设计参数 - 【盒子模型】
  • JavaWeb_第3章_HTTPTomcatServlet
  • 【一条命令搞定rabbitmq的安装与配置】
  • 【科技与狠活】如何利用Python绘制足球场
  • 详解 Go 语言中的 init () 函数
  • 修复 爱普生 EPSON L4156 打印机 无法打印,开关 WIFI 墨水 三个灯同时闪烁的问题
  • 卡尔曼滤波之最优状态估计和最优状态估计算法
  • 【计算机网络】计算机网络复习总结 ----- 链路层
  • JUC并发编程与源码分析笔记06-Java内存模型之JMM
  • 【网关路由测试】——诊断路由测试
  • 软件架构基本功