README.md
1# BearPi-HM_Nano开发板WiFi编程开发——Wifi连接热点
2
3
4本示例将演示如何在BearPi-HM_Nano开发板上编写一个Wifi连接热点的业务程序。
5
6## Wifi API分析
7本案例主要使用了以下几个API完成Wifi联网。
8### RegisterWifiEvent()
9```c
10WifiErrorCode RegisterWifiEvent(WifiEvent *event);
11```
12 **描述:**
13为指定的Wi-Fi事件注册回调函数。当WifiEvent中定义的Wi-Fi事件发生时,将调用已注册的回调函数。
14
15**参数:**
16
17|参数名|描述|
18|:--|:------|
19| event | 表示要注册回调的事件。 |
20
21
22### EnableWifi()
23```c
24WifiErrorCode EnableWifi(void);
25```
26**描述:**
27
28启用STA模式。
29
30### AddDeviceConfig()
31```c
32WifiErrorCode AddDeviceConfig(const WifiDeviceConfig *config, int *result);
33```
34**描述:**
35
36添加用于连接到指定热点的配置,此函数生成一个networkId。
37
38**参数:**
39
40|参数名|描述|
41|:--|:------|
42| config | 表示待添加的热点配置。 |
43| result | 表示生成的networkId。每个networkId匹配一个热点配置。 |
44
45### ConnectTo()
46```c
47WifiErrorCode ConnectTo(int networkId);
48```
49**描述:**
50
51连接到和networkId匹配的热点。
52
53**参数:**
54
55|参数名|描述|
56|:--|:------|
57| networkId | 表示与目标热点匹配的网络id。 |
58
59
60### netifapi_netif_find()
61```c
62struct netif *netifapi_netif_find(const char *name);
63```
64**描述:**
65
66获取netif用于IP操作。
67
68### dhcp_start()
69
70```c
71err_t dhcp_start(struct netif *netif);
72```
73
74**描述:**
75
76启动DHCP客户端, 用于动态获取IP地址。
77
78
79## 软件设计
80
81**主要代码分析**
82
83完成Wifi热点的连接需要以下几步
84
851. 通过 `RegisterWifiEvent` 接口向系统注册扫描状态变化回调函数,用于接收扫描状态变化的通知,如扫描动作是否完成等。
86
87* `OnWifiConnectionChangedHandler` 用于绑定连接状态变化的回调函数,该回调函数有两个参数 `state` 和 `info` 。
88
89 * state表示连接状态,取值为0和1,1表示热点连接成功。
90
91 * info表示Wi-Fi连接信息,包含以下参数。
92
93
94 |参数名|描述|
95 |:--|:------|
96 | ssid [WIFI_MAX_SSID_LEN] | 连接的热点名称。 |
97 | bssid [WIFI_MAC_LEN] | 连接的热点MAC地址。 |
98 | rssi | 接收信号强度(RSSI)。 |
99 | connState | Wifi连接状态。 |
100 | disconnectedReason | Wi-Fi断开的原因。 |
101
102
1032. 调用 `EnableWifi` 接口,使能 Wifi。
1043. 调用 `AddDeviceConfig` 接口,配置连接的热点信息。
1054. 调用 `ConnectTo` 接口,连接到指定networkId对应的热点。
1065. 调用 `WaitConnectResult` 接口等待,该函数中会有15s的时间去轮询连接成功标志位 `g_ConnectSuccess`,当`g_ConnectSuccess` 为 1 时退出等待。
1076. 调用 `netifapi_netif_find` 接口,获取 netif 用于 IP 操作。
1087. 调用 `dhcp_start` 接口,启动 DHCP客户端, 获取 IP。
109
110```c
111static BOOL WifiStaTask(void)
112{
113 unsigned int size = WIFI_SCAN_HOTSPOT_LIMIT;
114
115 //初始化WIFI
116 if (WiFiInit() != WIFI_SUCCESS) {
117 printf("WiFiInit failed, error = %d\r\n", error);
118 return -1;
119 }
120 //分配空间,保存WiFi信息
121 WifiScanInfo *info = malloc(sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT);
122 if (info == NULL) {
123 return -1;
124 }
125 //轮询查找WiFi列表
126 do {
127 Scan();
128 WaitScanResult();
129 error = GetScanInfoList(info, &size);
130 } while (g_staScanSuccess != 1);
131 //打印WiFi列表
132 printf("********************\r\n");
133 for (uint8_t i = 0; i < g_ssid_count; i++) {
134 printf("no:%03d, ssid:%-30s, rssi:%5d\r\n", i + 1, info[i].ssid, info[i].rssi);
135 }
136 printf("********************\r\n");
137 //连接指定的WiFi热点
138 for (uint8_t i = 0; i < g_ssid_count; i++) {
139 if (WifiConnectAp(SELECT_WIFI_SSID, SELECT_WIFI_PASSWORD, info, i) == WIFI_SUCCESS) {
140 printf("WiFi connect succeed!\r\n");
141 break;
142 }
143
144 if (i == g_ssid_count - 1) {
145 printf("ERROR: No wifi as expected\r\n");
146 while (1)
147 osDelay(DHCP_DELAY);
148 }
149 }
150
151 //启动DHCP
152 if (g_lwip_netif) {
153 dhcp_start(g_lwip_netif);
154 printf("begain to dhcp\r\n");
155 }
156 //等待DHCP
157 for (;;) {
158 if (dhcp_is_bound(g_lwip_netif) == ERR_OK) {
159 printf("<-- DHCP state:OK -->\r\n");
160 //打印获取到的IP信息
161 netifapi_netif_common(g_lwip_netif, dhcp_clients_info_show, NULL);
162 break;
163 }
164 osDelay(DHCP_DELAY);
165 }
166
167 //执行其他操作
168 for (;;) {
169 osDelay(DHCP_DELAY);
170 }
171}
172```
173
174## 编译调试
175### 修改对接热点的账号密码
176修改`wifi_sta_connect.c`第51行和52行的热点账号密码。
177```c
178#define SELECT_WIFI_SSID "BearPi"
179#define SELECT_WIFI_PASSWORD "0987654321"
180```
181### 修改 BUILD.gn 文件
182
183修改 `device\board\bearpi\bearpi_hm_nano\app` 路径下 BUILD.gn 文件,指定 `wifi_sta_connect` 参与编译。
184```r
185#"D1_iot_wifi_sta:wifi_sta",
186"D2_iot_wifi_sta_connect:wifi_sta_connect",
187#"D3_iot_udp_client:udp_client",
188#"D4_iot_tcp_server:tcp_server",
189#"D5_iot_mqtt:iot_mqtt",
190#"D6_iot_cloud_oc:oc_mqtt",
191```
192
193
194### 运行结果
195
196示例代码编译烧录后,按下开发板的RESET按键,通过串口助手查看日志,会打印连接到的Wifi热点信息。
197```
198<--System Init-->
199
200<--Wifi Init-->
201
202register wifi event succeed!
203
204+NOTICE:SCANFINISH
205WaitScanResult:wait success[1]s
206
207
208Select: 2 wireless, Waiting...
209
210+NOTICE:CONNECTED
211callback function for wifi connect
212
213WaitConnectResult:wait success[1]s
214WiFi connect succeed!
215
216begain to dhcp
217
218<-- DHCP state:Inprogress -->
219
220<-- DHCP state:OK -->
221
222server :
223 server_id : 192.168.0.1
224 mask : 255.255.255.0, 1
225 gw : 192.168.0.1
226 T0 : 7200
227 T1 : 3600
228 T2 : 6300
229clients <1> :
230 mac_idx mac addr state lease tries rto
231 0 801131801388 192.168.0.151 10 0 1 4
232
233```
234
235