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 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 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 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 444