问题:如何在设施上进行 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_Hint 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;}