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