1 #include <stdint.h> 2 #include <stdlib.h> 3 4 #include "wifi_hal.h" 5 6 #define LOG_TAG "WifiHAL" 7 8 #include <utils/Log.h> 9 #include <inttypes.h> 10 #include <sys/socket.h> 11 #include <linux/if.h> 12 #include <ctype.h> 13 #include <stdarg.h> 14 15 pthread_mutex_t printMutex; 16 void printMsg(const char *fmt, ...) 17 { 18 pthread_mutex_lock(&printMutex); 19 va_list l; 20 va_start(l, fmt); 21 22 vprintf(fmt, l); 23 va_end(l); 24 pthread_mutex_unlock(&printMutex); 25 } 26 27 template<typename T, unsigned N> 28 unsigned countof(T (&rgt)[N]) { 29 return N; 30 } 31 32 template<typename T> 33 T min(const T& t1, const T& t2) { 34 return (t1 < t2) ? t1 : t2; 35 } 36 37 #define EVENT_BUF_SIZE 2048 38 #define MAX_CH_BUF_SIZE 64 39 #define MAX_FEATURE_SET 8 40 #define HOTLIST_LOST_WINDOW 5 41 42 static wifi_handle halHandle; 43 static wifi_interface_handle *ifaceHandles; 44 static wifi_interface_handle wlan0Handle; 45 static wifi_interface_handle p2p0Handle; 46 static int numIfaceHandles; 47 static int cmdId = 0; 48 static int ioctl_sock = 0; 49 static int max_event_wait = 5; 50 static int stest_max_ap = 10; 51 static int stest_base_period = 5000; 52 static int stest_threshold = 80; 53 static int swctest_rssi_sample_size = 3; 54 static int swctest_rssi_lost_ap = 3; 55 static int swctest_rssi_min_breaching = 2; 56 static int swctest_rssi_ch_threshold = 1; 57 static int htest_low_threshold = 90; 58 static int htest_high_threshold = 10; 59 static int rtt_samples = 30; 60 static wifi_band band = WIFI_BAND_UNSPECIFIED; 61 62 mac_addr hotlist_bssids[16]; 63 unsigned char mac_oui[3]; 64 int channel_list[16]; 65 int num_hotlist_bssids = 0; 66 int num_channels = 0; 67 68 void parseMacAddress(const char *str, mac_addr addr); 69 70 int linux_set_iface_flags(int sock, const char *ifname, int dev_up) 71 { 72 struct ifreq ifr; 73 int ret; 74 75 printMsg("setting interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN"); 76 77 if (sock < 0) { 78 printMsg("Bad socket: %d\n", sock); 79 return -1; 80 } 81 82 memset(&ifr, 0, sizeof(ifr)); 83 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); 84 85 printMsg("reading old value\n"); 86 87 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) { 88 ret = errno ? -errno : -999; 89 printMsg("Could not read interface %s flags: %d\n", ifname, errno); 90 return ret; 91 }else { 92 printMsg("writing new value\n"); 93 } 94 95 if (dev_up) { 96 if (ifr.ifr_flags & IFF_UP) { 97 printMsg("interface %s is already up\n", ifname); 98 return 0; 99 } 100 ifr.ifr_flags |= IFF_UP; 101 }else { 102 if (!(ifr.ifr_flags & IFF_UP)) { 103 printMsg("interface %s is already down\n", ifname); 104 return 0; 105 } 106 ifr.ifr_flags &= ~IFF_UP; 107 } 108 109 if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) { 110 printMsg("Could not set interface %s flags \n", ifname); 111 return ret; 112 }else { 113 printMsg("set interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN"); 114 } 115 printMsg("Done\n"); 116 return 0; 117 } 118 119 120 static int init() { 121 122 ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); 123 if (ioctl_sock < 0) { 124 printMsg("Bad socket: %d\n", ioctl_sock); 125 return errno; 126 } else { 127 printMsg("Good socket: %d\n", ioctl_sock); 128 } 129 130 int ret = linux_set_iface_flags(ioctl_sock, "wlan0", 1); 131 if (ret < 0) { 132 return ret; 133 } 134 135 wifi_error res = wifi_initialize(&halHandle); 136 if (res < 0) { 137 return res; 138 } 139 140 res = wifi_get_ifaces(halHandle, &numIfaceHandles, &ifaceHandles); 141 if (res < 0) { 142 return res; 143 } 144 145 char buf[EVENT_BUF_SIZE]; 146 for (int i = 0; i < numIfaceHandles; i++) { 147 if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) { 148 if (strcmp(buf, "wlan0") == 0) { 149 printMsg("found interface %s\n", buf); 150 wlan0Handle = ifaceHandles[i]; 151 } else if (strcmp(buf, "p2p0") == 0) { 152 printMsg("found interface %s\n", buf); 153 p2p0Handle = ifaceHandles[i]; 154 } 155 } 156 } 157 158 return res; 159 } 160 161 static void cleaned_up_handler(wifi_handle handle) { 162 printMsg("HAL cleaned up handler\n"); 163 halHandle = NULL; 164 ifaceHandles = NULL; 165 } 166 167 static void cleanup() { 168 printMsg("cleaning up HAL\n"); 169 wifi_cleanup(halHandle, cleaned_up_handler); 170 } 171 172 static void *eventThreadFunc(void *context) { 173 174 printMsg("starting wifi event loop\n"); 175 wifi_event_loop(halHandle); 176 printMsg("out of wifi event loop\n"); 177 178 return NULL; 179 } 180 181 182 static int getNewCmdId() { 183 return cmdId++; 184 } 185 186 /* ------------------------------------------- */ 187 /* helpers */ 188 /* ------------------------------------------- */ 189 190 void printScanHeader() { 191 printMsg("SSID\t\t\t\t\tBSSID\t\t RSSI\tchannel\ttimestamp\tRTT\tRTT SD\n"); 192 } 193 194 void printScanResult(wifi_scan_result result) { 195 196 printMsg("%-32s\t", result.ssid); 197 198 printMsg("%02x:%02x:%02x:%02x:%02x:%02x ", result.bssid[0], result.bssid[1], 199 result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]); 200 201 printMsg("%d\t", result.rssi); 202 printMsg("%d\t", result.channel); 203 printMsg("%lld\t", result.ts); 204 printMsg("%lld\t", result.rtt); 205 printMsg("%lld\n", result.rtt_sd); 206 } 207 208 void printSignificantChangeResult(wifi_significant_change_result *res) { 209 210 wifi_significant_change_result &result = *res; 211 printMsg("%02x:%02x:%02x:%02x:%02x:%02x ", result.bssid[0], result.bssid[1], 212 result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]); 213 214 printMsg("%d\t", result.channel); 215 216 for (int i = 0; i < result.num_rssi; i++) { 217 printMsg("%d,", result.rssi[i]); 218 } 219 printMsg("\n"); 220 } 221 222 void printScanCapabilities(wifi_gscan_capabilities capabilities) 223 { 224 printMsg("max_scan_cache_size = %d\n", capabilities.max_scan_cache_size); 225 printMsg("max_scan_buckets = %d\n", capabilities.max_scan_buckets); 226 printMsg("max_ap_cache_per_scan = %d\n", capabilities.max_ap_cache_per_scan); 227 printMsg("max_rssi_sample_size = %d\n", capabilities.max_rssi_sample_size); 228 printMsg("max_scan_reporting_threshold = %d\n", capabilities.max_scan_reporting_threshold); 229 printMsg("max_hotlist_aps = %d\n", capabilities.max_hotlist_aps); 230 printMsg("max_significant_wifi_change_aps = %d\n", 231 capabilities.max_significant_wifi_change_aps); 232 } 233 234 235 /* ------------------------------------------- */ 236 /* commands and events */ 237 /* ------------------------------------------- */ 238 239 typedef enum { 240 EVENT_TYPE_SCAN_RESULTS_AVAILABLE = 1000, 241 EVENT_TYPE_HOTLIST_AP_FOUND = 1001, 242 EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE = 1002, 243 EVENT_TYPE_RTT_RESULTS = 1003, 244 EVENT_TYPE_SCAN_COMPLETE = 1004, 245 EVENT_TYPE_HOTLIST_AP_LOST = 1005 246 } EventType; 247 248 typedef struct { 249 int type; 250 char buf[256]; 251 } EventInfo; 252 253 const int MAX_EVENTS_IN_CACHE = 256; 254 EventInfo eventCache[256]; 255 int eventsInCache = 0; 256 pthread_cond_t eventCacheCondition; 257 pthread_mutex_t eventCacheMutex; 258 259 void putEventInCache(int type, const char *msg) { 260 pthread_mutex_lock(&eventCacheMutex); 261 if (eventsInCache + 1 < MAX_EVENTS_IN_CACHE) { 262 eventCache[eventsInCache].type = type; 263 strcpy(eventCache[eventsInCache].buf, msg); 264 eventsInCache++; 265 pthread_cond_signal(&eventCacheCondition); 266 //printf("put new event in cache; size = %d\n", eventsInCache); 267 } else { 268 printf("Too many events in the cache\n"); 269 } 270 pthread_mutex_unlock(&eventCacheMutex); 271 } 272 273 void getEventFromCache(EventInfo& info) { 274 pthread_mutex_lock(&eventCacheMutex); 275 while (true) { 276 if (eventsInCache > 0) { 277 //printf("found an event in cache; size = %d\n", eventsInCache); 278 info.type = eventCache[0].type; 279 strcpy(info.buf, eventCache[0].buf); 280 eventsInCache--; 281 memmove(&eventCache[0], &eventCache[1], sizeof(EventInfo) * eventsInCache); 282 pthread_mutex_unlock(&eventCacheMutex); 283 return; 284 } else { 285 pthread_cond_wait(&eventCacheCondition, &eventCacheMutex); 286 //printf("pthread_cond_wait unblocked ...\n"); 287 } 288 } 289 } 290 291 int numScanResultsAvailable = 0; 292 static void onScanResultsAvailable(wifi_request_id id, unsigned num_results) { 293 printMsg("Received scan results available event\n"); 294 numScanResultsAvailable = num_results; 295 putEventInCache(EVENT_TYPE_SCAN_RESULTS_AVAILABLE, "New scan results are available"); 296 } 297 298 static void on_scan_event(wifi_scan_event event, unsigned status) { 299 if (event == WIFI_SCAN_BUFFER_FULL) { 300 printMsg("Received scan complete event - WIFI_SCAN_BUFFER_FULL \n"); 301 } else if(event == WIFI_SCAN_COMPLETE) { 302 printMsg("Received scan complete event - WIFI_SCAN_COMPLETE\n"); 303 } 304 } 305 306 static int scanCmdId; 307 static int hotlistCmdId; 308 static int significantChangeCmdId; 309 static int rttCmdId; 310 311 static bool startScan( void (*pfnOnResultsAvailable)(wifi_request_id, unsigned), 312 int max_ap_per_scan, int base_period, int report_threshold) { 313 314 /* Get capabilties */ 315 wifi_gscan_capabilities capabilities; 316 int result = wifi_get_gscan_capabilities(wlan0Handle, &capabilities); 317 if (result < 0) { 318 printMsg("failed to get scan capabilities - %d\n", result); 319 printMsg("trying scan anyway ..\n"); 320 } else { 321 printScanCapabilities(capabilities); 322 } 323 324 wifi_scan_cmd_params params; 325 memset(¶ms, 0, sizeof(params)); 326 327 if(num_channels > 0){ 328 params.max_ap_per_scan = max_ap_per_scan; 329 params.base_period = base_period; // 5 second by default 330 params.report_threshold = report_threshold; 331 params.num_buckets = 1; 332 333 params.buckets[0].bucket = 0; 334 params.buckets[0].band = WIFI_BAND_UNSPECIFIED; 335 params.buckets[0].period = base_period; 336 params.buckets[0].num_channels = num_channels; 337 338 for(int i = 0; i < num_channels; i++){ 339 params.buckets[0].channels[i].channel = channel_list[i]; 340 } 341 342 } else { 343 344 /* create a schedule to scan channels 1, 6, 11 every 5 second and 345 * scan 36, 40, 44, 149, 153, 157, 161 165 every 10 second */ 346 347 params.max_ap_per_scan = max_ap_per_scan; 348 params.base_period = base_period; // 5 second 349 params.report_threshold = report_threshold; 350 params.num_buckets = 3; 351 352 params.buckets[0].bucket = 0; 353 params.buckets[0].band = WIFI_BAND_UNSPECIFIED; 354 params.buckets[0].period = 5000; // 5 second 355 params.buckets[0].report_events = 0; 356 params.buckets[0].num_channels = 2; 357 358 params.buckets[0].channels[0].channel = 2412; 359 params.buckets[0].channels[1].channel = 2437; 360 361 params.buckets[1].bucket = 1; 362 params.buckets[1].band = WIFI_BAND_A; 363 params.buckets[1].period = 10000; // 10 second 364 params.buckets[1].report_events = 1; 365 params.buckets[1].num_channels = 8; // driver should ignore list since band is specified 366 367 368 params.buckets[1].channels[0].channel = 5180; 369 params.buckets[1].channels[1].channel = 5200; 370 params.buckets[1].channels[2].channel = 5220; 371 params.buckets[1].channels[3].channel = 5745; 372 params.buckets[1].channels[4].channel = 5765; 373 params.buckets[1].channels[5].channel = 5785; 374 params.buckets[1].channels[6].channel = 5805; 375 params.buckets[1].channels[7].channel = 5825; 376 377 params.buckets[2].bucket = 2; 378 params.buckets[2].band = WIFI_BAND_UNSPECIFIED; 379 params.buckets[2].period = 15000; // 15 second 380 params.buckets[2].report_events = 2; 381 params.buckets[2].num_channels = 1; 382 383 params.buckets[2].channels[0].channel = 2462; 384 385 } 386 387 wifi_scan_result_handler handler; 388 memset(&handler, 0, sizeof(handler)); 389 handler.on_scan_results_available = pfnOnResultsAvailable; 390 handler.on_scan_event = on_scan_event; 391 392 scanCmdId = getNewCmdId(); 393 printMsg("Starting scan --->\n"); 394 return wifi_start_gscan(scanCmdId, wlan0Handle, params, handler) == WIFI_SUCCESS; 395 } 396 397 static void stopScan() { 398 wifi_request_id id = scanCmdId; 399 if (id == 0) 400 id = -1; 401 402 wifi_stop_gscan(id, wlan0Handle); 403 scanCmdId = 0; 404 } 405 406 wifi_scan_result *saved_scan_results; 407 unsigned max_saved_scan_results; 408 unsigned num_saved_scan_results; 409 410 static void on_single_shot_scan_event(wifi_scan_event event, unsigned status) { 411 if (event == WIFI_SCAN_BUFFER_FULL) { 412 printMsg("Received scan complete event - WIFI_SCAN_BUFFER_FULL \n"); 413 } else if(event == WIFI_SCAN_COMPLETE) { 414 printMsg("Received scan complete event - WIFI_SCAN_COMPLETE\n"); 415 putEventInCache(EVENT_TYPE_SCAN_COMPLETE, "One scan completed"); 416 } 417 } 418 419 static void on_full_scan_result(wifi_request_id id, wifi_scan_result *r) { 420 if (num_saved_scan_results < max_saved_scan_results) { 421 wifi_scan_result *result = &(saved_scan_results[num_saved_scan_results]); 422 memcpy(result, r, sizeof(wifi_scan_result)); 423 //printMsg("Retrieved full scan result for %s(%02x:%02x:%02x:%02x:%02x:%02x)\n", 424 // result->ssid, result->bssid[0], result->bssid[1], result->bssid[2], result->bssid[3], 425 // result->bssid[4], result->bssid[5]); 426 num_saved_scan_results++; 427 } 428 } 429 430 static int scanOnce(wifi_band band, wifi_scan_result *results, int num_results) { 431 432 saved_scan_results = results; 433 max_saved_scan_results = num_results; 434 num_saved_scan_results = 0; 435 436 wifi_scan_cmd_params params; 437 memset(¶ms, 0, sizeof(params)); 438 439 params.max_ap_per_scan = 10; 440 params.base_period = 5000; // 5 second by default 441 params.report_threshold = 90; 442 params.num_buckets = 1; 443 444 params.buckets[0].bucket = 0; 445 params.buckets[0].band = band; 446 params.buckets[0].period = 5000; // 5 second 447 params.buckets[0].report_events = 2; // REPORT_EVENTS_AFTER_EACH_SCAN 448 params.buckets[0].num_channels = 0; 449 450 wifi_scan_result_handler handler; 451 memset(&handler, 0, sizeof(handler)); 452 handler.on_scan_results_available = NULL; 453 handler.on_scan_event = on_single_shot_scan_event; 454 handler.on_full_scan_result = on_full_scan_result; 455 456 int scanCmdId = getNewCmdId(); 457 printMsg("Starting scan --->\n"); 458 if (wifi_start_gscan(scanCmdId, wlan0Handle, params, handler) == WIFI_SUCCESS) { 459 int events = 0; 460 while (true) { 461 EventInfo info; 462 memset(&info, 0, sizeof(info)); 463 getEventFromCache(info); 464 if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE 465 || info.type == EVENT_TYPE_SCAN_COMPLETE) { 466 int retrieved_num_results = num_saved_scan_results; 467 if (retrieved_num_results == 0) { 468 printMsg("fetched 0 scan results, waiting for more..\n"); 469 continue; 470 } else { 471 printMsg("fetched %d scan results\n", retrieved_num_results); 472 473 /* 474 printScanHeader(); 475 476 for (int i = 0; i < retrieved_num_results; i++) { 477 printScanResult(results[i]); 478 } 479 */ 480 481 printMsg("Scan once completed, stopping scan\n"); 482 wifi_stop_gscan(scanCmdId, wlan0Handle); 483 saved_scan_results = NULL; 484 max_saved_scan_results = 0; 485 num_saved_scan_results = 0; 486 return retrieved_num_results; 487 } 488 } 489 } 490 } else { 491 return 0; 492 } 493 } 494 495 static void retrieveScanResults() { 496 497 wifi_scan_result results[256]; 498 memset(results, 0, sizeof(wifi_scan_result) * 256); 499 printMsg("Retrieve Scan results available -->\n"); 500 int num_results = 256; 501 int result = wifi_get_cached_gscan_results(wlan0Handle, 1, num_results, results, &num_results); 502 if (result < 0) { 503 printMsg("failed to fetch scan results : %d\n", result); 504 return; 505 } else { 506 printMsg("fetched %d scan results\n", num_results); 507 } 508 509 printScanHeader(); 510 for (int i = 0; i < num_results; i++) { 511 printScanResult(results[i]); 512 } 513 } 514 515 516 static int compareScanResultsByRssi(const void *p1, const void *p2) { 517 const wifi_scan_result *result1 = static_cast<const wifi_scan_result *>(p1); 518 const wifi_scan_result *result2 = static_cast<const wifi_scan_result *>(p2); 519 520 /* RSSI is -ve, so lower one wins */ 521 if (result1->rssi < result2->rssi) { 522 return 1; 523 } else if (result1->rssi == result2->rssi) { 524 return 0; 525 } else { 526 return -1; 527 } 528 } 529 530 static void sortScanResultsByRssi(wifi_scan_result *results, int num_results) { 531 qsort(results, num_results, sizeof(wifi_scan_result), &compareScanResultsByRssi); 532 } 533 534 static int removeDuplicateScanResults(wifi_scan_result *results, int num) { 535 /* remove duplicates by BSSID */ 536 int num_results = num; 537 for (int i = 0; i < num_results; i++) { 538 //printMsg("Processing result[%d] - %02x:%02x:%02x:%02x:%02x:%02x\n", i, 539 // results[i].bssid[0], results[i].bssid[1], results[i].bssid[2], 540 // results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]); 541 542 for (int j = i + 1; j < num_results; ) { 543 if (memcmp(results[i].bssid, results[j].bssid, sizeof(mac_addr)) == 0) { 544 /* 'remove' this scan result from the list */ 545 // printMsg("removing dupe entry\n"); 546 int num_to_move = num_results - j - 1; 547 memmove(&results[j], &results[j+1], num_to_move * sizeof(wifi_scan_result)); 548 num_results--; 549 } else { 550 j++; 551 } 552 } 553 554 // printMsg("num_results = %d\n", num_results); 555 } 556 557 return num_results; 558 } 559 560 static void onRTTResults (wifi_request_id id, unsigned num_results, wifi_rtt_result result[]) { 561 562 printMsg("RTT results!!\n"); 563 printMsg("Addr\t\t\tts\t\tRSSI\tSpread\trtt\tsd\tspread\tdist\tsd\tspread\n"); 564 565 for (unsigned i = 0; i < num_results; i++) { 566 printMsg("%02x:%02x:%02x:%02x:%02x:%02x\t%lld\t%d\t%d\t%lld\t%lld\t%lld\t%d\t%d\t%d\n", 567 result[i].addr[0], result[i].addr[1], result[i].addr[2], result[i].addr[3], 568 result[i].addr[4], result[i].addr[5], result[i].ts, result[i].rssi, 569 result[i].rssi_spread, result[i].rtt, result[i].rtt_sd, result[i].rtt_spread, 570 result[i].distance, result[i].distance_sd, result[i].distance_spread); 571 } 572 573 putEventInCache(EVENT_TYPE_RTT_RESULTS, "RTT results"); 574 } 575 576 static void onHotlistAPFound(wifi_request_id id, unsigned num_results, wifi_scan_result *results) { 577 578 printMsg("Found hotlist APs\n"); 579 for (unsigned i = 0; i < num_results; i++) { 580 printScanResult(results[i]); 581 } 582 putEventInCache(EVENT_TYPE_HOTLIST_AP_FOUND, "Found a hotlist AP"); 583 } 584 585 static void onHotlistAPLost(wifi_request_id id, unsigned num_results, wifi_scan_result *results) { 586 587 printMsg("Lost hotlist APs\n"); 588 for (unsigned i = 0; i < num_results; i++) { 589 printScanResult(results[i]); 590 } 591 putEventInCache(EVENT_TYPE_HOTLIST_AP_LOST, "Lost event Hotlist APs"); 592 } 593 594 static void testRTT() { 595 596 wifi_scan_result results[256]; 597 int num_results = scanOnce(WIFI_BAND_ABG, results, countof(results)); 598 if (num_results == 0) { 599 printMsg("RTT aborted because of no scan results\n"); 600 return; 601 } else { 602 printMsg("Retrieved %d scan results\n", num_results); 603 } 604 605 num_results = removeDuplicateScanResults(results, num_results); 606 /* 607 printMsg("Deduped scan results - %d\n", num_results); 608 for (int i = 0; i < num_results; i++) { 609 printScanResult(results[i]); 610 } 611 */ 612 613 sortScanResultsByRssi(results, num_results); 614 printMsg("Sorted scan results -\n"); 615 for (int i = 0; i < num_results; i++) { 616 printScanResult(results[i]); 617 } 618 619 620 static const int max_ap = 5; 621 wifi_rtt_config params[max_ap]; 622 memset(params, 0, sizeof(params)); 623 624 printMsg("Configuring RTT for %d APs, num_samples = %d\n", 625 min(num_results, max_ap), rtt_samples); 626 627 unsigned num_ap = 0; 628 for (int i = 0; i < min(num_results, max_ap); i++, num_ap++) { 629 630 memcpy(params[i].addr, results[i].bssid, sizeof(mac_addr)); 631 mac_addr &addr = params[i].addr; 632 printMsg("Adding %02x:%02x:%02x:%02x:%02x:%02x (%d) for RTT\n", addr[0], 633 addr[1], addr[2], addr[3], addr[4], addr[5], results[i].channel); 634 635 params[i].type = RTT_TYPE_1_SIDED; 636 params[i].channel.center_freq = results[i].channel; 637 params[i].channel.width = WIFI_CHAN_WIDTH_20; 638 params[i].peer = WIFI_PEER_INVALID; 639 params[i].continuous = 1; 640 params[i].interval = 1000; 641 params[i].num_samples_per_measurement = rtt_samples; 642 params[i].num_retries_per_measurement = 10; 643 } 644 645 wifi_rtt_event_handler handler; 646 handler.on_rtt_results = &onRTTResults; 647 648 int result = wifi_rtt_range_request(rttCmdId, wlan0Handle, num_ap, params, handler); 649 650 if (result == WIFI_SUCCESS) { 651 printMsg("Waiting for RTT results\n"); 652 653 while (true) { 654 EventInfo info; 655 memset(&info, 0, sizeof(info)); 656 getEventFromCache(info); 657 658 if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE) { 659 retrieveScanResults(); 660 } else if (info.type == EVENT_TYPE_RTT_RESULTS) { 661 break; 662 } 663 } 664 } else { 665 printMsg("Could not set setRTTAPs : %d\n", result); 666 } 667 } 668 669 670 static wifi_error setHotlistAPsUsingScanResult(wifi_bssid_hotlist_params *params){ 671 printMsg("testHotlistAPs Scan started, waiting for event ...\n"); 672 EventInfo info; 673 memset(&info, 0, sizeof(info)); 674 getEventFromCache(info); 675 676 wifi_scan_result results[256]; 677 memset(results, 0, sizeof(wifi_scan_result) * 256); 678 679 printMsg("Retrieving scan results for Hotlist AP setting\n"); 680 int num_results = 256; 681 int result = wifi_get_cached_gscan_results(wlan0Handle, 1, num_results, results, &num_results); 682 if (result < 0) { 683 printMsg("failed to fetch scan results : %d\n", result); 684 return WIFI_ERROR_UNKNOWN; 685 } else { 686 printMsg("fetched %d scan results\n", num_results); 687 } 688 689 for (int i = 0; i < num_results; i++) { 690 printScanResult(results[i]); 691 } 692 693 for (int i = 0; i < stest_max_ap; i++) { 694 memcpy(params->ap[i].bssid, results[i].bssid, sizeof(mac_addr)); 695 params->ap[i].low = -htest_low_threshold; 696 params->ap[i].high = -htest_high_threshold; 697 } 698 params->num_ap = stest_max_ap; 699 return WIFI_SUCCESS; 700 } 701 702 static wifi_error setHotlistAPs() { 703 wifi_bssid_hotlist_params params; 704 memset(¶ms, 0, sizeof(params)); 705 706 params.lost_ap_sample_size = HOTLIST_LOST_WINDOW; 707 if (num_hotlist_bssids > 0) { 708 for (int i = 0; i < num_hotlist_bssids; i++) { 709 memcpy(params.ap[i].bssid, hotlist_bssids[i], sizeof(mac_addr)); 710 params.ap[i].low = -htest_low_threshold; 711 params.ap[i].high = -htest_high_threshold; 712 } 713 params.num_ap = num_hotlist_bssids; 714 } else { 715 setHotlistAPsUsingScanResult(¶ms); 716 } 717 718 printMsg("BSSID\t\t\tHIGH\tLOW\n"); 719 for (int i = 0; i < params.num_ap; i++) { 720 mac_addr &addr = params.ap[i].bssid; 721 printMsg("%02x:%02x:%02x:%02x:%02x:%02x\t%d\t%d\n", addr[0], 722 addr[1], addr[2], addr[3], addr[4], addr[5], 723 params.ap[i].high, params.ap[i].low); 724 } 725 726 wifi_hotlist_ap_found_handler handler; 727 handler.on_hotlist_ap_found = &onHotlistAPFound; 728 handler.on_hotlist_ap_lost = &onHotlistAPLost; 729 hotlistCmdId = getNewCmdId(); 730 printMsg("Setting hotlist APs threshold\n"); 731 return wifi_set_bssid_hotlist(hotlistCmdId, wlan0Handle, params, handler); 732 } 733 734 static void resetHotlistAPs() { 735 printMsg(", stoping Hotlist AP scanning\n"); 736 wifi_reset_bssid_hotlist(hotlistCmdId, wlan0Handle); 737 } 738 739 static void setPnoMacOui() { 740 wifi_set_scanning_mac_oui(wlan0Handle, mac_oui); 741 } 742 743 static void testHotlistAPs(){ 744 745 EventInfo info; 746 memset(&info, 0, sizeof(info)); 747 748 printMsg("starting Hotlist AP scanning\n"); 749 if (!startScan(&onScanResultsAvailable, stest_max_ap,stest_base_period, stest_threshold)) { 750 printMsg("testHotlistAPs failed to start scan!!\n"); 751 return; 752 } 753 754 int result = setHotlistAPs(); 755 if (result == WIFI_SUCCESS) { 756 printMsg("Waiting for Hotlist AP event\n"); 757 while (true) { 758 memset(&info, 0, sizeof(info)); 759 getEventFromCache(info); 760 761 if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE) { 762 retrieveScanResults(); 763 } else if (info.type == EVENT_TYPE_HOTLIST_AP_FOUND || 764 info.type == EVENT_TYPE_HOTLIST_AP_LOST) { 765 printMsg("Hotlist APs"); 766 if (--max_event_wait > 0) 767 printMsg(", waiting for more event ::%d\n", max_event_wait); 768 else 769 break; 770 } 771 } 772 resetHotlistAPs(); 773 } else { 774 printMsg("Could not set AP hotlist : %d\n", result); 775 } 776 } 777 778 static void onSignificantWifiChange(wifi_request_id id, 779 unsigned num_results, wifi_significant_change_result **results) 780 { 781 printMsg("Significant wifi change for %d\n", num_results); 782 for (unsigned i = 0; i < num_results; i++) { 783 printSignificantChangeResult(results[i]); 784 } 785 putEventInCache(EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE, "significant wifi change noticed"); 786 } 787 788 static int SelectSignificantAPsFromScanResults() { 789 wifi_scan_result results[256]; 790 memset(results, 0, sizeof(wifi_scan_result) * 256); 791 printMsg("Retrieving scan results for significant wifi change setting\n"); 792 int num_results = 256; 793 int result = wifi_get_cached_gscan_results(wlan0Handle, 1, num_results, results, &num_results); 794 if (result < 0) { 795 printMsg("failed to fetch scan results : %d\n", result); 796 return WIFI_ERROR_UNKNOWN; 797 } else { 798 printMsg("fetched %d scan results\n", num_results); 799 } 800 801 for (int i = 0; i < num_results; i++) { 802 printScanResult(results[i]); 803 } 804 805 wifi_significant_change_params params; 806 memset(¶ms, 0, sizeof(params)); 807 808 params.rssi_sample_size = swctest_rssi_sample_size; 809 params.lost_ap_sample_size = swctest_rssi_lost_ap; 810 params.min_breaching = swctest_rssi_min_breaching; 811 812 for (int i = 0; i < stest_max_ap; i++) { 813 memcpy(params.ap[i].bssid, results[i].bssid, sizeof(mac_addr)); 814 params.ap[i].low = results[i].rssi - swctest_rssi_ch_threshold; 815 params.ap[i].high = results[i].rssi + swctest_rssi_ch_threshold; 816 } 817 params.num_ap = stest_max_ap; 818 819 printMsg("Settting Significant change params rssi_sample_size#%d lost_ap_sample_size#%d" 820 " and min_breaching#%d\n", params.rssi_sample_size, 821 params.lost_ap_sample_size , params.min_breaching); 822 printMsg("BSSID\t\t\tHIGH\tLOW\n"); 823 for (int i = 0; i < params.num_ap; i++) { 824 mac_addr &addr = params.ap[i].bssid; 825 printMsg("%02x:%02x:%02x:%02x:%02x:%02x\t%d\t%d\n", addr[0], 826 addr[1], addr[2], addr[3], addr[4], addr[5], 827 params.ap[i].high, params.ap[i].low); 828 } 829 wifi_significant_change_handler handler; 830 memset(&handler, 0, sizeof(handler)); 831 handler.on_significant_change = &onSignificantWifiChange; 832 833 int id = getNewCmdId(); 834 return wifi_set_significant_change_handler(id, wlan0Handle, params, handler); 835 836 } 837 838 static void untrackSignificantChange() { 839 printMsg(", Stop tracking SignificantChange\n"); 840 wifi_reset_bssid_hotlist(hotlistCmdId, wlan0Handle); 841 } 842 843 static void trackSignificantChange() { 844 printMsg("starting trackSignificantChange\n"); 845 846 if (!startScan(&onScanResultsAvailable, stest_max_ap,stest_base_period, stest_threshold)) { 847 printMsg("trackSignificantChange failed to start scan!!\n"); 848 return; 849 } else { 850 printMsg("trackSignificantChange Scan started, waiting for event ...\n"); 851 } 852 853 EventInfo info; 854 memset(&info, 0, sizeof(info)); 855 getEventFromCache(info); 856 857 int result = SelectSignificantAPsFromScanResults(); 858 if (result == WIFI_SUCCESS) { 859 printMsg("Waiting for significant wifi change event\n"); 860 while (true) { 861 memset(&info, 0, sizeof(info)); 862 getEventFromCache(info); 863 864 if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE) { 865 retrieveScanResults(); 866 } else if(info.type == EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE) { 867 printMsg("Received significant wifi change"); 868 if (--max_event_wait > 0) 869 printMsg(", waiting for more event ::%d\n", max_event_wait); 870 else 871 break; 872 } 873 } 874 untrackSignificantChange(); 875 } else { 876 printMsg("Failed to set significant change ::%d\n", result); 877 } 878 } 879 880 /* ------------------------------------------- */ 881 /* tests */ 882 /* ------------------------------------------- */ 883 884 void testScan() { 885 printf("starting scan with max_ap_per_scan#%d base_period#%d threshold#%d \n", 886 stest_max_ap,stest_base_period, stest_threshold); 887 if (!startScan(&onScanResultsAvailable, stest_max_ap,stest_base_period, stest_threshold)) { 888 printMsg("failed to start scan!!\n"); 889 return; 890 } else { 891 EventInfo info; 892 memset(&info, 0, sizeof(info)); 893 894 while (true) { 895 getEventFromCache(info); 896 printMsg("retrieved event %d : %s\n", info.type, info.buf); 897 retrieveScanResults(); 898 if(--max_event_wait > 0) 899 printMsg("Waiting for more :: %d event \n", max_event_wait); 900 else 901 break; 902 } 903 904 stopScan(); 905 printMsg("stopped scan\n"); 906 } 907 } 908 909 void testStopScan() { 910 stopScan(); 911 printMsg("stopped scan\n"); 912 } 913 914 byte parseHexChar(char ch) { 915 if (isdigit(ch)) 916 return ch - '0'; 917 else if ('A' <= ch && ch <= 'F') 918 return ch - 'A' + 10; 919 else if ('a' <= ch && ch <= 'f') 920 return ch - 'a' + 10; 921 else { 922 printMsg("invalid character in bssid %c\n", ch); 923 return 0; 924 } 925 } 926 927 byte parseHexByte(char ch1, char ch2) { 928 return (parseHexChar(ch1) << 4) | parseHexChar(ch2); 929 } 930 931 void parseMacAddress(const char *str, mac_addr addr) { 932 addr[0] = parseHexByte(str[0], str[1]); 933 addr[1] = parseHexByte(str[3], str[4]); 934 addr[2] = parseHexByte(str[6], str[7]); 935 addr[3] = parseHexByte(str[9], str[10]); 936 addr[4] = parseHexByte(str[12], str[13]); 937 addr[5] = parseHexByte(str[15], str[16]); 938 // printMsg("read mac addr: %02x:%02x:%02x:%02x:%02x:%02x\n", addr[0], 939 // addr[1], addr[2], addr[3], addr[4], addr[5]); 940 } 941 942 void parseMacOUI(char *str, unsigned char *addr) { 943 addr[0] = parseHexByte(str[0], str[1]); 944 addr[1] = parseHexByte(str[3], str[4]); 945 addr[2] = parseHexByte(str[6], str[7]); 946 printMsg("read mac OUI: %02x:%02x:%02x\n", addr[0], 947 addr[1], addr[2]); 948 } 949 950 void readTestOptions(int argc, char *argv[]){ 951 952 printf("Total number of argc #%d\n", argc); 953 for (int j = 1; j < argc-1; j++) { 954 if (strcmp(argv[j], "-max_ap") == 0 && isdigit(argv[j+1][0])) { 955 stest_max_ap = atoi(argv[++j]); 956 printf(" max_ap #%d\n", stest_max_ap); 957 } else if (strcmp(argv[j], "-base_period") == 0 && isdigit(argv[j+1][0])) { 958 stest_base_period = atoi(argv[++j]); 959 printf(" base_period #%d\n", stest_base_period); 960 } else if (strcmp(argv[j], "-threshold") == 0 && isdigit(argv[j+1][0])) { 961 stest_threshold = atoi(argv[++j]); 962 printf(" threshold #%d\n", stest_threshold); 963 } else if (strcmp(argv[j], "-avg_RSSI") == 0 && isdigit(argv[j+1][0])) { 964 swctest_rssi_sample_size = atoi(argv[++j]); 965 printf(" avg_RSSI #%d\n", swctest_rssi_sample_size); 966 } else if (strcmp(argv[j], "-ap_loss") == 0 && isdigit(argv[j+1][0])) { 967 swctest_rssi_lost_ap = atoi(argv[++j]); 968 printf(" ap_loss #%d\n", swctest_rssi_lost_ap); 969 } else if (strcmp(argv[j], "-ap_breach") == 0 && isdigit(argv[j+1][0])) { 970 swctest_rssi_min_breaching = atoi(argv[++j]); 971 printf(" ap_breach #%d\n", swctest_rssi_min_breaching); 972 } else if (strcmp(argv[j], "-ch_threshold") == 0 && isdigit(argv[j+1][0])) { 973 swctest_rssi_ch_threshold = atoi(argv[++j]); 974 printf(" ch_threshold #%d\n", swctest_rssi_ch_threshold); 975 } else if (strcmp(argv[j], "-wt_event") == 0 && isdigit(argv[j+1][0])) { 976 max_event_wait = atoi(argv[++j]); 977 printf(" wt_event #%d\n", max_event_wait); 978 } else if (strcmp(argv[j], "-low_th") == 0 && isdigit(argv[j+1][0])) { 979 htest_low_threshold = atoi(argv[++j]); 980 printf(" low_threshold #-%d\n", htest_low_threshold); 981 } else if (strcmp(argv[j], "-high_th") == 0 && isdigit(argv[j+1][0])) { 982 htest_high_threshold = atoi(argv[++j]); 983 printf(" high_threshold #-%d\n", htest_high_threshold); 984 } else if (strcmp(argv[j], "-hotlist_bssids") == 0 && isxdigit(argv[j+1][0])) { 985 j++; 986 for (num_hotlist_bssids = 0; 987 j < argc && isxdigit(argv[j][0]); 988 j++, num_hotlist_bssids++) { 989 parseMacAddress(argv[j], hotlist_bssids[num_hotlist_bssids]); 990 } 991 j -= 1; 992 } else if (strcmp(argv[j], "-channel_list") == 0 && isxdigit(argv[j+1][0])) { 993 j++; 994 for (num_channels = 0; j < argc && isxdigit(argv[j][0]); j++, num_channels++) { 995 channel_list[num_channels] = atoi(argv[j]); 996 } 997 j -= 1; 998 } else if ((strcmp(argv[j], "-get_ch_list") == 0)) { 999 if(strcmp(argv[j + 1], "a") == 0) { 1000 band = WIFI_BAND_A_WITH_DFS; 1001 } else if(strcmp(argv[j + 1], "bg") == 0) { 1002 band = WIFI_BAND_BG; 1003 } else if(strcmp(argv[j + 1], "abg") == 0) { 1004 band = WIFI_BAND_ABG_WITH_DFS; 1005 } else if(strcmp(argv[j + 1], "a_nodfs") == 0) { 1006 band = WIFI_BAND_A; 1007 } else if(strcmp(argv[j + 1], "dfs") == 0) { 1008 band = WIFI_BAND_A_DFS; 1009 } else if(strcmp(argv[j + 1], "abg_nodfs") == 0) { 1010 band = WIFI_BAND_ABG; 1011 } 1012 j++; 1013 } else if ((strcmp(argv[j], "-rtt_samples") == 0)) { 1014 rtt_samples = atoi(argv[++j]); 1015 printf(" rtt_retries #-%d\n", rtt_samples); 1016 } else if (strcmp(argv[j], "-scan_mac_oui") == 0 && isxdigit(argv[j+1][0])) { 1017 parseMacOUI(argv[++j], mac_oui); 1018 } 1019 } 1020 } 1021 1022 wifi_iface_stat link_stat; 1023 wifi_radio_stat trx_stat; 1024 wifi_peer_info peer_info; 1025 wifi_rate_stat rate_stat[32]; 1026 void onLinkStatsResults(wifi_request_id id, wifi_iface_stat *iface_stat, 1027 int num_radios, wifi_radio_stat *radio_stat) 1028 { 1029 int num_peer = iface_stat->num_peers; 1030 memcpy(&trx_stat, radio_stat, sizeof(wifi_radio_stat)); 1031 memcpy(&link_stat, iface_stat, sizeof(wifi_iface_stat)); 1032 memcpy(&peer_info, iface_stat->peer_info, num_peer*sizeof(wifi_peer_info)); 1033 int num_rate = peer_info.num_rate; 1034 memcpy(&rate_stat, iface_stat->peer_info->rate_stats, num_rate*sizeof(wifi_rate_stat)); 1035 } 1036 1037 void printFeatureListBitMask(void) 1038 { 1039 printMsg("WIFI_FEATURE_INFRA 0x0001 - Basic infrastructure mode\n"); 1040 printMsg("WIFI_FEATURE_INFRA_5G 0x0002 - Support for 5 GHz Band\n"); 1041 printMsg("WIFI_FEATURE_HOTSPOT 0x0004 - Support for GAS/ANQP\n"); 1042 printMsg("WIFI_FEATURE_P2P 0x0008 - Wifi-Direct\n"); 1043 printMsg("WIFI_FEATURE_SOFT_AP 0x0010 - Soft AP\n"); 1044 printMsg("WIFI_FEATURE_GSCAN 0x0020 - Google-Scan APIs\n"); 1045 printMsg("WIFI_FEATURE_NAN 0x0040 - Neighbor Awareness Networking\n"); 1046 printMsg("WIFI_FEATURE_D2D_RTT 0x0080 - Device-to-device RTT\n"); 1047 printMsg("WIFI_FEATURE_D2AP_RTT 0x0100 - Device-to-AP RTT\n"); 1048 printMsg("WIFI_FEATURE_BATCH_SCAN 0x0200 - Batched Scan (legacy)\n"); 1049 printMsg("WIFI_FEATURE_PNO 0x0400 - Preferred network offload\n"); 1050 printMsg("WIFI_FEATURE_ADDITIONAL_STA 0x0800 - Support for two STAs\n"); 1051 printMsg("WIFI_FEATURE_TDLS 0x1000 - Tunnel directed link setup\n"); 1052 printMsg("WIFI_FEATURE_TDLS_OFFCHANNEL 0x2000 - Support for TDLS off channel\n"); 1053 printMsg("WIFI_FEATURE_EPR 0x4000 - Enhanced power reporting\n"); 1054 printMsg("WIFI_FEATURE_AP_STA 0x8000 - Support for AP STA Concurrency\n"); 1055 } 1056 1057 char *rates[] = { 1058 "1Mbps", 1059 "2Mbps", 1060 "5.5Mbps", 1061 "6Mbps", 1062 "9Mbps", 1063 "11Mbps", 1064 "12Mbps", 1065 "18Mbps", 1066 "24Mbps", 1067 "36Mbps", 1068 "48Mbps", 1069 "54Mbps", 1070 "VHT MCS0 ss1", 1071 "VHT MCS1 ss1", 1072 "VHT MCS2 ss1", 1073 "VHT MCS3 ss1", 1074 "VHT MCS4 ss1", 1075 "VHT MCS5 ss1", 1076 "VHT MCS6 ss1", 1077 "VHT MCS7 ss1", 1078 "VHT MCS8 ss1", 1079 "VHT MCS9 ss1", 1080 "VHT MCS0 ss2", 1081 "VHT MCS1 ss2", 1082 "VHT MCS2 ss2", 1083 "VHT MCS3 ss2", 1084 "VHT MCS4 ss2", 1085 "VHT MCS5 ss2", 1086 "VHT MCS6 ss2", 1087 "VHT MCS7 ss2", 1088 "VHT MCS8 ss2", 1089 "VHT MCS9 ss2" 1090 }; 1091 1092 void printLinkStats(wifi_iface_stat link_stat, wifi_radio_stat trx_stat) 1093 { 1094 printMsg("Printing link layer statistics:\n"); 1095 printMsg("-------------------------------\n"); 1096 printMsg("beacon_rx = %d\n", link_stat.beacon_rx); 1097 printMsg("RSSI = %d\n", link_stat.rssi_mgmt); 1098 printMsg("AC_BE:\n"); 1099 printMsg("txmpdu = %d\n", link_stat.ac[WIFI_AC_BE].tx_mpdu); 1100 printMsg("rxmpdu = %d\n", link_stat.ac[WIFI_AC_BE].rx_mpdu); 1101 printMsg("mpdu_lost = %d\n", link_stat.ac[WIFI_AC_BE].mpdu_lost); 1102 printMsg("retries = %d\n", link_stat.ac[WIFI_AC_BE].retries); 1103 printMsg("AC_BK:\n"); 1104 printMsg("txmpdu = %d\n", link_stat.ac[WIFI_AC_BK].tx_mpdu); 1105 printMsg("rxmpdu = %d\n", link_stat.ac[WIFI_AC_BK].rx_mpdu); 1106 printMsg("mpdu_lost = %d\n", link_stat.ac[WIFI_AC_BK].mpdu_lost); 1107 printMsg("AC_VI:\n"); 1108 printMsg("txmpdu = %d\n", link_stat.ac[WIFI_AC_VI].tx_mpdu); 1109 printMsg("rxmpdu = %d\n", link_stat.ac[WIFI_AC_VI].rx_mpdu); 1110 printMsg("mpdu_lost = %d\n", link_stat.ac[WIFI_AC_VI].mpdu_lost); 1111 printMsg("AC_VO:\n"); 1112 printMsg("txmpdu = %d\n", link_stat.ac[WIFI_AC_VO].tx_mpdu); 1113 printMsg("rxmpdu = %d\n", link_stat.ac[WIFI_AC_VO].rx_mpdu); 1114 printMsg("mpdu_lost = %d\n", link_stat.ac[WIFI_AC_VO].mpdu_lost); 1115 printMsg("\n"); 1116 printMsg("Printing radio statistics:\n"); 1117 printMsg("--------------------------\n"); 1118 printMsg("on time = %d\n", trx_stat.on_time); 1119 printMsg("tx time = %d\n", trx_stat.tx_time); 1120 printMsg("rx time = %d\n", trx_stat.rx_time); 1121 printMsg("\n"); 1122 printMsg("Printing rate statistics:\n"); 1123 printMsg("-------------------------\n"); 1124 printMsg("%27s %12s %14s %15s\n", "TX", "RX", "LOST", "RETRIES"); 1125 for (int i=0; i < 32; i++) { 1126 printMsg("%-15s %10d %10d %10d %10d\n", 1127 rates[i], rate_stat[i].tx_mpdu, rate_stat[i].rx_mpdu, 1128 rate_stat[i].mpdu_lost, rate_stat[i].retries); 1129 } 1130 } 1131 1132 void getLinkStats(void) 1133 { 1134 wifi_stats_result_handler handler; 1135 memset(&handler, 0, sizeof(handler)); 1136 handler.on_link_stats_results = &onLinkStatsResults; 1137 1138 int result = wifi_get_link_stats(0, wlan0Handle, handler); 1139 if (result < 0) { 1140 printMsg("failed to get link statistics - %d\n", result); 1141 } else { 1142 printLinkStats(link_stat, trx_stat); 1143 } 1144 } 1145 1146 void getChannelList(void) 1147 { 1148 wifi_channel channel[MAX_CH_BUF_SIZE]; 1149 int num_channels = 0, i; 1150 1151 int result = wifi_get_valid_channels(wlan0Handle, band, MAX_CH_BUF_SIZE, 1152 channel, &num_channels); 1153 printMsg("Number of channels - %d\nChannel List:\n",num_channels); 1154 for (i = 0; i < num_channels; i++) { 1155 printMsg("%d MHz\n", channel[i]); 1156 } 1157 } 1158 1159 void getFeatureSet(void) 1160 { 1161 feature_set set; 1162 int result = wifi_get_supported_feature_set(wlan0Handle, &set); 1163 1164 if (result < 0) { 1165 printMsg("Error %d\n",result); 1166 return; 1167 } 1168 printFeatureListBitMask(); 1169 printMsg("Supported feature set bit mask - %x\n", set); 1170 return; 1171 } 1172 1173 void getFeatureSetMatrix(void) 1174 { 1175 feature_set set[MAX_FEATURE_SET]; 1176 int size; 1177 1178 int result = wifi_get_concurrency_matrix(wlan0Handle, MAX_FEATURE_SET, set, &size); 1179 1180 if (result < 0) { 1181 printMsg("Error %d\n",result); 1182 return; 1183 } 1184 printFeatureListBitMask(); 1185 for (int i = 0; i < size; i++) 1186 printMsg("Concurrent feature set - %x\n", set[i]); 1187 return; 1188 } 1189 1190 1191 1192 int main(int argc, char *argv[]) { 1193 1194 pthread_mutex_init(&printMutex, NULL); 1195 1196 if (init() != 0) { 1197 printMsg("could not initiate HAL"); 1198 return -1; 1199 } else { 1200 printMsg("successfully initialized HAL; wlan0 = %p\n", wlan0Handle); 1201 } 1202 1203 pthread_cond_init(&eventCacheCondition, NULL); 1204 pthread_mutex_init(&eventCacheMutex, NULL); 1205 1206 pthread_t tidEvent; 1207 pthread_create(&tidEvent, NULL, &eventThreadFunc, NULL); 1208 1209 sleep(2); // let the thread start 1210 1211 if (argc < 2 || argv[1][0] != '-') { 1212 printf("Usage: halutil [OPTION]\n"); 1213 printf(" -s start AP scan test\n"); 1214 printf(" -swc start Significant Wifi change test\n"); 1215 printf(" -h start Hotlist APs scan test\n"); 1216 printf(" -ss stop scan test\n"); 1217 printf(" -max_ap Max AP for scan \n"); 1218 printf(" -base_period Base period for scan \n"); 1219 printf(" -threshold Threshold scan test\n"); 1220 printf(" -avg_RSSI samples for averaging RSSI\n"); 1221 printf(" -ap_loss samples to confirm AP loss\n"); 1222 printf(" -ap_breach APs breaching threshold\n"); 1223 printf(" -ch_threshold Change in threshold\n"); 1224 printf(" -wt_event Waiting event for test\n"); 1225 printf(" -low_th Low threshold for hotlist APs\n"); 1226 printf(" -hight_th High threshold for hotlist APs\n"); 1227 printf(" -hotlist_bssids BSSIDs for hotlist test\n"); 1228 printf(" -stats print link layer statistics\n"); 1229 printf(" -get_ch_list <a/bg/abg/a_nodfs/abg_nodfs/dfs> Get channel list\n"); 1230 printf(" -get_feature_set Get Feature set\n"); 1231 printf(" -get_feature_matrix Get concurrent feature matrix\n"); 1232 printf(" -rtt Run RTT on nearby APs\n"); 1233 printf(" -rtt_samples Run RTT on nearby APs\n"); 1234 printf(" -scan_mac_oui XY:AB:CD\n"); 1235 printf(" -nodfs <0|1> Turn OFF/ON non-DFS locales\n"); 1236 goto cleanup; 1237 } 1238 memset(mac_oui, 0, 3); 1239 1240 if (strcmp(argv[1], "-s") == 0) { 1241 readTestOptions(argc, argv); 1242 setPnoMacOui(); 1243 testScan(); 1244 }else if(strcmp(argv[1], "-swc") == 0){ 1245 readTestOptions(argc, argv); 1246 setPnoMacOui(); 1247 trackSignificantChange(); 1248 }else if (strcmp(argv[1], "-ss") == 0) { 1249 // Stop scan so clear the OUI too 1250 setPnoMacOui(); 1251 testStopScan(); 1252 }else if ((strcmp(argv[1], "-h") == 0) || 1253 (strcmp(argv[1], "-hotlist_bssids") == 0)) { 1254 readTestOptions(argc, argv); 1255 setPnoMacOui(); 1256 testHotlistAPs(); 1257 }else if (strcmp(argv[1], "-stats") == 0) { 1258 getLinkStats(); 1259 } else if ((strcmp(argv[1], "-rtt") == 0)) { 1260 readTestOptions(argc, argv); 1261 testRTT(); 1262 } else if ((strcmp(argv[1], "-get_ch_list") == 0)) { 1263 readTestOptions(argc, argv); 1264 getChannelList(); 1265 } else if ((strcmp(argv[1], "-get_feature_set") == 0)) { 1266 getFeatureSet(); 1267 } else if ((strcmp(argv[1], "-get_feature_matrix") == 0)) { 1268 getFeatureSetMatrix(); 1269 } else if ((strcmp(argv[1], "-scan_mac_oui") == 0)) { 1270 readTestOptions(argc, argv); 1271 setPnoMacOui(); 1272 testScan(); 1273 } else if (strcmp(argv[1], "-nodfs") == 0) { 1274 u32 nodfs = 0; 1275 if (argc > 2) 1276 nodfs = (u32)atoi(argv[2]); 1277 wifi_set_nodfs_flag(wlan0Handle, nodfs); 1278 } 1279 cleanup: 1280 cleanup(); 1281 return 0; 1282 } 1283