1 /*
2  * Copyright (c) 2019 Winner Microelectronics Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author          Notes
8  * 2023-07-25     WCX1024979076   1st version
9  */
10 
11 #include <rtthread.h>
12 #include <string.h>
13 #include <rtdevice.h>
14 
15 #ifdef RT_USING_WIFI
16 #include "drv_wifi.h"
17 #include "esp_system.h"
18 #include "esp_wifi.h"
19 #include "esp_event.h"
20 #include "esp_log.h"
21 #include "esp_timer.h"
22 #include "nvs_flash.h"
23 #include "esp_private/wifi.h"
24 
25 #define DBG_LEVEL DBG_LOG
26 #define LOG_TAG  "DRV.WIFI"
27 #include <rtdbg.h>
28 
29 #define MAX_ADDR_LEN        (6)
30 
31 struct drv_wifi
32 {
33     struct rt_wlan_device *wlan;
34     wifi_interface_t wifi_if;
35     rt_uint8_t dev_addr[MAX_ADDR_LEN];
36 };
37 
38 static const struct rt_wlan_dev_ops ops;
39 static struct drv_wifi wifi_sta;
40 static struct drv_wifi wifi_ap;
41 
42 #define EXAMPLE_ESP_MAXIMUM_RETRY 5
43 #define DEFAULT_SCAN_LIST_SIZE 3
44 static int s_retry_num = 0;
45 
46 wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];
47 
48 static rt_err_t drv_wlan_scan_stop(struct rt_wlan_device *wlan);
49 
wifi_event_handler(void * arg,esp_event_base_t event_base,int32_t event_id,void * event_data)50 static void wifi_event_handler(void *arg, esp_event_base_t event_base,
51                                int32_t event_id, void *event_data)
52 {
53     if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_START) {
54         rt_wlan_dev_indicate_event_handle(wifi_ap.wlan, RT_WLAN_DEV_EVT_AP_START, RT_NULL);
55     } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STOP) {
56         rt_wlan_dev_indicate_event_handle(wifi_ap.wlan, RT_WLAN_DEV_EVT_AP_STOP, RT_NULL);
57     } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED) {
58         wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *) event_data;
59         rt_wlan_dev_indicate_event_handle(wifi_ap.wlan, RT_WLAN_DEV_EVT_AP_ASSOCIATED, RT_NULL);
60     } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED) {
61         wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *) event_data;
62         rt_wlan_dev_indicate_event_handle(wifi_ap.wlan, RT_WLAN_DEV_EVT_AP_DISASSOCIATED, RT_NULL);
63     } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
64         esp_wifi_connect();
65     } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
66         rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, RT_WLAN_DEV_EVT_CONNECT, RT_NULL);
67     } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
68         if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
69             esp_wifi_connect();
70             s_retry_num++;
71         } else {
72             rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, RT_WLAN_DEV_EVT_CONNECT_FAIL, RT_NULL);
73         }
74     } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) {
75         drv_wlan_scan_stop(RT_NULL);
76     }
77 }
78 
wifi_sta_receive(void * buffer,uint16_t len,void * eb)79 static esp_err_t wifi_sta_receive(void *buffer, uint16_t len, void *eb)
80 {
81     rt_wlan_dev_report_data(wifi_sta.wlan, buffer, len);
82     return RT_EOK;
83 }
84 
wifi_ap_receive(void * buffer,uint16_t len,void * eb)85 static esp_err_t wifi_ap_receive(void *buffer, uint16_t len, void *eb)
86 {
87     rt_wlan_dev_report_data(wifi_ap.wlan, buffer, len);
88     return RT_EOK;
89 }
90 
wifi_init_sta(void)91 void wifi_init_sta(void)
92 {
93 }
94 
wifi_init_softap(void)95 void wifi_init_softap(void)
96 {
97 }
98 
99 /* Initialize Wi-Fi as sta and set scan method */
drv_wlan_scan(struct rt_wlan_device * wlan,struct rt_scan_info * scan_info)100 static rt_err_t drv_wlan_scan(struct rt_wlan_device *wlan, struct rt_scan_info *scan_info)
101 {
102     ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
103     ESP_ERROR_CHECK(esp_wifi_start());
104     esp_wifi_scan_start(NULL, false);
105 }
106 
drv_wlan_init(struct rt_wlan_device * wlan)107 static rt_err_t drv_wlan_init(struct rt_wlan_device *wlan)
108 {
109     // 初始化时钟以及事件处理
110     esp_timer_init();
111     esp_event_loop_create_default();
112 
113     wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
114     ESP_ERROR_CHECK(esp_wifi_init(&cfg));
115 
116     esp_event_handler_instance_t instance_any_id;
117     ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
118                                                         ESP_EVENT_ANY_ID,
119                                                         &wifi_event_handler,
120                                                         NULL,
121                                                         &instance_any_id));
122 
123     // 注册收到内容回调
124     ESP_ERROR_CHECK(esp_wifi_internal_reg_rxcb(WIFI_IF_STA,  wifi_sta_receive));
125     ESP_ERROR_CHECK(esp_wifi_internal_reg_rxcb(WIFI_IF_AP,  wifi_ap_receive));
126 
127     return RT_EOK;
128 }
129 
drv_wlan_mode(struct rt_wlan_device * wlan,rt_wlan_mode_t mode)130 static rt_err_t drv_wlan_mode(struct rt_wlan_device *wlan, rt_wlan_mode_t mode)
131 {
132     if (mode == RT_WLAN_STATION) {
133         wifi_init_sta();
134     } else {
135         wifi_init_softap();
136     }
137     return RT_EOK;
138 }
139 
140 
drv_wlan_join(struct rt_wlan_device * wlan,struct rt_sta_info * sta_info)141 static rt_err_t drv_wlan_join(struct rt_wlan_device *wlan, struct rt_sta_info *sta_info)
142 {
143     wifi_config_t wifi_config = {
144         .sta = {
145             .ssid = "",
146             .password = "",
147             /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).
148              * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
149              * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
150              * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
151              */
152             .threshold.authmode = WIFI_AUTH_WPA_WPA2_PSK,
153             .sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
154         },
155     };
156     rt_memcpy(wifi_config.sta.ssid, sta_info->ssid.val, sta_info->ssid.len);
157     rt_memcpy(wifi_config.sta.password, sta_info->key.val, sta_info->key.len);
158     ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
159     ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
160     ESP_ERROR_CHECK(esp_wifi_start());
161     return RT_EOK;
162 }
163 
drv_wlan_softap(struct rt_wlan_device * wlan,struct rt_ap_info * ap_info)164 static rt_err_t drv_wlan_softap(struct rt_wlan_device *wlan, struct rt_ap_info *ap_info)
165 {
166     wifi_config_t wifi_config = {
167         .ap = {
168             .ssid = "",
169             .ssid_len = 0,
170             .channel = 3,
171             .password = "",
172             .max_connection = 3,
173             .authmode = WIFI_AUTH_WPA_WPA2_PSK,
174             .pmf_cfg = {
175                 .required = false,
176             },
177         },
178     };
179     rt_memcpy(wifi_config.ap.ssid, ap_info->ssid.val, ap_info->ssid.len);
180     rt_memcpy(wifi_config.ap.password, ap_info->key.val, ap_info->key.len);
181     wifi_config.ap.ssid_len = ap_info->ssid.len;
182     ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
183     ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
184     ESP_ERROR_CHECK(esp_wifi_start());
185 
186     drv_wlan_scan_stop(RT_NULL);
187     return RT_EOK;
188 }
189 
drv_wlan_disconnect(struct rt_wlan_device * wlan)190 static rt_err_t drv_wlan_disconnect(struct rt_wlan_device *wlan)
191 {
192     ESP_ERROR_CHECK(esp_wifi_disconnect());
193     return RT_EOK;
194 }
195 
drv_wlan_ap_stop(struct rt_wlan_device * wlan)196 static rt_err_t drv_wlan_ap_stop(struct rt_wlan_device *wlan)
197 {
198     return RT_EOK;
199 }
200 
drv_wlan_ap_deauth(struct rt_wlan_device * wlan,rt_uint8_t mac[])201 static rt_err_t drv_wlan_ap_deauth(struct rt_wlan_device *wlan, rt_uint8_t mac[])
202 {
203     return RT_EOK;
204 }
205 
drv_wlan_scan_stop(struct rt_wlan_device * wlan)206 static rt_err_t drv_wlan_scan_stop(struct rt_wlan_device *wlan)
207 {
208     struct rt_wlan_info wlan_info;
209     struct rt_wlan_buff buff;
210     uint16_t number = DEFAULT_SCAN_LIST_SIZE;
211     uint16_t ap_count = 0;
212 
213     memset(ap_info, 0, sizeof(ap_info));
214 
215     ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));
216     ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));
217     for (int i = 0; (i < DEFAULT_SCAN_LIST_SIZE) && (i < ap_count); i++) {
218         rt_memset(&wlan_info, 0, sizeof(wlan_info));
219         rt_memcpy(&wlan_info.bssid[0], ap_info[i].bssid, 6);
220         rt_memcpy(wlan_info.ssid.val, ap_info[i].ssid , strlen(ap_info[i].ssid));
221 
222         wlan_info.ssid.len = strlen(ap_info[i].ssid);
223         wlan_info.hidden = 0;
224         wlan_info.channel = (rt_int16_t)ap_info[i].primary;
225         wlan_info.rssi = -(char)(0x100 - ap_info[i].rssi);
226         wlan_info.band = RT_802_11_BAND_2_4GHZ;
227         wlan_info.security = SECURITY_UNKNOWN;
228 
229         buff.data = &wlan_info;
230         buff.len = sizeof(wlan_info);
231         rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, RT_WLAN_DEV_EVT_SCAN_REPORT, &buff);
232     }
233     esp_wifi_scan_stop();
234     return RT_EOK;
235 }
236 
drv_wlan_get_rssi(struct rt_wlan_device * wlan)237 static int drv_wlan_get_rssi(struct rt_wlan_device *wlan)
238 {
239     return 0;
240 }
241 
drv_wlan_set_powersave(struct rt_wlan_device * wlan,int level)242 static rt_err_t drv_wlan_set_powersave(struct rt_wlan_device *wlan, int level)
243 {
244     return RT_EOK;
245 }
246 
drv_wlan_get_powersave(struct rt_wlan_device * wlan)247 static int drv_wlan_get_powersave(struct rt_wlan_device *wlan)
248 {
249     return 0;
250 }
251 
drv_wlan_cfg_promisc(struct rt_wlan_device * wlan,rt_bool_t start)252 static rt_err_t drv_wlan_cfg_promisc(struct rt_wlan_device *wlan, rt_bool_t start)
253 {
254     return RT_EOK;
255 }
256 
drv_wlan_cfg_filter(struct rt_wlan_device * wlan,struct rt_wlan_filter * filter)257 static rt_err_t drv_wlan_cfg_filter(struct rt_wlan_device *wlan, struct rt_wlan_filter *filter)
258 {
259     return -RT_EINVAL;/* not support */
260 }
261 
drv_wlan_set_channel(struct rt_wlan_device * wlan,int channel)262 static rt_err_t drv_wlan_set_channel(struct rt_wlan_device *wlan, int channel)
263 {
264     return RT_EOK;
265 }
266 
drv_wlan_get_channel(struct rt_wlan_device * wlan)267 static int drv_wlan_get_channel(struct rt_wlan_device *wlan)
268 {
269     return 0;
270 }
271 
drv_wlan_set_country(struct rt_wlan_device * wlan,rt_country_code_t country_code)272 static rt_err_t drv_wlan_set_country(struct rt_wlan_device *wlan, rt_country_code_t country_code)
273 {
274     return RT_EOK;
275 }
276 
drv_wlan_get_country(struct rt_wlan_device * wlan)277 static rt_country_code_t drv_wlan_get_country(struct rt_wlan_device *wlan)
278 {
279     return 0;   //RT_EOK;
280 }
281 
drv_wlan_set_mac(struct rt_wlan_device * wlan,rt_uint8_t mac[])282 static rt_err_t drv_wlan_set_mac(struct rt_wlan_device *wlan, rt_uint8_t mac[])
283 {
284     return RT_EOK;
285 }
286 
drv_wlan_get_mac(struct rt_wlan_device * wlan,rt_uint8_t mac[])287 static rt_err_t drv_wlan_get_mac(struct rt_wlan_device *wlan, rt_uint8_t mac[])
288 {
289     return RT_EOK;
290 }
291 
drv_wlan_recv(struct rt_wlan_device * wlan,void * buff,int len)292 static int drv_wlan_recv(struct rt_wlan_device *wlan, void *buff, int len)
293 {
294     return RT_EOK;
295 }
296 
drv_wlan_send(struct rt_wlan_device * wlan,void * buff,int len)297 static int drv_wlan_send(struct rt_wlan_device *wlan, void *buff, int len)
298 {
299     struct drv_wifi* wifi = wlan->user_data;
300     esp_wifi_internal_tx(wifi->wifi_if, buff, len);
301     return RT_EOK;
302 }
303 
304 static const struct rt_wlan_dev_ops ops =
305 {
306     .wlan_init              = drv_wlan_init,
307     .wlan_mode              = drv_wlan_mode,
308     .wlan_scan              = drv_wlan_scan,
309     .wlan_join              = drv_wlan_join,
310     .wlan_softap            = drv_wlan_softap,
311     .wlan_disconnect        = drv_wlan_disconnect,
312     .wlan_ap_stop           = drv_wlan_ap_stop,
313     .wlan_ap_deauth         = drv_wlan_ap_deauth,
314     .wlan_scan_stop         = drv_wlan_scan_stop,
315     .wlan_get_rssi          = drv_wlan_get_rssi,
316     .wlan_set_powersave     = drv_wlan_set_powersave,
317     .wlan_get_powersave     = drv_wlan_get_powersave,
318     .wlan_cfg_promisc       = drv_wlan_cfg_promisc,
319     .wlan_cfg_filter        = drv_wlan_cfg_filter,
320     .wlan_set_channel       = drv_wlan_set_channel,
321     .wlan_get_channel       = drv_wlan_get_channel,
322     .wlan_set_country       = drv_wlan_set_country,
323     .wlan_get_country       = drv_wlan_get_country,
324     .wlan_set_mac           = drv_wlan_set_mac,
325     .wlan_get_mac           = drv_wlan_get_mac,
326     .wlan_recv              = drv_wlan_recv,
327     .wlan_send              = drv_wlan_send,
328 };
329 
rt_hw_wifi_init(void)330 int rt_hw_wifi_init(void)
331 {
332     // 初始化nvs_flash
333     esp_err_t esp_ret = nvs_flash_init();
334 
335     if (esp_ret == ESP_ERR_NVS_NO_FREE_PAGES || esp_ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
336         ESP_ERROR_CHECK(nvs_flash_erase());
337         esp_ret = nvs_flash_init();
338     }
339     ESP_ERROR_CHECK(esp_ret);
340 
341     // 向系统注册
342     static struct rt_wlan_device wlan;
343     static struct rt_wlan_device wlan2;
344 
345     rt_memset(&wifi_sta, 0, sizeof(wifi_sta));
346     wifi_sta.wifi_if = WIFI_IF_STA;
347     rt_err_t ret = rt_wlan_dev_register(&wlan, RT_WLAN_DEVICE_STA_NAME, &ops, 0, &wifi_sta);
348     wifi_sta.wlan = &wlan;
349 
350     rt_memset(&wifi_ap, 0, sizeof(wifi_ap));
351     wifi_ap.wifi_if = WIFI_IF_AP;
352     ret |= rt_wlan_dev_register(&wlan2, RT_WLAN_DEVICE_AP_NAME, &ops, 0, &wifi_ap);
353     wifi_ap.wlan = &wlan2;
354 
355     return ret;
356 }
357 
358 INIT_DEVICE_EXPORT(rt_hw_wifi_init);
359 
360 #endif /* RT_USING_WIFI */
361