1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 #include <drivers/u_ld.h>
6 #include <vfsdev/wifi_dev.h>
7 #if(AOS_COMP_USERVICE > 0)
8 #include <uservice/uservice.h>
9 #include <uservice/eventid.h>
10 #endif
11 #include <aos/hal/wifi.h>
12 #if LWIP_ETHERNETIF && !LWIP_SUPPORT
13 #include <lwip/def.h>
14 #include <lwip/netdb.h>
15 #endif
16 #include "aos/vfs.h"
17 #include "fcntl.h"
18 #include "plat_types.h"
19 #include "bwifi_interface.h"
20 #include "bes_sniffer.h"
21 
22 typedef enum {
23     SCAN_NORMAL,
24     SCAN_SPECIFIED
25 } scan_type_t;
26 
27 static struct {
28     uint8_t wifi_started:1;
29     uint8_t resetting:1;
30     uint8_t sta_connected:1;
31     uint8_t sta_got_ip:1;
32     uint8_t sap_started:1;
33     uint8_t sap_connected:1;
34     uint8_t smart_config:1;
35     uint8_t zero_config:1;
36 
37     struct {
38         int ap_num;
39         ap_list_t ap_list[3];
40     } scan_req;
41 
42     struct {
43         uint8_t bssid[6];
44         wifi_ip_stat_t ip_stat;
45     } network;
46 
47     netdev_t* dev;
48 
49 } wifi_status;
50 
51 static monitor_data_cb_t promisc_cb;
52 static monitor_data_cb_t mgnt_frame_cb;
53 
wifi_get_netif(netdev_t * dev,wifi_mode_t mode)54 struct netif *wifi_get_netif(netdev_t *dev, wifi_mode_t mode)
55 {
56 #if LWIP_ETHERNETIF && !LWIP_SUPPORT
57     if (mode == WIFI_MODE_STA)
58         return bwifi_get_netif(WIFI_IF_STATION);
59     else if (mode == WIFI_MODE_AP)
60         return bwifi_get_netif(WIFI_IF_SOFTAP);
61 #endif
62     return NULL;
63 }
64 
on_wifi_connect(WIFI_USER_EVT_ID event_id,void * arg)65 static void on_wifi_connect(WIFI_USER_EVT_ID event_id, void *arg)
66 {
67     printf("%s event_id:%d\n", __func__, event_id);
68 
69     if (event_id == WIFI_USER_EVT_CONN_INTER_STATE) {
70         BWIFI_CONNECT_INTER_STATE state = *(BWIFI_CONNECT_INTER_STATE *)arg;
71         int event;
72 
73         switch (state) {
74         case INTER_STATE_AUTHENTICATING:
75             event = EVENT_WIFI_AUTHENTICATING;
76             break;
77         case INTER_STATE_AUTH_REJECT:
78             event = EVENT_WIFI_AUTH_REJECT;
79             break;
80         case INTER_STATE_AUTH_TIMEOUT:
81             event = EVENT_WIFI_AUTH_TIMEOUT;
82             break;
83         case INTER_STATE_ASSOCIATING:
84             event = EVENT_WIFI_ASSOCIATING;
85             break;
86         case INTER_STATE_ASSOC_REJECT:
87             event = EVENT_WIFI_ASSOC_REJECT;
88             break;
89         case INTER_STATE_ASSOC_TIMEOUT:
90             event = EVENT_WIFI_ASSOC_TIMEOUT;
91             break;
92         case INTER_STATE_ASSOCIATED:
93             event = EVENT_WIFI_ASSOCIATED;
94             break;
95         case INTER_STATE_4WAY_HANDSHAKE:
96             event = EVENT_WIFI_4WAY_HANDSHAKE;
97             break;
98         case INTER_STATE_HANDSHAKE_FAIL:
99             event = EVENT_WIFI_HANDSHAKE_FAILED;
100             break;
101         case INTER_STATE_GROUP_HANDSHAKE:
102             event = EVENT_WIFI_GROUP_HANDSHAKE;
103             break;
104         default:
105             /* Unhandled intermediate states */
106             return;
107         }
108 #if 0
109         if (m->ev_cb && m->ev_cb->stat_chg) {
110             m->ev_cb->stat_chg(m, event, NULL);
111         }
112 #endif
113         event_publish(event, NULL);
114     } else if (event_id == WIFI_USER_EVT_CONNECTED) {
115         uint8_t *bssid = (uint8_t *)arg;
116 
117         wifi_status.sta_connected = 1;
118         memcpy(wifi_status.network.bssid, bssid, 6);
119 #if 0
120         if (m->ev_cb && m->ev_cb->stat_chg) {
121             m->ev_cb->stat_chg(m, NOTIFY_WIFI_CONNECTED, NULL);
122         }
123 #endif
124         event_publish(EVENT_WIFI_CONNECTED, wifi_get_netif(wifi_status.dev, WIFI_MODE_STA));
125 #if LWIP_SUPPORT
126     } else if (event_id == WIFI_USER_EVT_GOT_IP) {
127         struct ip_info *ip = (struct ip_info *)arg;
128 
129         wifi_status.sta_got_ip = 1;
130         snprintf(wifi_status.network.ip_stat.ip,
131                  sizeof(wifi_status.network.ip_stat.ip),
132                  "%s", inet_ntoa(ip->ip));
133         snprintf(wifi_status.network.ip_stat.mask,
134                  sizeof(wifi_status.network.ip_stat.mask),
135                  "%s", inet_ntoa(ip->netmask));
136         snprintf(wifi_status.network.ip_stat.gate,
137                  sizeof(wifi_status.network.ip_stat.gate),
138                  "%s", inet_ntoa(ip->gw));
139 #if 0
140         if (m->ev_cb && m->ev_cb->ip_got) {
141             m->ev_cb->ip_got(m, &wifi_status.network.ip_stat, NULL);
142         }
143         if (m->ev_cb && m->ev_cb->para_chg) {
144             memcpy(info.bssid, wifi_status.network.bssid, 6);
145             m->ev_cb->para_chg(m, &info, NULL, 0, NULL);
146         }
147 #endif
148 #endif
149     }
150 }
151 
on_wifi_disconnect(WIFI_USER_EVT_ID event_id,void * arg)152 static void on_wifi_disconnect(WIFI_USER_EVT_ID event_id, void *arg)
153 {
154     printf("%s event_id:%d\n", __func__, event_id);
155     if (event_id == WIFI_USER_EVT_DISCONNECTED) {
156         uint8_t reason = *(uint8_t *)arg;
157 
158         wifi_status.sta_connected = 0;
159         wifi_status.sta_got_ip = 0;
160         printf("wifi disconnected (reason=%d, locally_generated=%d)\n",
161                reason & 0x7F, (reason & BIT(7)) >> 7);
162 #if 0
163         if (m->ev_cb && m->ev_cb->stat_chg) {
164             m->ev_cb->stat_chg(m, NOTIFY_WIFI_DISCONNECTED, &reason);
165         }
166 #endif
167         event_publish(EVENT_WIFI_DISCONNECTED, &reason);
168     }
169 }
170 
on_fatal_error(WIFI_USER_EVT_ID event_id,void * arg)171 static void on_fatal_error(WIFI_USER_EVT_ID event_id, void *arg)
172 {
173     printf("%s event_id:%d\n", __func__, event_id);
174 
175     if (event_id == WIFI_USER_EVT_FATAL_ERROR) {
176         uint8 rst_flag = ((BWIFI_FATAL_ERROR_RESET_T *)arg)->rst_flag;
177         uint16 error = ((BWIFI_FATAL_ERROR_RESET_T *)arg)->error_cause;
178         BWIFI_LMAC_STATUS_DUMP_T dump_info =
179             ((BWIFI_FATAL_ERROR_RESET_T *)arg)->dump_info;
180         char str_buf[300];
181         size_t nbytes;
182         ssize_t written_bytes;
183         const char *pfile = "/data/wifi_reset_reports";
184         int fd;
185 
186         if (rst_flag == 1) {
187             wifi_status.resetting = 1;
188             printf("Bottom layer crashed, wifi card will be reset...\n");
189 #if 0
190             if (m->ev_cb && m->ev_cb->fatal_err) {
191                 m->ev_cb->fatal_err(m, NULL);
192             }
193 #endif
194             nbytes = snprintf(str_buf, sizeof(str_buf),
195                      "errorCode=0x%04x\ndumpInfo=0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x",
196                      error,
197                      dump_info.pac_rxc_rx_buf_in_ptr,
198                      dump_info.pac_rxc_rx_buf_out_ptr,
199                      dump_info.scheduler_events,
200                      dump_info.lmac_pc0,
201                      dump_info.lmac_pc1,
202                      dump_info.lmac_lr,
203                      dump_info.lmac_sp,
204                      dump_info.pac_ntd_status_peek,
205                      dump_info.pac_txc_status,
206                      dump_info.QUEUE_0_CONTROL,
207                      dump_info.QUEUE_1_CONTROL,
208                      dump_info.QUEUE_2_CONTROL,
209                      dump_info.QUEUE_3_CONTROL,
210                      dump_info.wlan_sw_override_1,
211                      dump_info.tsq_in_prog,
212                      dump_info.tsq_in_cmpl);
213 
214             if (nbytes <= 0) {
215                 printf("snprintf fail, return %d", nbytes);
216                 return;
217             }
218 
219             aos_vfs_init();
220             fd = aos_open(pfile, O_CREAT | O_RDWR);
221             if (fd < 0) {
222                 printf("Failed to open file %s (%d)\n", pfile, fd);
223                 return;
224             }
225             written_bytes = aos_write(fd, str_buf, nbytes);
226             if (written_bytes < 0) {
227                 printf("Failed to write file %s\n", pfile);
228             } else if (written_bytes != nbytes) {
229                 printf("Incompletely write file %s, nbytes:%d, written_bytes:%d\n",
230                        pfile, nbytes, written_bytes);
231             }
232             aos_close(fd);
233         } else if (rst_flag == 2) {
234             wifi_status.resetting = 0;
235             printf("wifi card is completely reset !!!\n");
236 #if 0
237             if (m->ev_cb && m->ev_cb->fatal_err) {
238                 m->ev_cb->fatal_err(m, NULL);
239             }
240 #endif
241         }
242     }
243 }
244 
haas1000_wifi_init(netdev_t * dev)245 static int haas1000_wifi_init(netdev_t *dev)
246 {
247     static int inited;
248     int ret;
249 
250     if (inited)
251         return 0;
252 
253     ret = bwifi_init();
254     if (ret) {
255         printf("bwifi init fail\n");
256         return -1;
257     }
258 
259     /* Register event callbacks */
260     bwifi_reg_user_evt_handler(WIFI_USER_EVT_CONN_INTER_STATE, on_wifi_connect);
261     bwifi_reg_user_evt_handler(WIFI_USER_EVT_CONNECTED, on_wifi_connect);
262     bwifi_reg_user_evt_handler(WIFI_USER_EVT_GOT_IP, on_wifi_connect);
263     bwifi_reg_user_evt_handler(WIFI_USER_EVT_DISCONNECTED, on_wifi_disconnect);
264     bwifi_reg_user_evt_handler(WIFI_USER_EVT_FATAL_ERROR, on_fatal_error);
265 
266     inited = 1;
267     wifi_status.wifi_started = 1;
268     wifi_status.dev = dev;
269     printf("wifi init success!!\n");
270     return 0;
271 };
272 
haas1000_wifi_deinit(netdev_t * dev)273 static int haas1000_wifi_deinit(netdev_t *dev)
274 {
275     return 0;
276 }
277 
haas1000_wifi_get_mac_addr(netdev_t * dev,uint8_t * mac)278 static int haas1000_wifi_get_mac_addr(netdev_t *dev, uint8_t *mac)
279 {
280     if (!mac) {printf("%s: invalid argument!\n", __func__); return -1;}
281     bwifi_get_own_mac(mac);
282     return 0;
283 };
284 
haas1000_wifi_set_mac_addr(netdev_t * dev,const uint8_t * mac)285 static int haas1000_wifi_set_mac_addr(netdev_t *dev, const uint8_t *mac)
286 {
287     printf("WiFi HAL %s not implemeted yet!\n", __func__);
288     return -1;
289 };
290 
wifi_connect_task(void * arg)291 static void wifi_connect_task(void *arg)
292 {
293     int ret = 0;
294     wifi_config_t *init_para = (wifi_config_t*)arg;
295     if (!init_para)
296         return;
297     ret = bwifi_connect_to_ssid(init_para->ssid, init_para->password, 0, 0, NULL);
298     if (ret) {
299         printf("wifi connect to %s fail:%d\n", init_para->ssid, ret);
300         event_publish(EVENT_WIFI_HANDSHAKE_FAILED, NULL);
301 #if 0
302         if (m->ev_cb && m->ev_cb->connect_fail) {
303             m->ev_cb->connect_fail(m, ret, NULL);
304         }
305 #endif
306     }
307     aos_free(init_para);
308     //aos_task_exit(0);
309     osThreadExitPub();
310 }
311 
start_ap(netdev_t * dev,const char * ssid,const char * passwd,int interval,int hide)312 static int start_ap(netdev_t *dev,
313                     const char *ssid,
314                     const char *passwd, int interval, int hide)
315 {
316 #ifdef __AP_MODE__
317     BWIFI_SEC_TYPE_T sec;
318 
319     printf("start_ap ssid:%s, pwd:%s, beacon_int:%d, hidden:%d\n", ssid, passwd, interval, hide);
320 
321     if (!passwd || !strlen(passwd))
322         sec = SECURITY_NONE;
323     else
324         sec = SECURITY_WPA2;
325 
326     if (bwifi_set_softap_config(ssid, 0, hide, sec, passwd)) {
327         printf("Softap %s config failed\n", ssid);
328         return -1;
329     }
330 
331     if (bwifi_softap_start()) {
332         printf("Softap %s start failed\n", ssid);
333         return -2;
334     }
335 
336     printf("Softap %s start success!!\n", ssid);
337     wifi_status.sap_started = 1;
338     event_publish(EVENT_WIFI_AP_UP, wifi_get_netif(wifi_status.dev, WIFI_MODE_AP));
339 #endif
340     return 0;
341 }
342 
stop_ap(netdev_t * dev)343 static int stop_ap(netdev_t *dev)
344 {
345 #ifdef __AP_MODE__
346 
347     printf("stop_ap\n");
348 
349     bwifi_softap_stop();
350     wifi_status.sap_started = 0;
351     event_publish(EVENT_WIFI_AP_DOWN, NULL);
352 #endif
353     return 0;
354 }
355 
356 
357 __SRAMDATA osThreadDef(wifi_connect_task, osPriorityNormal, 1, (4096), "wifi_connect");
haas1000_wifi_connect(netdev_t * dev,wifi_config_t * config)358 static int haas1000_wifi_connect(netdev_t *dev, wifi_config_t* config)
359 {
360     if (!config) {
361         printf("%s: invalid argument!\n", __func__);
362         return -1;
363     }
364 
365     if (WARN_ON(!wifi_status.wifi_started || wifi_status.resetting))
366         return -1;
367 
368     if (config->mode == WIFI_MODE_STA) {
369         wifi_config_t *init_config_ptr = aos_malloc(sizeof(wifi_config_t));
370         if (!init_config_ptr) {
371             printf("Failed to alloc init para for wifi_connect_task\n");
372             return -1;
373         }
374         strncpy(init_config_ptr->ssid, config->ssid, sizeof(init_config_ptr->ssid)-1);
375         strncpy(init_config_ptr->password, config->password, sizeof(init_config_ptr->password)-1);
376         //if (aos_task_new("wifi_connect", wifi_connect_task, init_para_ptr, 4096)) {
377         if (osThreadCreate(osThread(wifi_connect_task), init_config_ptr) == NULL) {
378             printf("Failed to create wifi_connect_task\n");
379             aos_free(init_config_ptr);
380             return -1;
381         }
382     } else if (config->mode == WIFI_MODE_AP) {
383         return start_ap(dev, config->ssid, config->password, config->ap_config.beacon_interval, config->ap_config.hide_ssid);
384     }
385 
386     return 0;
387 }
388 
haas1000_wifi_notify_ip_state2drv(netdev_t * dev,wifi_ip_stat_t * in_net_para,wifi_mode_t mode)389 static int haas1000_wifi_notify_ip_state2drv(netdev_t *dev,
390                        wifi_ip_stat_t *in_net_para,
391                        wifi_mode_t mode)
392 {
393 #if LWIP_ETHERNETIF && !LWIP_SUPPORT
394     struct ip_info ip;
395 
396     if (!in_net_para) {
397         printf("%s: invalid argument!\n", __func__);
398         return -1;
399     }
400 
401     if (mode == WIFI_MODE_STA&& wifi_status.sta_connected) {
402         memcpy(&wifi_status.network.ip_stat, in_net_para, sizeof(wifi_ip_stat_t));
403         printf("set ip: %s\n", in_net_para->ip);
404         printf("set mask: %s\n", in_net_para->mask);
405         printf("set gw: %s\n", in_net_para->gate);
406         inet_aton(in_net_para->ip, &ip.ip);
407         inet_aton(in_net_para->mask, &ip.netmask);
408         inet_aton(in_net_para->gate, &ip.gw);
409         return bwifi_set_ip_addr(WIFI_IF_STATION, &ip);
410     }
411 #endif
412     return -1;
413 }
414 
get_ip_stat(netdev_t * dev,wifi_ip_stat_t * out_net_para,wifi_mode_t mode)415 static int get_ip_stat(netdev_t *dev,
416                        wifi_ip_stat_t *out_net_para,
417                        wifi_mode_t mode)
418 {
419 #if LWIP_SUPPORT
420     if (!out_net_para) {
421         printf("%s: invalid argument!\n", __func__);
422         return -1;
423     }
424 
425     if (mode == WIFI_MODE_STA&& wifi_status.sta_got_ip) {
426         memcpy(out_net_para, &wifi_status.network.ip_stat, sizeof(wifi_ip_stat_t));
427         return 0;
428     }
429 #endif
430     return -1;
431 }
432 
haas1000_wifi_sta_get_link_status(netdev_t * dev,wifi_ap_record_t * out_stat)433 static int haas1000_wifi_sta_get_link_status(netdev_t *dev, wifi_ap_record_t *out_stat)
434 {
435     if (!out_stat) {
436         printf("%s: invalid argument!\n", __func__);
437         return -1;
438     }
439 
440     if (wifi_status.sta_connected) {
441         out_stat->link_status = WIFI_STATUS_LINK_UP;
442         out_stat->rssi = bwifi_get_current_rssi();
443         bwifi_get_current_ssid(out_stat->ssid);
444         bwifi_get_current_bssid(out_stat->bssid);
445         out_stat->channel = bwifi_get_current_channel();
446     } else {
447         out_stat->link_status = WIFI_STATUS_LINK_DOWN;
448     }
449 
450     return 0;
451 }
452 
find_index_by_value(int value,int * array,int size)453 static int find_index_by_value(int value, int *array, int size)
454 {
455     int i;
456 
457     for( i=0; i<size; i++ ) {
458         if( array[i] == value )
459             break;
460     }
461     return i;
462 }
463 
wifi_scan(netdev_t * dev,wifi_scan_config_t * config,bool block,scan_type_t t)464 static int wifi_scan(netdev_t *dev, wifi_scan_config_t* config, bool block, scan_type_t t)
465 {
466     int i, ret;
467     struct bwifi_ssid *scan_ssid = NULL, *prev_scan_ssid = NULL;
468     struct bwifi_scan_config scan_config = {0};
469     struct bwifi_bss_info *scan_result = NULL;
470     static wifi_scan_result_t result = {0};
471     int index = 0, a_size = 0;
472     int scan_chs[] =  {1, 6, 11, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 0};
473 
474     if (WARN_ON(!wifi_status.wifi_started || wifi_status.resetting))
475         return -1;
476 
477     if (t == SCAN_SPECIFIED) {
478         prev_scan_ssid = NULL;
479         a_size = sizeof(scan_chs)/sizeof(scan_chs[0]) - 1;
480         for (i = 0; i < wifi_status.scan_req.ap_num; i++) {
481             index = find_index_by_value(wifi_status.scan_req.ap_list[i].channel, scan_chs, a_size);
482             if( index < a_size && index > i) {
483                 scan_chs[index] = scan_chs[i];
484                 scan_chs[i] = wifi_status.scan_req.ap_list[i].channel;
485             }
486             printf("Scan for specific SSID %s\n", wifi_status.scan_req.ap_list[i].ssid);
487             scan_ssid = (struct bwifi_ssid *)aos_malloc(sizeof(struct bwifi_ssid));
488             if (!scan_ssid) {
489                 printf("Failed to malloc scan ssid struct\n");
490                 break;
491             }
492             memcpy(scan_ssid->ssid,
493                    wifi_status.scan_req.ap_list[i].ssid,
494                    sizeof(scan_ssid->ssid));
495             scan_ssid->next = NULL;
496             if (prev_scan_ssid)
497                 prev_scan_ssid->next = scan_ssid;
498             else
499                 scan_config.ssids = scan_ssid;
500             prev_scan_ssid = scan_ssid;
501         }
502         scan_config.channels = scan_chs;
503         ret = bwifi_config_scan(&scan_config);
504 
505         scan_ssid = scan_config.ssids;
506         while (scan_ssid) {
507             prev_scan_ssid = scan_ssid;
508             scan_ssid = scan_ssid->next;
509             aos_free(prev_scan_ssid);
510         }
511     } else {
512         ret = bwifi_scan();
513     }
514     if (ret <= 0) {
515         printf("wifi scan fail\n");
516         return -1;
517     }
518 
519     scan_result = (struct bwifi_bss_info *)aos_malloc(ret * sizeof(struct bwifi_bss_info));
520     if (!scan_result) {
521         printf("Failed to malloc scan result buffer\n");
522         goto end;
523     }
524     ret = bwifi_get_scan_result(scan_result, ret);
525 
526     result.ap_num = ret;
527     if (result.ap_list == NULL) {
528         result.ap_list = aos_malloc(ret * sizeof(ap_list_t));
529     } else {
530         result.ap_list = aos_realloc(result.ap_list, ret * sizeof(ap_list_t));
531     }
532     if (!result.ap_list) {
533         printf("Failed to malloc the returned ap list\n");
534         result.ap_num = 0; goto end;
535     }
536 
537     for (i = 0; i < ret; i++) {
538         struct bwifi_bss_info *r = scan_result + i;
539 
540         ap_list_t *res = result.ap_list + i;
541         memcpy(res->ssid, r->ssid, sizeof(res->ssid));
542         res->ap_power = r->rssi;
543         memcpy(res->bssid, r->bssid, sizeof(res->bssid));
544     }
545 
546 end:
547     event_publish(EVENT_WIFI_SCAN_DONE, &result);
548 
549     if (scan_result)
550         aos_free(scan_result);
551 
552     return 0;
553 }
554 
haas1000_wifi_start_scan(netdev_t * dev,wifi_scan_config_t * config,bool block)555 static int haas1000_wifi_start_scan(netdev_t *dev, wifi_scan_config_t* config, bool block)
556 {
557     return wifi_scan(dev, config, block, SCAN_NORMAL);
558 }
559 
haas1000_wifi_start_specified_scan(netdev_t * dev,ap_list_t * ap_list,int ap_num)560 static int haas1000_wifi_start_specified_scan(netdev_t *dev, ap_list_t *ap_list, int ap_num)
561 {
562     int i = 0;
563 
564     if (ap_num > 3)
565         ap_num = 3;
566     wifi_status.scan_req.ap_num = ap_num;
567     while (i < ap_num) {
568         wifi_status.scan_req.ap_list[i] = *(ap_list + i);
569         i++;
570     }
571 
572     int ret = wifi_scan(dev, NULL, false, SCAN_SPECIFIED);
573 
574     printf("haas start scan:%d", ret);
575     return ret;
576 }
577 
disconnect_station(netdev_t * dev)578 static int disconnect_station(netdev_t *dev)
579 {
580     if (wifi_status.wifi_started && wifi_status.sta_connected && !wifi_status.resetting)
581         return bwifi_disconnect();
582 
583     return 0;
584 }
585 
disconnect_soft_ap(netdev_t * dev)586 static int disconnect_soft_ap(netdev_t *dev)
587 {
588     return 0;
589 }
590 
haas1000_wifi_disconnect(netdev_t * dev)591 static int haas1000_wifi_disconnect(netdev_t *dev)
592 {
593     int ret = 0;
594 
595     ret = disconnect_station(dev);
596     if (wifi_status.sap_started)
597         ret += disconnect_soft_ap(dev);
598     return ret;
599 }
600 
haas1000_wifi_cancel_connect(netdev_t * dev)601 static int haas1000_wifi_cancel_connect(netdev_t *dev)
602 {
603     if (wifi_status.wifi_started && !wifi_status.sta_connected && !wifi_status.resetting)
604         return bwifi_disconnect();
605 
606     return -1;
607 }
608 
haas1000_wifi_set_channel(netdev_t * dev,int ch)609 static int haas1000_wifi_set_channel(netdev_t *dev, int ch)
610 {
611     if (WARN_ON(!wifi_status.wifi_started ||
612                 wifi_status.sta_connected))
613         return -1;
614 
615     return bes_sniffer_set_channel((u8)ch);
616 }
617 
haas1000_wifi_get_channel(netdev_t * dev,int * ch)618 static int haas1000_wifi_get_channel(netdev_t *dev, int* ch)
619 {
620     if(ch != NULL) {
621        *ch  = bwifi_get_current_channel();
622        return 0;
623     }
624     return -1;
625 }
626 
627 /* Wi-Fi Smart Config */
628 
wifi_sniffer_handler(unsigned short data_len,void * data)629 static int wifi_sniffer_handler(unsigned short data_len, void *data)
630 {
631     uint8_t *frame = (uint8_t *)data;
632 
633     if (data == NULL) {
634         printf("%s ldpc:%d\n", __func__, data_len);
635         return 0;
636     }
637 
638     printf("%s data:%p, len:%d\n", __func__, data, data_len);
639 #if 0
640     printf("	%02x %02x %02x %02x\n",
641            frame[0], frame[1], frame[2], frame[3]);
642     printf("	%02x %02x %02x %02x %02x %02x\n",
643            frame[4], frame[5], frame[6], frame[7], frame[8], frame[9]);
644     printf("	%02x %02x %02x %02x %02x %02x\n",
645            frame[10], frame[11], frame[12], frame[13], frame[14], frame[15]);
646     printf("	%02x %02x %02x %02x %02x %02x\n",
647            frame[16], frame[17], frame[18], frame[19], frame[20], frame[21]);
648     printf("	%02x %02x\n", frame[22], frame[23]);
649 #endif
650 
651     if (wifi_status.smart_config && promisc_cb)
652         promisc_cb(frame, data_len, NULL);
653     else if (wifi_status.zero_config && mgnt_frame_cb) {
654         uint8_t type = frame[0] & 0xFC;
655         if (type == PROBE_REQ) {
656             printf("%s: probe request received!\n", __func__);
657             mgnt_frame_cb(frame, data_len, NULL);
658         }
659     }
660     return 0;
661 }
662 
haas1000_wifi_start_monitor(netdev_t * dev)663 static int haas1000_wifi_start_monitor(netdev_t *dev)
664 {
665     if (WARN_ON(!wifi_status.wifi_started ||
666                 wifi_status.sta_connected))
667         return -1;
668 
669     if (bes_sniffer_start(wifi_sniffer_handler) ||
670         bes_sniffer_set_filter(0,1,1,0,0,0,0))
671         return -2;
672 
673     wifi_status.smart_config = 1;
674     return 0;
675 }
676 
haas1000_wifi_stop_monitor(netdev_t * dev)677 static int haas1000_wifi_stop_monitor(netdev_t *dev)
678 {
679     wifi_status.smart_config = 0;
680     return bes_sniffer_stop();
681 }
682 
haas1000_wifi_register_monitor_cb(netdev_t * dev,monitor_data_cb_t fn)683 static void haas1000_wifi_register_monitor_cb(netdev_t *dev, monitor_data_cb_t fn)
684 {
685     promisc_cb = fn;
686 }
687 
688 /* Wi-Fi Zero Config */
689 
haas1000_wifi_start_mgnt_monitor(netdev_t * dev)690 static int haas1000_wifi_start_mgnt_monitor(netdev_t *dev)
691 {
692     if (WARN_ON(!wifi_status.sta_connected ||
693                 wifi_status.resetting))
694         return -1;
695 
696     if (bes_sniffer_start(wifi_sniffer_handler) ||
697         bes_sniffer_set_filter(1,0,0,0,0,0,0))
698         return -2;
699 
700     wifi_status.zero_config = 1;
701     return 0;
702 }
703 
haas1000_wifi_stop_mgnt_monitor(netdev_t * dev)704 static int haas1000_wifi_stop_mgnt_monitor(netdev_t *dev)
705 {
706     wifi_status.zero_config = 0;
707     return bes_sniffer_stop();
708 }
709 
haas1000_wifi_register_mgnt_monitor_cb(netdev_t * dev,monitor_data_cb_t fn)710 static void haas1000_wifi_register_mgnt_monitor_cb(netdev_t *dev, monitor_data_cb_t fn)
711 {
712     mgnt_frame_cb = fn;
713 }
714 
haas1000_wifi_send_80211_raw_frame(netdev_t * dev,uint8_t * buf,int len)715 static int haas1000_wifi_send_80211_raw_frame(netdev_t *dev, uint8_t *buf, int len)
716 {
717     if (WARN_ON(!wifi_status.sta_connected ||
718                 wifi_status.resetting))
719         return -1;
720 
721     return bes_sniffer_send_mgmt_frame(bwifi_get_current_channel(), buf, len);
722 }
723 
724 static wifi_driver_t haas1000_wifi_driver = {
725 
726     /** driver info */
727     .base.os                    = "rtos",
728     .base.type                  = "solo",
729     .base.partner               = "AliOS Things Team",
730     .base.app_net               = "rtsp+rtp+rtcp",
731     .base.project               = "HAAS100",
732     .base.cloud                 = "aliyun",
733 
734     /** common APIs */
735     .init                       = haas1000_wifi_init,
736     .deinit                     = haas1000_wifi_deinit,
737 //    .set_mode                   = haas1000_wifi_set_mode,
738 //    .get_mode                   = haas1000_wifi_get_mode,
739 
740     /** conf APIs */
741     .set_mac_addr               = haas1000_wifi_set_mac_addr,
742     .get_mac_addr               = haas1000_wifi_get_mac_addr,
743 //    .set_lpm                    = haas1000_wifi_set_lpm,
744 //    .get_lpm                    = haas1000_wifi_get_lpm,
745     .notify_ip_state2drv        = haas1000_wifi_notify_ip_state2drv,
746 
747     /** connection APIs */
748     .start_scan                 = haas1000_wifi_start_scan,
749     .start_specified_scan       = haas1000_wifi_start_specified_scan,
750     .connect                    = haas1000_wifi_connect,
751     .cancel_connect             = haas1000_wifi_cancel_connect,
752     .disconnect                 = haas1000_wifi_disconnect,
753     .sta_get_link_status        = haas1000_wifi_sta_get_link_status,
754 //    .ap_get_sta_list            = haas1000_wifi_ap_get_sta_list,
755 
756 
757     /** promiscuous APIs */
758     .start_monitor              = haas1000_wifi_start_monitor,
759     .stop_monitor               = haas1000_wifi_stop_monitor,
760     .send_80211_raw_frame       = haas1000_wifi_send_80211_raw_frame,
761     .set_channel                = haas1000_wifi_set_channel,
762     .get_channel                = haas1000_wifi_get_channel,
763     .register_monitor_cb        = haas1000_wifi_register_monitor_cb,
764     .start_mgnt_monitor         = haas1000_wifi_start_mgnt_monitor,
765     .stop_mgnt_monitor          = haas1000_wifi_stop_mgnt_monitor,
766     .register_mgnt_monitor_cb   = haas1000_wifi_register_mgnt_monitor_cb,
767 
768     .set_smartcfg = NULL,
769 };
770 
haas1000_wifi_register(void)771 int haas1000_wifi_register(void)
772 {
773     return vfs_wifi_dev_register(&haas1000_wifi_driver, 0);
774 }
775 
776 VFS_DRIVER_ENTRY(haas1000_wifi_register)
777 
778