问题:如何在设施上进行 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 模块接口设计
init Wifi_Init(void);
init Wifi_Connect(const char *id, const char *pwd);
int Wifi_Start(void);
int Wifi_IsOk(void);
void Wifi_Stop(void);
char *Wifi_IpAddr(void);
波及的 OH 零碎接口
WifiErrorCode RegisterWifiEvent(WifiEvent *event);
WifiErrorCode EnableWifi(void);
WifiErrorCode AddDeviceConfig(const WifiDeviceConfig *config, int result);
WifiErrorCode ConnetTo(int networkid); // 通过网络标识连贯到指标热点
struct netif *netifapi_netif_find(const char *name); // 获取 netif 构造体用于后续 dhcp 操作
err_t dhcp_start(struct netif *netif); // 启动 hdcp, 获取 ip
WIFI 热点连贯流程
WIFI 联网要害参数实现
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* id, const char* pwd)
{
int ret = WIFI_SUCCESS;
if(!Wifi_IsOk() )
{ret = id && pwd ? EnableWifi() : ERROR_WIFI_UNKNOWN;
// ret = (ret == WIFI_SUCCESS) ? && IsWifiActive() ? WIFI_SUCCESS : ERROR_WIFI_NOT_AVAILABLE;
if(ret == WIFI_SUCCESS)
{WifiDeviceConfig config = {0};
int result = 0;
config.securityType = WIFI_SEC_TYPE_PSK;
strcpy(config.ssid, id);
strcpy(config.preSharedKey, pwd);
ret += AddDeviceConfig(&config, &result);
ret += ConnectTo(result);
if(ret == WIFI_SUCCESS)
{ClearWaitResult();
ToWait(WIFI_TIMEOUT);
ret = (GetWaitResult() > 0) ? WIFI_SUCCESS : ERROR_WIFI_UNKNOWN;
}
}
}
return ret;
}
int Wifi_Start(void)
{
int ret = WIFI_SUCCESS;
if(!Wifi_IsOk() )
{g_LwipNetif = netifapi_netif_find(WLAN_PORT);
if(g_LwipNetif)
{
int i = WIFI_TIMEOUT;
if(dhcp_start(g_LwipNetif) == ERR_OK )
{while( ((ret = dhcp_is_bound(g_LwipNetif)) != ERR_OK) && i-- )
{usleep(200 * 1000);
}
}
if(ret != WIFI_SUCCESS)
{Wifi_Stop();
}
}
else
{ret = ERROR_WIFI_UNKNOWN;}
}
return ret;
}
编程试验
main_entry.c
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifi_connect.h"
static void* Init_Task(const char* arg)
{Wifi_Init();
Wifi_Connect("Py4OH-Test", "12345678");
Wifi_Start();
if(Wifi_IsOk() )
{printf("IP: %s\n", Wifi_IpAddr());
}
return arg;
}
static void Main_Entry(void)
{osThreadAttr_t attr = {0};
attr.name = "Init Task";
attr.stack_size = 1024 * 4;
attr.priority = 20;
if(osThreadNew((osThreadFunc_t)Init_Task, NULL, &attr) == NULL )
{printf("[dt4sw] Failed to create task!\n");
}
}
SYS_RUN(Main_Entry);
wifi_connect.h
#ifndef WIFI_CONNECT_H
#define WIFI_CONNECT_H
int Wifi_Init(void);
int Wifi_Connect(const char* id, const char* pwd);
int Wifi_Start(void);
int Wifi_IsOk(void);
void Wifi_Stop(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_TIMEOUT 20
#define WLAN_PORT "wlan0"
static int g_WaitResult = 0;
static WifiEvent g_WifiEventHandler = {0};
static struct netif* g_LwipNetif = NULL;
static void ClearWaitResult(void)
{g_WaitResult = 0;}
static void SetWaitResult(int result)
{g_WaitResult = result;}
static int GetWaitResult(void)
{return g_WaitResult;}
static void ToWait(unsigned int sec)
{while( sec-- && !GetWaitResult() )
{sleep(1);
}
}
static void OnWifiScanStateChanged(int state, int size)
{(void)state;
(void)size;
}
static void OnWifiConnectionChanged(int state, WifiLinkedInfo *info)
{(void)info;
SetWaitResult(state);
}
static void OnHotspotStaJoin(StationInfo *info)
{(void)info;
}
static void OnHotspotStateChanged(int state)
{(void)state;
}
static 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* id, const char* pwd)
{
int ret = WIFI_SUCCESS;
if(!Wifi_IsOk() )
{ret = id && pwd ? EnableWifi() : ERROR_WIFI_UNKNOWN;
// ret = (ret == WIFI_SUCCESS) ? && IsWifiActive() ? WIFI_SUCCESS : ERROR_WIFI_NOT_AVAILABLE;
if(ret == WIFI_SUCCESS)
{WifiDeviceConfig config = {0};
int result = 0;
config.securityType = WIFI_SEC_TYPE_PSK;
strcpy(config.ssid, id);
strcpy(config.preSharedKey, pwd);
ret += AddDeviceConfig(&config, &result);
ret += ConnectTo(result);
if(ret == WIFI_SUCCESS)
{ClearWaitResult();
ToWait(WIFI_TIMEOUT);
ret = (GetWaitResult() > 0) ? WIFI_SUCCESS : ERROR_WIFI_UNKNOWN;
}
}
}
return ret;
}
int Wifi_Start(void)
{
int ret = WIFI_SUCCESS;
if(!Wifi_IsOk() )
{g_LwipNetif = netifapi_netif_find(WLAN_PORT);
if(g_LwipNetif)
{
int i = WIFI_TIMEOUT;
if(dhcp_start(g_LwipNetif) == ERR_OK )
{while( ((ret = dhcp_is_bound(g_LwipNetif)) != ERR_OK) && i-- )
{usleep(200 * 1000);
}
}
if(ret != WIFI_SUCCESS)
{Wifi_Stop();
}
}
else
{ret = ERROR_WIFI_UNKNOWN;}
}
return ret;
}
int Wifi_IsOk(void)
{return !!g_LwipNetif;}
void Wifi_Stop(void)
{dhcp_stop(g_LwipNetif);
g_LwipNetif = NULL;
}
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_LwipNetif, &addr, &mask, &gw);
if((addr.addr != 0) && (addr.addr != -1) )
{ret = ip4addr_ntoa(&addr);
}
else
{Wifi_Stop();
}
}
return ret;
}