1@page page_device_wlan WLAN Device
2
3With the rapid development of the Internet of Things, more and more embedded devices are equipped with WIFI wireless network devices. In order to be able to manage WIFI network devices, RT-Thread introduces a WLAN device management framework. This framework has many features to control and manage WIFI, providing developers with many conveniences for using WIFI devices.
4
5# Introduction to the WLAN Framework
6
7The WLAN framework is a set of middleware developed by RT-Thread for managing WIFI. Connect to the specific WIFI driver, control the WIFI connection disconnection, scan and other operations. Support different applications, provide WIFI control, events, data diversion and other operations for the application, and provide a unified WIFI control interface for the upper application. The WLAN framework consists of three main parts. The DEV driver interface layer provides a unified API for the WLAN framework. Manage layer provides users with specific functions such as WIFI scanning, connection, and disconnection. Protocol is responsible for processing the data stream generated on the WIFI. Different protocols such as LWIP can be mounted according to different usage scenarios. It has the characteristics of simple use, complete functions, convenient docking and strong compatibility.
8
9The following figure is a hierarchical diagram of the WIFI framework:
10
11![WIFI Framework](figures/an0026_1.png)
12
13The First Part: `APP`, the application layer. It is a specific application based on the WLAN framework, such as WiFi-related shell commands.
14
15The Second Part:  `Airkiss and Voice`, the network configuration layer. Provide functions such as using wireless or sound waves to configure the network.
16
17The Third Part: `WLAN Manager`, the WLAN management layer. Ability to control and manage WLAN devices. It has functions related to WLAN control, such as setting mode, connecting hotspots, disconnecting hotspots, enabling hotspots, scanning hotspots, etc. It also provides management functions such as reconnection after disconnection and automatic hotspot switching.
18
19The Fourth Part: `WLAN Protocol`, the protocol layer. The data stream is submitted to a specific protocol for resolution, and the user can specify to communicate using different protocols.
20
21The Fifth Part: `WLAN Config`, the parameter management layer. Manage hotspot information and passwords for successful connections and write them to non-volatile storage media.
22
23The Sixth Part: `WLAN Device`, the driver interface layer. Connect to specific WLAN hardware and provide unified APIs for management.
24
25## Functions
26
27* Automatic Connection: After using automatic connection function, as long as the WIFI is disconnected, the hotspot information of the previous successful connection will be automatically read, and the hotspot will be connected. If a hotspot connection fails, switch to the next hotspot to connect until the connection is successful. The hotspot information used by the automatic connection is sequentially tried in the order of the success of the connection, and the hotspot information of the latest connection success is preferentially used. After the connection is successful, the hotspot information is cached first, and use it first when reconnecting after the next disconnection.
28* Parameter storage: Stores the WIFI parameters for successful connection. The WIFI parameter will be cached in the memory. If the external non-volatile storage interface is configured, it will be stored in the external storage medium. Users can implement the `struct rt_wlan_cfg_ops` structure according to his actual situation and save the parameters anywhere. The cached parameters mainly provide hotspot information for automatic connections. When WIFI is unconnected, it will read the cached parameters and try to connect.
29* WIFI control: Provide complete WIFI control APIs, scanning, connection, hotspot, etc. Provide WIFI related status callback events, disconnect, connection, connection failure, etc. Provide users with an easy to use WIFI management APIs.
30* Shell command: You can enter the command in Msh to control WIFI to perform scanning, connecting, disconnecting and other actions. Print debugging information such as WIFI status.
31
32## Configuration
33
34Use `menuconfig` command in ENV to enter the WLAN configuration interface by following the menu:
35
36```c
37RT-Thread Components ->  Device Drivers -> Using WiFi ->
38```
39
40Configuration options are described in detail as follows:
41
42```c
43[*] Using Wi-Fi framework                /* Using Wi-Fi framework */
44(wlan0) The WiFi device name for station /* The default name for station */
45(wlan1) The WiFi device name for ap      /* The default name for ap */
46(lwip) Default transport protocol        /* Default protocol */
47(10000) Set scan timeout time(ms)        /* Scan timeout time */
48(10000) Set connect timeout time(ms)     /* Connect timeout time */
49(32)  SSID name maximum length           /* Maximum length of SSID name */
50(32)  Maximum password length            /* Maximum length of password */
51[*]   Automatic sorting of scan results  /* Automatic sorting of scan results */
52(3)   Maximum number of WiFi information automatically saved /* Maximum number of WiFi information automatically saved */
53(wlan_job) WiFi work queue thread name   /* WiFi work queue thread name */
54(2048) wifi work queue thread size       /* wifi work queue thread size */
55(22)  WiFi work queue thread priority    /* WiFi work queue thread priority */
56(2)   Maximum number of driver events    /* Maximum number of driver events in dev layer */
57[ ]   Forced use of PBUF transmission    /* Forced use of PBUF transmission */
58[ ]   Enable WLAN Debugging Options      /* Enable WLAN Debugging Options */
59```
60
61# Access Wi-Fi Devices
62
63The application accesses the WLAN device hardware through the WLAN device management interface, and the relevant interfaces are as follows:
64
65| Fuctions | **Description**                 |
66| -------------------- | ---------------------------- |
67| rt_wlan_prot_attach()           | Specify the WLAN protocol attached |
68| rt_wlan_scan_sync()             | Synchronized WLAN Scan |
69| rt_wlan_connect()               | Synchronized Hotspot Connection |
70| rt_wlan_disconnect()            | Synchronized Hotspot Disconnection |
71| rt_wlan_config_autoreconnect()  | Configuration automatic reconnection mode |
72
73## Specify Protocol
74
75```c
76rt_err_t rt_wlan_prot_attach(const char *dev_name, const char *prot_name);
77```
78
79| **Parameter**                  | **D**escription                     |
80| ----------------------------- | ---------------------------------- |
81| dev_name                       | WLAN device name            |
82| prot_name                     | Protocol name, possible values: RT_WLAN_PROT_LWIP, indicates the protocol type LWIP |
83| Return                 | **--**                               |
84| -RT_ERROR                     | Execution failed            |
85| RT_EOK                        | Execution succeed           |
86
87## Synchronized WLAN Scan
88
89```c
90struct rt_wlan_scan_result *rt_wlan_scan_sync(void);
91```
92
93| **Return**                   | **Description** |
94| ---------- | ------------------------------- |
95| rt_wlan_scan_result           | Scan Result              |
96
97The scan result is a structure as follows:
98
99```c
100struct rt_wlan_scan_result
101{
102    rt_int32_t num;             /* info number */
103    struct rt_wlan_info *info;  /* info pointer */
104};
105```
106
107## Synchronized Hotspot Connection
108
109```c
110rt_err_t rt_wlan_connect(const char *ssid, const char *password);
111```
112
113| **Parameter**               | **Description**                     |
114| ----------------------------- | ---------------------------------- |
115| ssid                          | WIFI name                       |
116| password                      | WIFI password                     |
117| Return                    | **--**                               |
118| -RT_EINVAL                    | Parameter error             |
119| -RT_EIO                       | Unregistered device       |
120| -RT_ERROR                     | Connection failed           |
121| RT_EOK                        | Connection successful  |
122
123## Synchronized Hotspot Disconnection
124
125```c
126rt_err_t rt_wlan_disconnect(void);
127```
128
129| Return                    | **Description**                     |
130| ----------------------------- | ---------------------------------- |
131| -RT_EIO                       | Unregistered device        |
132| -RT_ENOMEM                    | Not enough memory     |
133| -RT_ERROR                     | Disconnection failed      |
134| RT_EOK                        | Disconnection successful    |
135
136## Automatic Reconnection Mode Configuration
137
138```c
139void rt_wlan_config_autoreconnect(rt_bool_t enable);
140```
141
142| **P**arameter                  | **Description**                     |
143| ----------------------------- | ---------------------------------- |
144| enable                        | enable or disable automatic reconnection |
145
146# FinSH Command
147
148Using shell commands can help us quickly debug WiFi-related features. The wifi related shell commands are as follows:
149
150```c
151wifi                           /* Print help */
152wifi help                      /* View help */
153wifi join SSID [PASSWORD]      /* Connect wifi.if SSDI is empty, use configuration to connect automatically */
154wifi ap   SSID [PASSWORD]      /* Create hotspot */
155wifi scan                      /* Scan all hotspots */
156wifi disc                      /* Disconnnect */
157wifi ap_stop                   /* Stop hotspot */
158wifi status                    /* Print wifi status sta + ap */
159wifi smartconfig               /* Start to configure network function */
160```
161
162## WiFi Scan
163
164The wifi scan command is `wifi scan`. After the wifi scan command is executed, the surrounding hotspot information will be printed on the terminal. Through the printed hotspot information, you can see multiple attributes such as SSID and MAC address.
165
166Enter the command in msh and the scan results are as follows:
167
168```c
169wifi scan
170SSID                                   MAC            security    rssi chn Mbps
171------------------------------- -----------------  -------------- ---- --- ----
172rtt_test_ssid_1                 c0:3d:46:00:3e:aa  OPEN           -14    8  300
173test_ssid                       3c:f5:91:8e:4c:79  WPA2_AES_PSK   -18    6   72
174rtt_test_ssid_2                 ec:88:8f:88:aa:9a  WPA2_MIXED_PSK -47    6  144
175rtt_test_ssid_3                 c0:3d:46:00:41:ca  WPA2_MIXED_PSK -48    3  300
176```
177
178## WiFi Connection
179
180The wifi scan command is `wifi join`. The command needs to be followed by the hotspot name and hotspot password. If the hotspot does not have a password, you may not enter this item. After the WiFi connection command is executed, if the hotspot exists and the password is correct, the board will connect to the hotspot and obtain the IP address. After the network connection is successful, you can use `socket` sockets for network communication.
181
182An example of using the wifi connection command is as follows. After the connection is successful, the obtained IP address will be printed on the terminal as follows:
183
184```c
185wifi join ssid_test 12345678
186[I/WLAN.mgnt] wifi connect success ssid:ssid_test
187[I/WLAN.lwip] Got IP address : 192.168.1.110
188```
189
190## WiFi Disconnection
191
192The command to disconnect WiFi is  `wifi disc`. After the WiFi disconnect command is executed, the development board will disconnect from the hotspot.
193
194The WiFi disconnect command usage example is as follows. After the disconnection is successful, the following information will be printed on the terminal as shown below.
195
196```c
197wifi disc
198[I/WLAN.mgnt] disconnect success!
199```
200
201# Example for WLAN Device Usage
202
203## WiFi Scan
204
205The following code will show a WiFi sync scan, and then print the results on the terminal. First perform WIFI initialization, and then execute the WIFI scan function `rt_wlan_scan_sync`, this function is synchronous, the number of scans and results returned by the function. In this example, the scanned hotspot name will be printed.
206
207```c
208#include <rthw.h>
209#include <rtthread.h>
210
211#include <dev_wlan_mgnt.h>
212#include <dev_wlan_prot.h>
213#include <dev_wlan_cfg.h>
214
215void wifi_scan(void)
216{
217    struct rt_wlan_scan_result *result;
218    int i = 0;
219
220    /* Configuring WLAN device working mode */
221    rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);
222    /* WiFi scan */
223    result = rt_wlan_scan_sync();
224    /* Print scan results */
225    rt_kprintf("scan num:%d\n", result->num);
226    for (i = 0; i < result->num; i++)
227    {
228        rt_kprintf("ssid:%s\n", result->info[i].ssid.val);
229    }
230}
231
232int scan(int argc, char *argv[])
233{
234    wifi_scan();
235    return 0;
236}
237MSH_CMD_EXPORT(scan, scan test.);
238```
239
240The results are as follows:
241
242![Scan](figures/an0026_3.png)
243
244## WiFi Connection and Disconnection
245
246The code below will show a WiFi sync connection. Initialize WIFI first, and then create a semaphore for waiting for the `RT_WLAN_EVT_READY` event. Register the callback function of the event that needs attention, execute the  `rt_wlan_connect` wifi connection function, and return value will indicate whether the connection has been successful. If the WiFi connection succeeds, it needs to wait for the network to get the IP address before communication. Use the semaphore created in advance to wait for the network to be ready. Once the network is ready, it will be able to communicate.
247
248After connecting to WIFI, wait for a while and then execute `rt_wlan_disconnect` to disconnect. The disconnect operation is blocked, and the return value indicates whether the disconnection was successful.
249
250```c
251#include <rthw.h>
252#include <rtthread.h>
253
254#include <dev_wlan_mgnt.h>
255#include <dev_wlan_prot.h>
256#include <dev_wlan_cfg.h>
257
258#define WLAN_SSID               "SSID-A"
259#define WLAN_PASSWORD           "12345678"
260#define NET_READY_TIME_OUT       (rt_tick_from_millisecond(15 * 1000))
261
262static rt_sem_t net_ready = RT_NULL;
263
264static void
265wifi_ready_callback(int event, struct rt_wlan_buff *buff, void *parameter)
266{
267    rt_kprintf("%s\n", __FUNCTION__);
268    rt_sem_release(net_ready);
269}
270
271static void
272wifi_connect_callback(int event, struct rt_wlan_buff *buff, void *parameter)
273{
274    rt_kprintf("%s\n", __FUNCTION__);
275    if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info)))
276    {
277        rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);
278    }
279}
280
281static void
282wifi_disconnect_callback(int event, struct rt_wlan_buff *buff, void *parameter)
283{
284    rt_kprintf("%s\n", __FUNCTION__);
285    if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info)))
286    {
287        rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);
288    }
289}
290
291static void
292wifi_connect_fail_callback(int event, struct rt_wlan_buff *buff, void *parameter)
293{
294    rt_kprintf("%s\n", __FUNCTION__);
295    if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info)))
296    {
297        rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);
298    }
299}
300
301rt_err_t wifi_connect(void)
302{
303    rt_err_t result = RT_EOK;
304
305    /* Configuring WLAN device working mode */
306    rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);
307    /* station connect */
308    rt_kprintf("start to connect ap ...\n");
309    net_ready = rt_sem_create("net_ready", 0, RT_IPC_FLAG_FIFO);
310    rt_wlan_register_event_handler(RT_WLAN_EVT_READY,
311            wifi_ready_callback, RT_NULL);
312    rt_wlan_register_event_handler(RT_WLAN_EVT_STA_CONNECTED,
313            wifi_connect_callback, RT_NULL);
314    rt_wlan_register_event_handler(RT_WLAN_EVT_STA_DISCONNECTED,
315            wifi_disconnect_callback, RT_NULL);
316    rt_wlan_register_event_handler(RT_WLAN_EVT_STA_CONNECTED_FAIL,
317            wifi_connect_fail_callback, RT_NULL);
318
319    /* connect wifi */
320    result = rt_wlan_connect(WLAN_SSID, WLAN_PASSWORD);
321
322    if (result == RT_EOK)
323    {
324        /* waiting for IP to be got successfully  */
325        result = rt_sem_take(net_ready, NET_READY_TIME_OUT);
326        if (result == RT_EOK)
327        {
328            rt_kprintf("networking ready!\n");
329        }
330        else
331        {
332            rt_kprintf("wait ip got timeout!\n");
333        }
334        rt_wlan_unregister_event_handler(RT_WLAN_EVT_READY);
335        rt_sem_delete(net_ready);
336
337        rt_thread_delay(rt_tick_from_millisecond(5 * 1000));
338        rt_kprintf("wifi disconnect test!\n");
339        /* disconnect */
340        result = rt_wlan_disconnect();
341        if (result != RT_EOK)
342        {
343            rt_kprintf("disconnect failed\n");
344            return result;
345        }
346        rt_kprintf("disconnect success\n");
347    }
348    else
349    {
350        rt_kprintf("connect failed!\n");
351    }
352    return result;
353}
354
355int connect(int argc, char *argv[])
356{
357    wifi_connect();
358    return 0;
359}
360MSH_CMD_EXPORT(connect, connect test.);
361```
362
363The results are as follows:
364
365![Disconnection](figures/an0026_4.png)
366
367## WiFi Auto Reconnection when Turn On
368
369First enable the automatic reconnection function, use the command line to connect to the hotspot A, and connect another hotspot B. After waiting for a few seconds, power off hotspot B, the system will automatically retry connecting B hotspot. At this time, B hotspot connection can not be connected, and the system automatically switches hotspot A to connect. After the connection is successful, the system stops connecting.
370
371```c
372#include <rthw.h>
373#include <rtthread.h>
374
375#include <dev_wlan_mgnt.h>
376#include <dev_wlan_prot.h>
377#include <dev_wlan_cfg.h>
378
379static void
380wifi_ready_callback(int event, struct rt_wlan_buff *buff, void *parameter)
381{
382    rt_kprintf("%s\n", __FUNCTION__);
383}
384
385static void
386wifi_connect_callback(int event, struct rt_wlan_buff *buff, void *parameter)
387{
388    rt_kprintf("%s\n", __FUNCTION__);
389    if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info)))
390    {
391        rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);
392    }
393}
394
395static void
396wifi_disconnect_callback(int event, struct rt_wlan_buff *buff, void *parameter)
397{
398    rt_kprintf("%s\n", __FUNCTION__);
399    if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info)))
400    {
401        rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);
402    }
403}
404
405static void
406wifi_connect_fail_callback(int event, struct rt_wlan_buff *buff, void *parameter)
407{
408    rt_kprintf("%s\n", __FUNCTION__);
409    if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info)))
410    {
411        rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);
412    }
413}
414
415int wifi_autoconnect(void)
416{
417    /* Configuring WLAN device working mode */
418    rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);
419    /* Start automatic connection */
420    rt_wlan_config_autoreconnect(RT_TRUE);
421    /* register event */
422    rt_wlan_register_event_handler(RT_WLAN_EVT_READY,
423            wifi_ready_callback, RT_NULL);
424    rt_wlan_register_event_handler(RT_WLAN_EVT_STA_CONNECTED,
425            wifi_connect_callback, RT_NULL);
426    rt_wlan_register_event_handler(RT_WLAN_EVT_STA_DISCONNECTED,
427            wifi_disconnect_callback, RT_NULL);
428    rt_wlan_register_event_handler(RT_WLAN_EVT_STA_CONNECTED_FAIL,
429            wifi_connect_fail_callback, RT_NULL);
430    return 0;
431}
432
433int auto_connect(int argc, char *argv[])
434{
435    wifi_autoconnect();
436    return 0;
437}
438MSH_CMD_EXPORT(auto_connect, auto connect test.);
439```
440
441The results are as follows:
442
443![Autoconnection](figures/an0026_5.png)
444