1 #if !defined(CONFIG_MBED_ENABLED) && !defined(CONFIG_PLATFOMR_CUSTOMER_RTOS)
2 #include "main.h"
3 #include "lwip/tcpip.h"
4 #endif
5 #include <osdep_service.h>
6 #include "wifi/wifi_conf.h"
7 #include "k_api.h"
8 #ifndef CONFIG_WLAN
9 #define CONFIG_WLAN 1
10 #endif
11
12 #if CONFIG_WLAN
13 #include <platform/platform_stdlib.h>
14
15 extern void _promisc_deinit(void *padapter);
16 extern int _promisc_recv_func(void *padapter, void *rframe);
17 extern int _promisc_set(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used);
18 extern unsigned char _is_promisc_enabled(void);
19 extern int _promisc_get_fixed_channel(void * fixed_bssid, u8 *ssid, int * ssid_length);
20 extern void _promisc_filter_by_ap_and_phone_mac(u8 enable, void *ap_mac, void *phone_mac);
21 // Add extra interfaces to make release sdk able to determine promisc API linking
promisc_deinit(void * padapter)22 void promisc_deinit(void *padapter)
23 {
24 #ifdef CONFIG_PROMISC
25 _promisc_deinit(padapter);
26 #endif
27 }
28
promisc_recv_func(void * padapter,void * rframe)29 int promisc_recv_func(void *padapter, void *rframe)
30 {
31 // Never reach here if not define CONFIG_PROMISC
32 #ifdef CONFIG_PROMISC
33 return _promisc_recv_func(padapter, rframe);
34 #else
35 return 0;
36 #endif
37 }
38
promisc_recv_lens_func(void * padapter,u8 * payload,u8 plen)39 int promisc_recv_lens_func(void *padapter, u8 *payload, u8 plen)
40 {
41 /* To avoid gcc warnings */
42 ( void ) padapter;
43 ( void ) payload;
44 ( void ) plen;
45
46 // Never reach here if not define CONFIG_PROMISC
47 #ifdef CONFIG_PROMISC
48 #if defined(CONFIG_UNSUPPORT_PLCPHDR_RPT) && CONFIG_UNSUPPORT_PLCPHDR_RPT
49 return _promisc_recv_lens_func(padapter, payload, plen);
50 #else
51 return 0;
52 #endif
53 #else
54 return 0;
55 #endif
56 }
57
promisc_filter_with_len(u16 len)58 int promisc_filter_with_len(u16 len)
59 {
60 /* To avoid gcc warnings */
61 ( void ) len;
62
63 // Never reach here if not define CONFIG_PROMISC
64 #ifdef CONFIG_PROMISC
65 #if defined(CONFIG_UNSUPPORT_PLCPHDR_RPT) && CONFIG_UNSUPPORT_PLCPHDR_RPT
66 return _promisc_filter_with_len(len);
67 #else
68 return -1;
69 #endif
70 #else
71 return -1;
72 #endif
73 }
74
promisc_set(rtw_rcr_level_t enabled,void (* callback)(unsigned char *,unsigned int,void *),unsigned char len_used)75 int promisc_set(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used)
76 {
77 #ifdef CONFIG_PROMISC
78 return _promisc_set(enabled, callback, len_used);
79 #else
80 return -1;
81 #endif
82 }
83
is_promisc_enabled(void)84 unsigned char is_promisc_enabled(void)
85 {
86 #ifdef CONFIG_PROMISC
87 return _is_promisc_enabled();
88 #else
89 return 0;
90 #endif
91 }
92
promisc_get_fixed_channel(void * fixed_bssid,u8 * ssid,int * ssid_length)93 int promisc_get_fixed_channel(void *fixed_bssid, u8 *ssid, int *ssid_length)
94 {
95 #ifdef CONFIG_PROMISC
96 return _promisc_get_fixed_channel(fixed_bssid, ssid, ssid_length);
97 #else
98 return 0;
99 #endif
100 }
101
promisc_filter_by_ap_and_phone_mac(u8 enable,void * ap_mac,void * phone_mac)102 void promisc_filter_by_ap_and_phone_mac(u8 enable, void *ap_mac, void *phone_mac)
103 {
104 #ifdef CONFIG_PROMISC
105 _promisc_filter_by_ap_and_phone_mac(enable, ap_mac, phone_mac);
106 #endif
107 }
108
109 // End of Add extra interfaces
110
111 struct eth_frame {
112 struct eth_frame *prev;
113 struct eth_frame *next;
114 unsigned char da[6];
115 unsigned char sa[6];
116 unsigned int len;
117 unsigned char type;
118 signed char rssi;
119 };
120
121 #ifndef CONFIG_INIC_CMD_RSP
122 #define CONFIG_INIC_CMD_RSP 0
123 #endif
124
125 #if CONFIG_INIC_CMD_RSP
126 #if defined(__IAR_SYSTEMS_ICC__) || defined (__GNUC__)
127 #pragma pack(1)
128 #endif
129 struct inic_eth_frame {
130 unsigned char da[6];
131 unsigned char sa[6];
132 unsigned int len;
133 unsigned char type;
134 };
135 #if defined(__IAR_SYSTEMS_ICC__) || defined (__GNUC__)
136 #pragma pack()
137 #endif
138
139 static struct inic_eth_frame *inic_frame, *inic_frame_tail = NULL;
140 static int inic_frame_cnt = 0;
141 #define MAX_INIC_FRAME_NUM 50 //maximum packets for each channel
142 extern void inic_c2h_msg(const char *atcmd, char status, char *msg, u16 msg_len);
143 #endif
144
145 struct eth_buffer {
146 struct eth_frame *head;
147 struct eth_frame *tail;
148 };
149
150 static struct eth_buffer eth_buffer;
151
152 #ifdef CONFIG_PROMISC
153 #define MAX_PACKET_FILTER_INFO 5
154 #define FILTER_ID_INIT_VALUE 10
155 rtw_packet_filter_info_t paff_array[MAX_PACKET_FILTER_INFO]={0};
156 static u8 packet_filter_enable_num = 0;
157
promisc_init_packet_filter(void)158 void promisc_init_packet_filter(void)
159 {
160 int i = 0;
161 for(i=0; i<MAX_PACKET_FILTER_INFO; i++){
162 paff_array[i].filter_id = FILTER_ID_INIT_VALUE;
163 paff_array[i].enable = 0;
164 paff_array[i].patt.mask_size = 0;
165 paff_array[i].rule = RTW_POSITIVE_MATCHING;
166 paff_array[i].patt.mask = NULL;
167 paff_array[i].patt.pattern = NULL;
168 }
169 packet_filter_enable_num = 0;
170 }
171
promisc_add_packet_filter(u8 filter_id,rtw_packet_filter_pattern_t * patt,rtw_packet_filter_rule_t rule)172 int promisc_add_packet_filter(u8 filter_id, rtw_packet_filter_pattern_t *patt, rtw_packet_filter_rule_t rule)
173 {
174 int i = 0;
175 while(i < MAX_PACKET_FILTER_INFO){
176 if(paff_array[i].filter_id == FILTER_ID_INIT_VALUE){
177 break;
178 }
179 i++;
180 }
181
182 if(i == MAX_PACKET_FILTER_INFO)
183 return -1;
184
185 paff_array[i].filter_id = filter_id;
186
187 paff_array[i].patt.offset= patt->offset;
188 paff_array[i].patt.mask_size = patt->mask_size;
189 paff_array[i].patt.mask = rtw_malloc(patt->mask_size);
190 memcpy(paff_array[i].patt.mask, patt->mask, patt->mask_size);
191 paff_array[i].patt.pattern= rtw_malloc(patt->mask_size);
192 memcpy(paff_array[i].patt.pattern, patt->pattern, patt->mask_size);
193
194 paff_array[i].rule = rule;
195 paff_array[i].enable = 0;
196
197 return 0;
198 }
199
promisc_enable_packet_filter(u8 filter_id)200 int promisc_enable_packet_filter(u8 filter_id)
201 {
202 int i = 0;
203 while(i < MAX_PACKET_FILTER_INFO){
204 if(paff_array[i].filter_id == filter_id)
205 break;
206 i++;
207 }
208
209 if(i == MAX_PACKET_FILTER_INFO)
210 return -1;
211
212 paff_array[i].enable = 1;
213 packet_filter_enable_num++;
214 return 0;
215 }
216
promisc_disable_packet_filter(u8 filter_id)217 int promisc_disable_packet_filter(u8 filter_id)
218 {
219 int i = 0;
220 while(i < MAX_PACKET_FILTER_INFO){
221 if(paff_array[i].filter_id == filter_id)
222 break;
223 i++;
224 }
225
226 if(i == MAX_PACKET_FILTER_INFO)
227 return -1;
228
229 paff_array[i].enable = 0;
230 packet_filter_enable_num--;
231 return 0;
232 }
233
promisc_remove_packet_filter(u8 filter_id)234 int promisc_remove_packet_filter(u8 filter_id)
235 {
236 int i = 0;
237 while(i < MAX_PACKET_FILTER_INFO){
238 if(paff_array[i].filter_id == filter_id)
239 break;
240 i++;
241 }
242
243 if(i == MAX_PACKET_FILTER_INFO)
244 return -1;
245
246 paff_array[i].filter_id = FILTER_ID_INIT_VALUE;
247 paff_array[i].enable = 0;
248 paff_array[i].patt.mask_size = 0;
249 paff_array[i].rule = 0;
250 if(paff_array[i].patt.mask){
251 rtw_free(paff_array[i].patt.mask);
252 paff_array[i].patt.mask = NULL;
253 }
254
255 if(paff_array[i].patt.pattern){
256 rtw_free(paff_array[i].patt.pattern);
257 paff_array[i].patt.pattern = NULL;
258 }
259 return 0;
260 }
261 #endif
262
263 /* Make callback simple to prevent latency to wlan rx when promiscuous mode */
promisc_callback(unsigned char * buf,unsigned int len,void * userdata)264 static void promisc_callback(unsigned char *buf, unsigned int len, void* userdata)
265 {
266 struct eth_frame *frame = (struct eth_frame *) rtw_malloc(sizeof(struct eth_frame));
267 _lock lock;
268 _irqL irqL;
269
270 if(frame) {
271 frame->prev = NULL;
272 frame->next = NULL;
273 memcpy(frame->da, buf, 6);
274 memcpy(frame->sa, buf+6, 6);
275 frame->len = len;
276 frame->rssi = ((ieee80211_frame_info_t *)userdata)->rssi;
277
278 rtw_enter_critical(&lock, &irqL);
279
280 if(eth_buffer.tail) {
281 eth_buffer.tail->next = frame;
282 frame->prev = eth_buffer.tail;
283 eth_buffer.tail = frame;
284 }
285 else {
286 eth_buffer.head = frame;
287 eth_buffer.tail = frame;
288 }
289
290 rtw_exit_critical(&lock, &irqL);
291 }
292 }
293
retrieve_frame(void)294 struct eth_frame* retrieve_frame(void)
295 {
296 struct eth_frame *frame = NULL;
297 _lock lock;
298 _irqL irqL;
299
300 rtw_enter_critical(&lock, &irqL);
301
302 if(eth_buffer.head) {
303 frame = eth_buffer.head;
304
305 if(eth_buffer.head->next) {
306 eth_buffer.head = eth_buffer.head->next;
307 eth_buffer.head->prev = NULL;
308 }
309 else {
310 eth_buffer.head = NULL;
311 eth_buffer.tail = NULL;
312 }
313 }
314
315 rtw_exit_critical(&lock, &irqL);
316
317 return frame;
318 }
319
promisc_test(int duration,unsigned char len_used)320 static void promisc_test(int duration, unsigned char len_used)
321 {
322 int ch;
323 unsigned int start_time;
324 struct eth_frame *frame;
325 eth_buffer.head = NULL;
326 eth_buffer.tail = NULL;
327
328 wifi_enter_promisc_mode();
329 wifi_set_promisc(RTW_PROMISC_ENABLE, promisc_callback, len_used);
330
331 for(ch = 1; ch <= 13; ch ++) {
332 if(wifi_set_channel(ch) == 0)
333 printf("\n\n\rSwitch to channel(%d)", ch);
334
335 start_time = rtw_get_current_time();
336
337 while(1) {
338 unsigned int current_time = rtw_get_current_time();
339
340 if(rtw_systime_to_ms(current_time - start_time) < (unsigned int)duration) {
341 frame = retrieve_frame();
342
343 if(frame) {
344 int i;
345 printf("\n\rDA:");
346 for(i = 0; i < 6; i ++)
347 printf(" %02x", frame->da[i]);
348 printf(", SA:");
349 for(i = 0; i < 6; i ++)
350 printf(" %02x", frame->sa[i]);
351 printf(", len=%d", frame->len);
352 printf(", RSSI=%d", frame->rssi);
353 #if CONFIG_INIC_CMD_RSP
354 if(inic_frame_tail){
355 if(inic_frame_cnt < MAX_INIC_FRAME_NUM){
356 memcpy(inic_frame_tail->da, frame->da, 6);
357 memcpy(inic_frame_tail->sa, frame->sa, 6);
358 inic_frame_tail->len = frame->len;
359 inic_frame_tail++;
360 inic_frame_cnt++;
361 }
362 }
363 #endif
364 rtw_free((void *) frame);
365 }
366 else
367 rtw_mdelay_os(1); //delay 1 tick
368 }
369 else
370 break;
371 }
372 #if CONFIG_INIC_CMD_RSP
373 if(inic_frame){
374 inic_c2h_msg("ATWM", RTW_SUCCESS, (char *)inic_frame, sizeof(struct inic_eth_frame)*inic_frame_cnt);
375 memset(inic_frame, '\0', sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
376 inic_frame_tail = inic_frame;
377 inic_frame_cnt = 0;
378 rtw_msleep_os(10);
379 }
380 #endif
381 }
382
383 wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0);
384
385 while((frame = retrieve_frame()) != NULL)
386 rtw_free((void *) frame);
387 }
388
promisc_callback_all(unsigned char * buf,unsigned int len,void * userdata)389 static void promisc_callback_all(unsigned char *buf, unsigned int len, void* userdata)
390 {
391 struct eth_frame *frame = (struct eth_frame *) rtw_malloc(sizeof(struct eth_frame));
392 _lock lock;
393 _irqL irqL;
394
395 if(frame) {
396 frame->prev = NULL;
397 frame->next = NULL;
398 #if defined(CONFIG_UNSUPPORT_PLCPHDR_RPT) && CONFIG_UNSUPPORT_PLCPHDR_RPT
399 if(((ieee80211_frame_info_t *)userdata)->type == RTW_RX_UNSUPPORT){
400 //NOTICE: buf structure now is rtw_rx_info_t.
401 frame->type = 0xFF;
402 memset(frame->da, 0, 6);
403 memset(frame->sa, 0, 6);
404 }
405 else
406 #endif
407 {
408 memcpy(frame->da, buf+4, 6);
409 memcpy(frame->sa, buf+10, 6);
410 frame->type = *buf;
411 }
412
413 frame->len = len;
414 /*
415 * type is the first byte of Frame Control Field of 802.11 frame
416 * If the from/to ds information is needed, type could be reused as follows:
417 * frame->type = ((((ieee80211_frame_info_t *)userdata)->i_fc & 0x0100) == 0x0100) ? 2 : 1;
418 * 1: from ds; 2: to ds
419 */
420
421 frame->rssi = ((ieee80211_frame_info_t *)userdata)->rssi;
422
423 rtw_enter_critical(&lock, &irqL);
424
425 if(eth_buffer.tail) {
426 eth_buffer.tail->next = frame;
427 frame->prev = eth_buffer.tail;
428 eth_buffer.tail = frame;
429 }
430 else {
431 eth_buffer.head = frame;
432 eth_buffer.tail = frame;
433 }
434
435 rtw_exit_critical(&lock, &irqL);
436 }
437 }
promisc_test_all(int duration,unsigned char len_used)438 static void promisc_test_all(int duration, unsigned char len_used)
439 {
440 int ch;
441 unsigned int start_time;
442 struct eth_frame *frame;
443 eth_buffer.head = NULL;
444 eth_buffer.tail = NULL;
445
446 wifi_enter_promisc_mode();
447 wifi_set_promisc(RTW_PROMISC_ENABLE_2, promisc_callback_all, len_used);
448
449 for(ch = 1; ch <= 13; ch ++) {
450 if(wifi_set_channel(ch) == 0)
451 printf("\n\n\rSwitch to channel(%d)", ch);
452
453 start_time = rtw_get_current_time();
454
455 while(1) {
456 unsigned int current_time = rtw_get_current_time();
457
458 if(rtw_systime_to_ms(current_time - start_time) < (unsigned int)duration) {
459 frame = retrieve_frame();
460
461 if(frame) {
462 int i;
463 printf("\n\rTYPE: 0x%x, ", frame->type);
464 printf("DA:");
465 for(i = 0; i < 6; i ++)
466 printf(" %02x", frame->da[i]);
467 printf(", SA:");
468 for(i = 0; i < 6; i ++)
469 printf(" %02x", frame->sa[i]);
470 printf(", len=%d", frame->len);
471 printf(", RSSI=%d", frame->rssi);
472 #if CONFIG_INIC_CMD_RSP
473 if(inic_frame_tail){
474 if(inic_frame_cnt < MAX_INIC_FRAME_NUM){
475 memcpy(inic_frame_tail->da, frame->da, 6);
476 memcpy(inic_frame_tail->sa, frame->sa, 6);
477 inic_frame_tail->len = frame->len;
478 inic_frame_tail->type = frame->type;
479 inic_frame_tail++;
480 inic_frame_cnt++;
481 }
482 }
483 #endif
484 rtw_free((void *) frame);
485 }
486 else
487 rtw_mdelay_os(1); //delay 1 tick
488 }
489 else
490 break;
491 }
492 #if CONFIG_INIC_CMD_RSP
493 if(inic_frame){
494 inic_c2h_msg("ATWM", RTW_SUCCESS, (char *)inic_frame, sizeof(struct inic_eth_frame)*inic_frame_cnt);
495 memset(inic_frame, '\0', sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
496 inic_frame_tail = inic_frame;
497 inic_frame_cnt = 0;
498 rtw_msleep_os(10);
499 }
500 #endif
501 }
502
503 wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0);
504
505 while((frame = retrieve_frame()) != NULL)
506 rtw_free((void *) frame);
507 }
508
cmd_promisc(int argc,char ** argv)509 void cmd_promisc(int argc, char **argv)
510 {
511 int duration;
512 #if CONFIG_INIC_CMD_RSP
513 inic_frame_tail = inic_frame = rtw_malloc(sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
514 if(inic_frame == NULL){
515 inic_c2h_msg("ATWM", RTW_BUFFER_UNAVAILABLE_TEMPORARY, NULL, 0);
516 return;
517 }
518 #endif
519 #ifdef CONFIG_PROMISC
520 wifi_init_packet_filter();
521 #endif
522 if((argc == 2) && ((duration = atoi(argv[1])) > 0))
523 //promisc_test(duration, 0);
524 promisc_test_all(duration, 0);
525 else if((argc == 3) && ((duration = atoi(argv[1])) > 0) && (strcmp(argv[2], "with_len") == 0))
526 promisc_test(duration, 1);
527 else
528 printf("\n\rUsage: %s DURATION_SECONDS [with_len]", argv[0]);
529 #if CONFIG_INIC_CMD_RSP
530 if(inic_frame)
531 rtw_free(inic_frame);
532 inic_frame_tail = NULL;
533 inic_frame_cnt = 0;
534 #endif
535 }
536 #endif //#if CONFIG_WLAN
537