199d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde#include <stdint.h>
2ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann#include <stdlib.h>
37f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
47f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde#include "wifi_hal.h"
57f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
67f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde#define LOG_TAG  "WifiHAL"
77f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
87f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde#include <utils/Log.h>
97f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde#include <inttypes.h>
10a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde#include <sys/socket.h>
11a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde#include <linux/if.h>
12ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann#include <ctype.h>
13ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann#include <stdarg.h>
14ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
15ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannpthread_mutex_t printMutex;
16ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid printMsg(const char *fmt, ...)
17ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann{
18ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_lock(&printMutex);
19ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    va_list l;
20ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    va_start(l, fmt);
21ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
22ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    vprintf(fmt, l);
23ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    va_end(l);
24ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_unlock(&printMutex);
25ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
26ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
2751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandetemplate<typename T, unsigned N>
2851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandeunsigned countof(T (&rgt)[N]) {
2951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    return N;
3051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande}
3151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
3251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandetemplate<typename T>
3351da80208c650a8271a18b0ca8681279ba060e1fVinit DeshpandeT min(const T& t1, const T& t2) {
3451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    return (t1 < t2) ? t1 : t2;
3551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande}
36a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
377f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde#define EVENT_BUF_SIZE 2048
3817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat#define MAX_CH_BUF_SIZE  64
3917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat#define MAX_FEATURE_SET  8
40a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin#define HOTLIST_LOST_WINDOW  5
417f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
427f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic wifi_handle halHandle;
437f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic wifi_interface_handle *ifaceHandles;
44a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapndestatic wifi_interface_handle wlan0Handle;
45a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapndestatic wifi_interface_handle p2p0Handle;
467f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int numIfaceHandles;
477f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int cmdId = 0;
48a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapndestatic int ioctl_sock = 0;
49ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int max_event_wait = 5;
50ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int stest_max_ap = 10;
519eba75b3904b23b4d16b89641bcfcd26f2a833c7Navtej Singh Mannstatic int stest_base_period = 5000;
52ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int stest_threshold = 80;
53ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int swctest_rssi_sample_size =  3;
54ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int swctest_rssi_lost_ap =  3;
55ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int swctest_rssi_min_breaching =  2;
56ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int swctest_rssi_ch_threshold =  1;
57ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int htest_low_threshold =  90;
58ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int htest_high_threshold =  10;
5951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandestatic int rtt_samples = 30;
6017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhatstatic wifi_band band = WIFI_BAND_UNSPECIFIED;
61ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
62ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannmac_addr hotlist_bssids[16];
63a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwinunsigned char mac_oui[3];
649eba75b3904b23b4d16b89641bcfcd26f2a833c7Navtej Singh Mannint channel_list[16];
65ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannint num_hotlist_bssids = 0;
669eba75b3904b23b4d16b89641bcfcd26f2a833c7Navtej Singh Mannint num_channels = 0;
67a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
6851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandevoid parseMacAddress(const char *str, mac_addr addr);
6951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
70a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapndeint linux_set_iface_flags(int sock, const char *ifname, int dev_up)
71a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde{
72ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    struct ifreq ifr;
73ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int ret;
74a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
75ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("setting interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
76a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
77ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (sock < 0) {
78ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Bad socket: %d\n", sock);
79ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      return -1;
80ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
81a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
82ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&ifr, 0, sizeof(ifr));
83ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
84a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
85ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("reading old value\n");
86a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
87ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
88ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      ret = errno ? -errno : -999;
89ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Could not read interface %s flags: %d\n", ifname, errno);
90ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      return ret;
91ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else {
92ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("writing new value\n");
93ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
94a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
95ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (dev_up) {
96ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      if (ifr.ifr_flags & IFF_UP) {
97ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("interface %s is already up\n", ifname);
98ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return 0;
99ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      }
100ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      ifr.ifr_flags |= IFF_UP;
101ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else {
102ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      if (!(ifr.ifr_flags & IFF_UP)) {
103ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("interface %s is already down\n", ifname);
104ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return 0;
105ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      }
106ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      ifr.ifr_flags &= ~IFF_UP;
107ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
108a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
109ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
110ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Could not set interface %s flags \n", ifname);
111ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      return ret;
112ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else {
113ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("set interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
114ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
115ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Done\n");
116ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    return 0;
117a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde}
118a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
1197f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1207f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int init() {
121a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
122a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
123a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    if (ioctl_sock < 0) {
124ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Bad socket: %d\n", ioctl_sock);
125ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      return errno;
126a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    } else {
127ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Good socket: %d\n", ioctl_sock);
128a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    }
129a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
130a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    int ret = linux_set_iface_flags(ioctl_sock, "wlan0", 1);
131a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    if (ret < 0) {
132a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde        return ret;
133a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    }
134a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
1357f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    wifi_error res = wifi_initialize(&halHandle);
1367f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    if (res < 0) {
1377f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        return res;
1387f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
1397f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1407f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    res = wifi_get_ifaces(halHandle, &numIfaceHandles, &ifaceHandles);
1417f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    if (res < 0) {
1427f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        return res;
1437f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
1447f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1457f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    char buf[EVENT_BUF_SIZE];
1467f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    for (int i = 0; i < numIfaceHandles; i++) {
1477f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
148a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde            if (strcmp(buf, "wlan0") == 0) {
149ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                printMsg("found interface %s\n", buf);
150a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde                wlan0Handle = ifaceHandles[i];
151a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde            } else if (strcmp(buf, "p2p0") == 0) {
152ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                printMsg("found interface %s\n", buf);
153a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde                p2p0Handle = ifaceHandles[i];
154a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde            }
1557f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        }
1567f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
1577f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1587f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    return res;
1597f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1607f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1617f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic void cleaned_up_handler(wifi_handle handle) {
162ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("HAL cleaned up handler\n");
1637f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    halHandle = NULL;
1647f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    ifaceHandles = NULL;
1657f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1667f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1677f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic void cleanup() {
168ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("cleaning up HAL\n");
1697f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    wifi_cleanup(halHandle, cleaned_up_handler);
1707f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1717f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1727f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic void *eventThreadFunc(void *context) {
1737f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
174ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("starting wifi event loop\n");
1757f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    wifi_event_loop(halHandle);
176ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("out of wifi event loop\n");
1777f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1787f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    return NULL;
1797f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1807f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1817f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1827f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int getNewCmdId() {
1837f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    return cmdId++;
1847f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1857f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1867f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
1877f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* helpers                                      */
1887f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
1897f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
190ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid printScanHeader() {
191ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("SSID\t\t\t\t\tBSSID\t\t  RSSI\tchannel\ttimestamp\tRTT\tRTT SD\n");
192ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
193ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
1947f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndevoid printScanResult(wifi_scan_result result) {
1957f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
196ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%-32s\t", result.ssid);
1977f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
198ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%02x:%02x:%02x:%02x:%02x:%02x ", result.bssid[0], result.bssid[1],
1997f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde            result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]);
2007f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
201ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%d\t", result.rssi);
202ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%d\t", result.channel);
203ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%lld\t", result.ts);
204ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%lld\t", result.rtt);
205ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%lld\n", result.rtt_sd);
2067f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
2077f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
208a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpandevoid printSignificantChangeResult(wifi_significant_change_result *res) {
209a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande
210a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    wifi_significant_change_result &result = *res;
211a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    printMsg("%02x:%02x:%02x:%02x:%02x:%02x ", result.bssid[0], result.bssid[1],
212a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande            result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]);
213a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande
214a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    printMsg("%d\t", result.channel);
215a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande
216a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    for (int i = 0; i < result.num_rssi; i++) {
21717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printMsg("%d,", result.rssi[i]);
218a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    }
21917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("\n");
220a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande}
221a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande
22299d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapndevoid printScanCapabilities(wifi_gscan_capabilities capabilities)
22399d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde{
224ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_scan_cache_size = %d\n", capabilities.max_scan_cache_size);
225ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_scan_buckets = %d\n", capabilities.max_scan_buckets);
226ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_ap_cache_per_scan = %d\n", capabilities.max_ap_cache_per_scan);
227ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_rssi_sample_size = %d\n", capabilities.max_rssi_sample_size);
228ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_scan_reporting_threshold = %d\n", capabilities.max_scan_reporting_threshold);
229ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_hotlist_aps = %d\n", capabilities.max_hotlist_aps);
230200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("max_significant_wifi_change_aps = %d\n",
231200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    capabilities.max_significant_wifi_change_aps);
23299d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde}
23399d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde
2347f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
2357f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
2367f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* commands and events                          */
2377f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
2387f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
239ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Manntypedef enum {
240ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EVENT_TYPE_SCAN_RESULTS_AVAILABLE = 1000,
241ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EVENT_TYPE_HOTLIST_AP_FOUND = 1001,
24217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE = 1002,
24351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    EVENT_TYPE_RTT_RESULTS = 1003,
244a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    EVENT_TYPE_SCAN_COMPLETE = 1004,
245a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    EVENT_TYPE_HOTLIST_AP_LOST = 1005
246ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann} EventType;
247ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
248ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Manntypedef struct {
249ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int type;
250ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    char buf[256];
251ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann} EventInfo;
252ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
253ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannconst int MAX_EVENTS_IN_CACHE = 256;
254ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh MannEventInfo eventCache[256];
255ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannint eventsInCache = 0;
256ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannpthread_cond_t eventCacheCondition;
257ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannpthread_mutex_t eventCacheMutex;
258ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
259ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid putEventInCache(int type, const char *msg) {
260ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_lock(&eventCacheMutex);
261ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (eventsInCache + 1 < MAX_EVENTS_IN_CACHE) {
262ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        eventCache[eventsInCache].type = type;
263ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        strcpy(eventCache[eventsInCache].buf, msg);
264ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        eventsInCache++;
265ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        pthread_cond_signal(&eventCacheCondition);
266ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        //printf("put new event in cache; size = %d\n", eventsInCache);
267ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
268ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf("Too many events in the cache\n");
269ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
270ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_unlock(&eventCacheMutex);
271ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
2727f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
273ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid getEventFromCache(EventInfo& info) {
274ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_lock(&eventCacheMutex);
275ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    while (true) {
276ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        if (eventsInCache > 0) {
277ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            //printf("found an event in cache; size = %d\n", eventsInCache);
278ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            info.type = eventCache[0].type;
279ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            strcpy(info.buf, eventCache[0].buf);
280ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            eventsInCache--;
281ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            memmove(&eventCache[0], &eventCache[1], sizeof(EventInfo) * eventsInCache);
282ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            pthread_mutex_unlock(&eventCacheMutex);
283ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            return;
284ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        } else {
285ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            pthread_cond_wait(&eventCacheCondition, &eventCacheMutex);
286ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            //printf("pthread_cond_wait unblocked ...\n");
287ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        }
288ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
289ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
2907f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
291ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannint numScanResultsAvailable = 0;
292ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void onScanResultsAvailable(wifi_request_id id, unsigned num_results) {
293ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Received scan results available event\n");
294ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    numScanResultsAvailable = num_results;
295ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    putEventInCache(EVENT_TYPE_SCAN_RESULTS_AVAILABLE, "New scan results are available");
2967f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
2977f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
29817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhatstatic void on_scan_event(wifi_scan_event event, unsigned status) {
29951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    if (event == WIFI_SCAN_BUFFER_FULL) {
30017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printMsg("Received scan complete event - WIFI_SCAN_BUFFER_FULL \n");
30151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    } else if(event == WIFI_SCAN_COMPLETE) {
30217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printMsg("Received scan complete event  - WIFI_SCAN_COMPLETE\n");
30351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    }
30417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat}
30517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
3067f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int scanCmdId;
307ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int hotlistCmdId;
308ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int significantChangeCmdId;
30917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhatstatic int rttCmdId;
31017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
311ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic bool startScan( void (*pfnOnResultsAvailable)(wifi_request_id, unsigned),
312ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                       int max_ap_per_scan, int base_period, int report_threshold) {
3137f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
31499d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    /* Get capabilties */
31599d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    wifi_gscan_capabilities capabilities;
31699d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    int result = wifi_get_gscan_capabilities(wlan0Handle, &capabilities);
31799d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    if (result < 0) {
318ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("failed to get scan capabilities - %d\n", result);
319ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("trying scan anyway ..\n");
32099d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    } else {
32199d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde        printScanCapabilities(capabilities);
32299d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    }
32399d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde
3247f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    wifi_scan_cmd_params params;
3257f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    memset(&params, 0, sizeof(params));
3267f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
3279eba75b3904b23b4d16b89641bcfcd26f2a833c7Navtej Singh Mann    if(num_channels > 0){
32851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        params.max_ap_per_scan = max_ap_per_scan;
32951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        params.base_period = base_period;                      // 5 second by default
33051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        params.report_threshold = report_threshold;
33151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        params.num_buckets = 1;
33251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
33351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        params.buckets[0].bucket = 0;
33451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        params.buckets[0].band = WIFI_BAND_UNSPECIFIED;
33551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        params.buckets[0].period = base_period;
33651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        params.buckets[0].num_channels = num_channels;
33751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
33851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        for(int i = 0; i < num_channels; i++){
33951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            params.buckets[0].channels[i].channel = channel_list[i];
34051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        }
3419eba75b3904b23b4d16b89641bcfcd26f2a833c7Navtej Singh Mann
3429eba75b3904b23b4d16b89641bcfcd26f2a833c7Navtej Singh Mann    } else {
3439eba75b3904b23b4d16b89641bcfcd26f2a833c7Navtej Singh Mann
34451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        /* create a schedule to scan channels 1, 6, 11 every 5 second and
34551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande         * scan 36, 40, 44, 149, 153, 157, 161 165 every 10 second */
34651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
347a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.max_ap_per_scan = max_ap_per_scan;
348a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.base_period = base_period;                      // 5 second
349a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.report_threshold = report_threshold;
350a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.num_buckets = 3;
351a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin
352a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[0].bucket = 0;
353a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[0].band = WIFI_BAND_UNSPECIFIED;
354a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[0].period = 5000;                // 5 second
355a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[0].report_events = 0;
356a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[0].num_channels = 2;
357a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin
358a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[0].channels[0].channel = 2412;
359a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[0].channels[1].channel = 2437;
360a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin
361a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].bucket = 1;
362a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].band = WIFI_BAND_A;
363a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].period = 10000;               // 10 second
364a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].report_events = 1;
365a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].num_channels = 8;   // driver should ignore list since band is specified
366a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin
367a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin
368a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].channels[0].channel = 5180;
369a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].channels[1].channel = 5200;
370a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].channels[2].channel = 5220;
371a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].channels[3].channel = 5745;
372a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].channels[4].channel = 5765;
373a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].channels[5].channel = 5785;
374a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].channels[6].channel = 5805;
375a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[1].channels[7].channel = 5825;
376a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin
377a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[2].bucket = 2;
378a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[2].band = WIFI_BAND_UNSPECIFIED;
379a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[2].period = 15000;                // 15 second
380a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[2].report_events = 2;
381a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[2].num_channels = 1;
382a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin
383a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin      params.buckets[2].channels[0].channel = 2462;
38451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
3859eba75b3904b23b4d16b89641bcfcd26f2a833c7Navtej Singh Mann    }
386ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
3877f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    wifi_scan_result_handler handler;
3887f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    memset(&handler, 0, sizeof(handler));
389ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    handler.on_scan_results_available = pfnOnResultsAvailable;
39017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    handler.on_scan_event = on_scan_event;
3917f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
3927f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    scanCmdId = getNewCmdId();
393ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Starting scan --->\n");
394a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    return wifi_start_gscan(scanCmdId, wlan0Handle, params, handler) == WIFI_SUCCESS;
3957f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
3967f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
3977f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic void stopScan() {
39817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    wifi_request_id id = scanCmdId;
39917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    if (id == 0)
40017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        id = -1;
40117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
40217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    wifi_stop_gscan(id, wlan0Handle);
40317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    scanCmdId = 0;
404ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
405ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
40651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandewifi_scan_result *saved_scan_results;
40751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandeunsigned max_saved_scan_results;
40851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandeunsigned num_saved_scan_results;
40951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
41051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandestatic void on_single_shot_scan_event(wifi_scan_event event, unsigned status) {
41151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    if (event == WIFI_SCAN_BUFFER_FULL) {
41251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("Received scan complete event - WIFI_SCAN_BUFFER_FULL \n");
41351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    } else if(event == WIFI_SCAN_COMPLETE) {
41451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("Received scan complete event  - WIFI_SCAN_COMPLETE\n");
41551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        putEventInCache(EVENT_TYPE_SCAN_COMPLETE, "One scan completed");
41651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    }
41751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande}
41851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
41951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandestatic void on_full_scan_result(wifi_request_id id, wifi_scan_result *r) {
42051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    if (num_saved_scan_results < max_saved_scan_results) {
42151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        wifi_scan_result *result = &(saved_scan_results[num_saved_scan_results]);
42251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        memcpy(result, r, sizeof(wifi_scan_result));
42351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        //printMsg("Retrieved full scan result for %s(%02x:%02x:%02x:%02x:%02x:%02x)\n",
42451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        //    result->ssid, result->bssid[0], result->bssid[1], result->bssid[2], result->bssid[3],
42551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        //    result->bssid[4], result->bssid[5]);
42651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        num_saved_scan_results++;
42751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    }
42851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande}
42951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
43051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandestatic int scanOnce(wifi_band band, wifi_scan_result *results, int num_results) {
43151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
43251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    saved_scan_results = results;
43351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    max_saved_scan_results = num_results;
43451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    num_saved_scan_results = 0;
43551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
43651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    wifi_scan_cmd_params params;
43751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    memset(&params, 0, sizeof(params));
43851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
43951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    params.max_ap_per_scan = 10;
44051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    params.base_period = 5000;                        // 5 second by default
44151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    params.report_threshold = 90;
44251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    params.num_buckets = 1;
44351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
44451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    params.buckets[0].bucket = 0;
44551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    params.buckets[0].band = band;
44651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    params.buckets[0].period = 5000;                  // 5 second
44751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    params.buckets[0].report_events = 2;              // REPORT_EVENTS_AFTER_EACH_SCAN
44851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    params.buckets[0].num_channels = 0;
44951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
45051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    wifi_scan_result_handler handler;
45151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    memset(&handler, 0, sizeof(handler));
45251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    handler.on_scan_results_available = NULL;
45351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    handler.on_scan_event = on_single_shot_scan_event;
45451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    handler.on_full_scan_result = on_full_scan_result;
45551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
45651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    int scanCmdId = getNewCmdId();
45751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    printMsg("Starting scan --->\n");
45851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    if (wifi_start_gscan(scanCmdId, wlan0Handle, params, handler) == WIFI_SUCCESS) {
45951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        int events = 0;
46051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        while (true) {
46151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            EventInfo info;
46251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            memset(&info, 0, sizeof(info));
46351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            getEventFromCache(info);
46451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE
46551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                || info.type == EVENT_TYPE_SCAN_COMPLETE) {
46651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                int retrieved_num_results = num_saved_scan_results;
46751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                if (retrieved_num_results == 0) {
46851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    printMsg("fetched 0 scan results, waiting for more..\n");
46951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    continue;
47051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                } else {
47151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    printMsg("fetched %d scan results\n", retrieved_num_results);
47251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
47351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    /*
47451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    printScanHeader();
47551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
47651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    for (int i = 0; i < retrieved_num_results; i++) {
47751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                        printScanResult(results[i]);
47851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    }
47951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    */
48051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
48151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    printMsg("Scan once completed, stopping scan\n");
48251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    wifi_stop_gscan(scanCmdId, wlan0Handle);
48351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    saved_scan_results = NULL;
48451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    max_saved_scan_results = 0;
48551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    num_saved_scan_results = 0;
48651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    return retrieved_num_results;
48751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                }
48851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            }
48951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        }
49051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    } else {
49151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        return 0;
49251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    }
49351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande}
49451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
495ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void retrieveScanResults() {
496ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
497ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_scan_result results[256];
498ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(results, 0, sizeof(wifi_scan_result) * 256);
499ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Retrieve Scan results available -->\n");
500ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int num_results = 256;
501a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    int result = wifi_get_cached_gscan_results(wlan0Handle, 1, num_results, results, &num_results);
502ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (result < 0) {
503ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("failed to fetch scan results : %d\n", result);
504ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return;
505ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
506ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("fetched %d scan results\n", num_results);
507ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
508ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
509ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printScanHeader();
510ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < num_results; i++) {
511ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printScanResult(results[i]);
512ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
513ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
514ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
51551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
51651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandestatic int compareScanResultsByRssi(const void *p1, const void *p2) {
51751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    const wifi_scan_result *result1 = static_cast<const wifi_scan_result *>(p1);
51851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    const wifi_scan_result *result2 = static_cast<const wifi_scan_result *>(p2);
51951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
52051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    /* RSSI is -ve, so lower one wins */
52151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    if (result1->rssi < result2->rssi) {
52251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        return 1;
52351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    } else if (result1->rssi == result2->rssi) {
52451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        return 0;
52551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    } else {
52651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        return -1;
52751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    }
52851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande}
52951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
53051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandestatic void sortScanResultsByRssi(wifi_scan_result *results, int num_results) {
53151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    qsort(results, num_results, sizeof(wifi_scan_result), &compareScanResultsByRssi);
53251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande}
53351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
53451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandestatic int removeDuplicateScanResults(wifi_scan_result *results, int num) {
53551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    /* remove duplicates by BSSID */
53651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    int num_results = num;
53751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    for (int i = 0; i < num_results; i++) {
53851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        //printMsg("Processing result[%d] - %02x:%02x:%02x:%02x:%02x:%02x\n", i,
53951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        //        results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
54051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        //        results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]);
54151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
54251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        for (int j = i + 1; j < num_results; ) {
54351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            if (memcmp(results[i].bssid, results[j].bssid, sizeof(mac_addr)) == 0) {
54451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                /* 'remove' this scan result from the list */
54551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                // printMsg("removing dupe entry\n");
54651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                int num_to_move = num_results - j - 1;
54751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                memmove(&results[j], &results[j+1], num_to_move * sizeof(wifi_scan_result));
54851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                num_results--;
54951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            } else {
55051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                j++;
55151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            }
55251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        }
55351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
55451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        // printMsg("num_results = %d\n", num_results);
55551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    }
55651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
55751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    return num_results;
55851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande}
55951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
56017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhatstatic void onRTTResults (wifi_request_id id, unsigned num_results, wifi_rtt_result result[]) {
56151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
56217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("RTT results!!\n");
56351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    printMsg("Addr\t\t\tts\t\tRSSI\tSpread\trtt\tsd\tspread\tdist\tsd\tspread\n");
56451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
56517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    for (unsigned i = 0; i < num_results; i++) {
5661bb0a65449359beec678022b5f192859155ddbe9eccopark        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",
56751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                result[i].addr[0], result[i].addr[1], result[i].addr[2], result[i].addr[3],
56851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                result[i].addr[4], result[i].addr[5], result[i].ts, result[i].rssi,
56951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                result[i].rssi_spread, result[i].rtt, result[i].rtt_sd, result[i].rtt_spread,
57051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                result[i].distance, result[i].distance_sd, result[i].distance_spread);
57117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    }
57251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
57317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    putEventInCache(EVENT_TYPE_RTT_RESULTS, "RTT results");
57417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat}
57517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
576ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void onHotlistAPFound(wifi_request_id id, unsigned num_results, wifi_scan_result *results) {
577ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
578ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Found hotlist APs\n");
579ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (unsigned i = 0; i < num_results; i++) {
580ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printScanResult(results[i]);
581ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
582ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    putEventInCache(EVENT_TYPE_HOTLIST_AP_FOUND, "Found a hotlist AP");
583ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
584ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
585a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwinstatic void onHotlistAPLost(wifi_request_id id, unsigned num_results, wifi_scan_result *results) {
586a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin
587a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    printMsg("Lost hotlist APs\n");
588a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    for (unsigned i = 0; i < num_results; i++) {
589a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        printScanResult(results[i]);
590a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    }
591a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    putEventInCache(EVENT_TYPE_HOTLIST_AP_LOST, "Lost event Hotlist APs");
592a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin}
593a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin
59451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandestatic void testRTT() {
59517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
59617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    wifi_scan_result results[256];
59751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    int num_results = scanOnce(WIFI_BAND_ABG, results, countof(results));
59851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    if (num_results == 0) {
59951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("RTT aborted because of no scan results\n");
60051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        return;
60117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    } else {
60251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("Retrieved %d scan results\n", num_results);
60317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    }
60417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
60551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    num_results = removeDuplicateScanResults(results, num_results);
60651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    /*
60751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    printMsg("Deduped scan results - %d\n", num_results);
60817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    for (int i = 0; i < num_results; i++) {
60917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printScanResult(results[i]);
61017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    }
61151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    */
61251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
61351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    sortScanResultsByRssi(results, num_results);
61451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    printMsg("Sorted scan results -\n");
61551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    for (int i = 0; i < num_results; i++) {
61651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printScanResult(results[i]);
61751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    }
61851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
61951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
62051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    static const int max_ap = 5;
62151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    wifi_rtt_config params[max_ap];
62251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    memset(params, 0, sizeof(params));
62351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
624b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande    printMsg("Configuring RTT for %d APs, num_samples = %d\n",
625b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande            min(num_results, max_ap), rtt_samples);
62651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
62751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    unsigned num_ap = 0;
62851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    for (int i = 0; i < min(num_results, max_ap); i++, num_ap++) {
62951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
63017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        memcpy(params[i].addr, results[i].bssid, sizeof(mac_addr));
63151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        mac_addr &addr = params[i].addr;
63251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("Adding %02x:%02x:%02x:%02x:%02x:%02x (%d) for RTT\n", addr[0],
63351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                addr[1], addr[2], addr[3], addr[4], addr[5], results[i].channel);
63451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
63517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        params[i].type  = RTT_TYPE_1_SIDED;
63617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        params[i].channel.center_freq = results[i].channel;
63717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        params[i].channel.width = WIFI_CHAN_WIDTH_20;
63817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        params[i].peer  = WIFI_PEER_INVALID;
63917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        params[i].continuous = 1;
64017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        params[i].interval = 1000;
64151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        params[i].num_samples_per_measurement = rtt_samples;
64251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        params[i].num_retries_per_measurement = 10;
64317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    }
64417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
64517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    wifi_rtt_event_handler handler;
64617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    handler.on_rtt_results = &onRTTResults;
64717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
64851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    int result = wifi_rtt_range_request(rttCmdId, wlan0Handle, num_ap, params, handler);
64951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
65051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    if (result == WIFI_SUCCESS) {
65151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("Waiting for RTT results\n");
65251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
65351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        while (true) {
65451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            EventInfo info;
65551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            memset(&info, 0, sizeof(info));
65651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            getEventFromCache(info);
65751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande
65851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE) {
65951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                retrieveScanResults();
66051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            } else if (info.type == EVENT_TYPE_RTT_RESULTS) {
66151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                break;
66251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            }
66351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        }
66451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    } else {
66551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("Could not set setRTTAPs : %d\n", result);
66651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    }
66717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat}
66817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
66917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
670ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic wifi_error setHotlistAPsUsingScanResult(wifi_bssid_hotlist_params *params){
671ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("testHotlistAPs Scan started, waiting for event ...\n");
672ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EventInfo info;
673ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&info, 0, sizeof(info));
674ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    getEventFromCache(info);
675ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
676ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_scan_result results[256];
677ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(results, 0, sizeof(wifi_scan_result) * 256);
678ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
679ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Retrieving scan results for Hotlist AP setting\n");
680ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int num_results = 256;
681a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    int result = wifi_get_cached_gscan_results(wlan0Handle, 1, num_results, results, &num_results);
682ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (result < 0) {
683ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("failed to fetch scan results : %d\n", result);
684ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return WIFI_ERROR_UNKNOWN;
685ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
686ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("fetched %d scan results\n", num_results);
687ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
688ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
689ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < num_results; i++) {
690ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printScanResult(results[i]);
691ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
692ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
693ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < stest_max_ap; i++) {
694a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande        memcpy(params->ap[i].bssid, results[i].bssid, sizeof(mac_addr));
695a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande        params->ap[i].low  = -htest_low_threshold;
696a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande        params->ap[i].high = -htest_high_threshold;
697ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
698a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    params->num_ap = stest_max_ap;
699ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    return WIFI_SUCCESS;
700ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
701ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
702ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic wifi_error setHotlistAPs() {
703ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_bssid_hotlist_params params;
704ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&params, 0, sizeof(params));
705ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
706a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    params.lost_ap_sample_size = HOTLIST_LOST_WINDOW;
707ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (num_hotlist_bssids > 0) {
708ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      for (int i = 0; i < num_hotlist_bssids; i++) {
709a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande          memcpy(params.ap[i].bssid, hotlist_bssids[i], sizeof(mac_addr));
710a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande          params.ap[i].low  = -htest_low_threshold;
711a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande          params.ap[i].high = -htest_high_threshold;
712ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      }
713a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande      params.num_ap = num_hotlist_bssids;
714ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
715ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      setHotlistAPsUsingScanResult(&params);
716ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
717ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
718ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("BSSID\t\t\tHIGH\tLOW\n");
719a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    for (int i = 0; i < params.num_ap; i++) {
720a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande        mac_addr &addr = params.ap[i].bssid;
721ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("%02x:%02x:%02x:%02x:%02x:%02x\t%d\t%d\n", addr[0],
722ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                addr[1], addr[2], addr[3], addr[4], addr[5],
723a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande                params.ap[i].high, params.ap[i].low);
724ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
725ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
726ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_hotlist_ap_found_handler handler;
727ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    handler.on_hotlist_ap_found = &onHotlistAPFound;
728a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    handler.on_hotlist_ap_lost = &onHotlistAPLost;
729ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    hotlistCmdId = getNewCmdId();
730ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Setting hotlist APs threshold\n");
731ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    return wifi_set_bssid_hotlist(hotlistCmdId, wlan0Handle, params, handler);
732ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
733ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
734ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void resetHotlistAPs() {
735ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg(", stoping Hotlist AP scanning\n");
736ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_reset_bssid_hotlist(hotlistCmdId, wlan0Handle);
737ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
738ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
739a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwinstatic void setPnoMacOui() {
740a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    wifi_set_scanning_mac_oui(wlan0Handle, mac_oui);
741a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin}
742ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
743ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void testHotlistAPs(){
744ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
745ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EventInfo info;
746ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&info, 0, sizeof(info));
747ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
748ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("starting Hotlist AP scanning\n");
749ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (!startScan(&onScanResultsAvailable, stest_max_ap,stest_base_period, stest_threshold)) {
75051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("testHotlistAPs failed to start scan!!\n");
75151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        return;
752ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
753ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
754ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int result = setHotlistAPs();
755ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (result == WIFI_SUCCESS) {
75651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("Waiting for Hotlist AP event\n");
75751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        while (true) {
75851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            memset(&info, 0, sizeof(info));
75951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            getEventFromCache(info);
76017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
76151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE) {
76251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                retrieveScanResults();
763a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin            } else if (info.type == EVENT_TYPE_HOTLIST_AP_FOUND ||
764a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin                   info.type == EVENT_TYPE_HOTLIST_AP_LOST) {
765a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin                printMsg("Hotlist APs");
76651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                if (--max_event_wait > 0)
76751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                  printMsg(", waiting for more event ::%d\n", max_event_wait);
76851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                else
76951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                  break;
77051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            }
77117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        }
77251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        resetHotlistAPs();
77317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    } else {
77451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("Could not set AP hotlist : %d\n", result);
77517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    }
77617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat}
77717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
778ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void onSignificantWifiChange(wifi_request_id id,
779a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande        unsigned num_results, wifi_significant_change_result **results)
780ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann{
781ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Significant wifi change for %d\n", num_results);
782ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (unsigned i = 0; i < num_results; i++) {
783a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande        printSignificantChangeResult(results[i]);
7847f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
785ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    putEventInCache(EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE, "significant wifi change noticed");
7867f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
7877f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
788ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int SelectSignificantAPsFromScanResults() {
789ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_scan_result results[256];
790ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(results, 0, sizeof(wifi_scan_result) * 256);
791ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Retrieving scan results for significant wifi change setting\n");
792ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int num_results = 256;
793a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    int result = wifi_get_cached_gscan_results(wlan0Handle, 1, num_results, results, &num_results);
794ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (result < 0) {
795ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("failed to fetch scan results : %d\n", result);
796ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return WIFI_ERROR_UNKNOWN;
797ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
798ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("fetched %d scan results\n", num_results);
799ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
800ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
801ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < num_results; i++) {
802ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printScanResult(results[i]);
803ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
804ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
805ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_significant_change_params params;
806ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&params, 0, sizeof(params));
807ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
808ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.rssi_sample_size = swctest_rssi_sample_size;
809ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.lost_ap_sample_size = swctest_rssi_lost_ap;
810ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.min_breaching = swctest_rssi_min_breaching;
811ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
812ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < stest_max_ap; i++) {
813a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande        memcpy(params.ap[i].bssid, results[i].bssid, sizeof(mac_addr));
814a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande        params.ap[i].low  = results[i].rssi - swctest_rssi_ch_threshold;
815a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande        params.ap[i].high = results[i].rssi + swctest_rssi_ch_threshold;
816ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
817a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    params.num_ap = stest_max_ap;
818ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
819ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Settting Significant change params rssi_sample_size#%d lost_ap_sample_size#%d"
820200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        " and min_breaching#%d\n", params.rssi_sample_size,
821200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        params.lost_ap_sample_size , params.min_breaching);
822ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("BSSID\t\t\tHIGH\tLOW\n");
823a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande    for (int i = 0; i < params.num_ap; i++) {
824a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande        mac_addr &addr = params.ap[i].bssid;
825ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("%02x:%02x:%02x:%02x:%02x:%02x\t%d\t%d\n", addr[0],
826ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                addr[1], addr[2], addr[3], addr[4], addr[5],
827a59fae6bd96ead6d3c8772b3cc5e69cd08444400Vinit Deshpande                params.ap[i].high, params.ap[i].low);
828ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
829ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_significant_change_handler handler;
830ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&handler, 0, sizeof(handler));
831ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    handler.on_significant_change = &onSignificantWifiChange;
832ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
833ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int id = getNewCmdId();
834ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    return wifi_set_significant_change_handler(id, wlan0Handle, params, handler);
835ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
836ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
837ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
838ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void untrackSignificantChange() {
839ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg(", Stop tracking SignificantChange\n");
840ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_reset_bssid_hotlist(hotlistCmdId, wlan0Handle);
841ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
842ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
843ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void trackSignificantChange() {
844ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("starting trackSignificantChange\n");
845ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
846ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (!startScan(&onScanResultsAvailable, stest_max_ap,stest_base_period, stest_threshold)) {
847ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("trackSignificantChange failed to start scan!!\n");
848ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return;
849ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
850ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("trackSignificantChange Scan started, waiting for event ...\n");
851ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
852ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
853ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EventInfo info;
854ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&info, 0, sizeof(info));
855ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    getEventFromCache(info);
856ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
857ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int result = SelectSignificantAPsFromScanResults();
85851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    if (result == WIFI_SUCCESS) {
85951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("Waiting for significant wifi change event\n");
86051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        while (true) {
86151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            memset(&info, 0, sizeof(info));
86251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            getEventFromCache(info);
863ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
86451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE) {
86551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                retrieveScanResults();
86651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            } else if(info.type == EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE) {
86751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                printMsg("Received significant wifi change");
86851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                if (--max_event_wait > 0)
86951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    printMsg(", waiting for more event ::%d\n", max_event_wait);
87051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                else
87151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                    break;
87251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            }
87351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        }
87451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        untrackSignificantChange();
87551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    } else {
87651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printMsg("Failed to set significant change  ::%d\n", result);
87751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    }
878ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
879ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
8807f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
8817f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* tests                                        */
8827f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
8837f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
8847f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndevoid testScan() {
885ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printf("starting scan with max_ap_per_scan#%d  base_period#%d  threshold#%d \n",
886ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann           stest_max_ap,stest_base_period, stest_threshold);
887ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (!startScan(&onScanResultsAvailable, stest_max_ap,stest_base_period, stest_threshold)) {
888ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("failed to start scan!!\n");
889ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return;
8907f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    } else {
891ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        EventInfo info;
892ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        memset(&info, 0, sizeof(info));
893ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
894ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        while (true) {
895ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            getEventFromCache(info);
896ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            printMsg("retrieved event %d : %s\n", info.type, info.buf);
897ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            retrieveScanResults();
898ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            if(--max_event_wait > 0)
899ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann              printMsg("Waiting for more :: %d event \n", max_event_wait);
900ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            else
901ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann              break;
902ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        }
903ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
9047f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        stopScan();
905ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("stopped scan\n");
9067f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
9077f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
9087f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
909ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid testStopScan() {
910ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    stopScan();
911ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("stopped scan\n");
912ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
913ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
914ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannbyte parseHexChar(char ch) {
915ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (isdigit(ch))
916ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return ch - '0';
917ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    else if ('A' <= ch && ch <= 'F')
918ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return ch - 'A' + 10;
919ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    else if ('a' <= ch && ch <= 'f')
920ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return ch - 'a' + 10;
921ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    else {
922a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        printMsg("invalid character in bssid %c\n", ch);
923ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return 0;
924ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
925ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
926ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
927ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannbyte parseHexByte(char ch1, char ch2) {
928ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    return (parseHexChar(ch1) << 4) | parseHexChar(ch2);
929ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
930ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
93151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpandevoid parseMacAddress(const char *str, mac_addr addr) {
932ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[0] = parseHexByte(str[0], str[1]);
933ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[1] = parseHexByte(str[3], str[4]);
934ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[2] = parseHexByte(str[6], str[7]);
935ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[3] = parseHexByte(str[9], str[10]);
936ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[4] = parseHexByte(str[12], str[13]);
937ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[5] = parseHexByte(str[15], str[16]);
93851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    // printMsg("read mac addr: %02x:%02x:%02x:%02x:%02x:%02x\n", addr[0],
93951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    //      addr[1], addr[2], addr[3], addr[4], addr[5]);
940ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
941ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
942a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwinvoid parseMacOUI(char *str, unsigned char *addr) {
943a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    addr[0] = parseHexByte(str[0], str[1]);
944a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    addr[1] = parseHexByte(str[3], str[4]);
945a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    addr[2] = parseHexByte(str[6], str[7]);
946a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    printMsg("read mac OUI: %02x:%02x:%02x\n", addr[0],
947a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin            addr[1], addr[2]);
948a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin}
949a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin
950ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid readTestOptions(int argc, char *argv[]){
951ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
95251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    printf("Total number of argc #%d\n", argc);
95351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    for (int j = 1; j < argc-1; j++) {
95451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        if (strcmp(argv[j], "-max_ap") == 0 && isdigit(argv[j+1][0])) {
95551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            stest_max_ap = atoi(argv[++j]);
95651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" max_ap #%d\n", stest_max_ap);
95751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-base_period") == 0 && isdigit(argv[j+1][0])) {
95851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            stest_base_period = atoi(argv[++j]);
95951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" base_period #%d\n", stest_base_period);
96051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-threshold") == 0 && isdigit(argv[j+1][0])) {
96151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            stest_threshold = atoi(argv[++j]);
96251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" threshold #%d\n", stest_threshold);
96351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-avg_RSSI") == 0 && isdigit(argv[j+1][0])) {
96451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            swctest_rssi_sample_size = atoi(argv[++j]);
96551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" avg_RSSI #%d\n", swctest_rssi_sample_size);
96651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-ap_loss") == 0 && isdigit(argv[j+1][0])) {
96751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            swctest_rssi_lost_ap = atoi(argv[++j]);
96851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" ap_loss #%d\n", swctest_rssi_lost_ap);
96951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-ap_breach") == 0 && isdigit(argv[j+1][0])) {
97051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            swctest_rssi_min_breaching = atoi(argv[++j]);
97151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" ap_breach #%d\n", swctest_rssi_min_breaching);
97251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-ch_threshold") == 0 && isdigit(argv[j+1][0])) {
97351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            swctest_rssi_ch_threshold = atoi(argv[++j]);
97451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" ch_threshold #%d\n", swctest_rssi_ch_threshold);
97551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-wt_event") == 0 && isdigit(argv[j+1][0])) {
97651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            max_event_wait = atoi(argv[++j]);
97751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" wt_event #%d\n", max_event_wait);
97851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-low_th") == 0 && isdigit(argv[j+1][0])) {
97951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            htest_low_threshold = atoi(argv[++j]);
98051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" low_threshold #-%d\n", htest_low_threshold);
98151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-high_th") == 0 && isdigit(argv[j+1][0])) {
98251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            htest_high_threshold = atoi(argv[++j]);
98351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" high_threshold #-%d\n", htest_high_threshold);
98451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-hotlist_bssids") == 0 && isxdigit(argv[j+1][0])) {
98551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            j++;
986200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle            for (num_hotlist_bssids = 0;
987200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                        j < argc && isxdigit(argv[j][0]);
988200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle                        j++, num_hotlist_bssids++) {
98951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                parseMacAddress(argv[j], hotlist_bssids[num_hotlist_bssids]);
99051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            }
99151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            j -= 1;
99251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if (strcmp(argv[j], "-channel_list") == 0 && isxdigit(argv[j+1][0])) {
99351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            j++;
99451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            for (num_channels = 0; j < argc && isxdigit(argv[j][0]); j++, num_channels++) {
99551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                channel_list[num_channels] = atoi(argv[j]);
99651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            }
99751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            j -= 1;
99851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if ((strcmp(argv[j], "-get_ch_list") == 0)) {
99951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            if(strcmp(argv[j + 1], "a") == 0) {
100051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                band = WIFI_BAND_A_WITH_DFS;
100151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            } else if(strcmp(argv[j + 1], "bg") == 0) {
100251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                band = WIFI_BAND_BG;
100351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            } else if(strcmp(argv[j + 1], "abg") == 0) {
100451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                band = WIFI_BAND_ABG_WITH_DFS;
100551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            } else if(strcmp(argv[j + 1], "a_nodfs") == 0) {
100651da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                band = WIFI_BAND_A;
100751da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            } else if(strcmp(argv[j + 1], "dfs") == 0) {
100851da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                band = WIFI_BAND_A_DFS;
100951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            } else if(strcmp(argv[j + 1], "abg_nodfs") == 0) {
101051da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande                band = WIFI_BAND_ABG;
101151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            }
101251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            j++;
101351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        } else if ((strcmp(argv[j], "-rtt_samples") == 0)) {
101451da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            rtt_samples = atoi(argv[++j]);
101551da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande            printf(" rtt_retries #-%d\n", rtt_samples);
1016a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        } else if (strcmp(argv[j], "-scan_mac_oui") == 0 && isxdigit(argv[j+1][0])) {
1017a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin            parseMacOUI(argv[++j], mac_oui);
1018a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin     }
101951da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande    }
1020ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
1021ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
10229427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ngwifi_iface_stat link_stat;
1023200e8ee5097134010a6edee8d031bb02ff7eeb5avandwallewifi_radio_stat trx_stat;
1024200e8ee5097134010a6edee8d031bb02ff7eeb5avandwallewifi_peer_info peer_info;
1025200e8ee5097134010a6edee8d031bb02ff7eeb5avandwallewifi_rate_stat rate_stat[32];
10269427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ngvoid onLinkStatsResults(wifi_request_id id, wifi_iface_stat *iface_stat,
10279427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng         int num_radios, wifi_radio_stat *radio_stat)
10289427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng{
1029200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    int num_peer = iface_stat->num_peers;
1030200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    memcpy(&trx_stat, radio_stat, sizeof(wifi_radio_stat));
10319427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    memcpy(&link_stat, iface_stat, sizeof(wifi_iface_stat));
1032200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    memcpy(&peer_info, iface_stat->peer_info, num_peer*sizeof(wifi_peer_info));
1033200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    int num_rate = peer_info.num_rate;
1034200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    memcpy(&rate_stat, iface_stat->peer_info->rate_stats, num_rate*sizeof(wifi_rate_stat));
10359427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng}
10369427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng
103717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhatvoid printFeatureListBitMask(void)
103817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat{
103917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_INFRA              0x0001      - Basic infrastructure mode\n");
104017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_INFRA_5G           0x0002      - Support for 5 GHz Band\n");
104117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_HOTSPOT            0x0004      - Support for GAS/ANQP\n");
104217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_P2P                0x0008      - Wifi-Direct\n");
104317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_SOFT_AP            0x0010      - Soft AP\n");
104417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_GSCAN              0x0020      - Google-Scan APIs\n");
104517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_NAN                0x0040      - Neighbor Awareness Networking\n");
104617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_D2D_RTT            0x0080      - Device-to-device RTT\n");
104717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_D2AP_RTT           0x0100      - Device-to-AP RTT\n");
104817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_BATCH_SCAN         0x0200      - Batched Scan (legacy)\n");
104917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_PNO                0x0400      - Preferred network offload\n");
105017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_ADDITIONAL_STA     0x0800      - Support for two STAs\n");
105117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_TDLS               0x1000      - Tunnel directed link setup\n");
105217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_TDLS_OFFCHANNEL    0x2000      - Support for TDLS off channel\n");
105317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_EPR                0x4000      - Enhanced power reporting\n");
105417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("WIFI_FEATURE_AP_STA             0x8000      - Support for AP STA Concurrency\n");
105517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat}
1056200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle
1057200e8ee5097134010a6edee8d031bb02ff7eeb5avandwallechar *rates[] = {
1058200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    "1Mbps",
1059200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    "2Mbps",
1060200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"5.5Mbps",
1061200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"6Mbps",
1062200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"9Mbps",
1063200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"11Mbps",
1064200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"12Mbps",
1065200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"18Mbps",
1066200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"24Mbps",
1067200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"36Mbps",
1068200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"48Mbps",
1069200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"54Mbps",
1070200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS0 ss1",
1071200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS1 ss1",
1072200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS2 ss1",
1073200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS3 ss1",
1074200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS4 ss1",
1075200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS5 ss1",
1076200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS6 ss1",
1077200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS7 ss1",
1078200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    "VHT MCS8 ss1",
1079200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS9 ss1",
1080200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS0 ss2",
1081200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS1 ss2",
1082200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS2 ss2",
1083200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS3 ss2",
1084200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS4 ss2",
1085200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS5 ss2",
1086200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS6 ss2",
1087200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS7 ss2",
1088200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS8 ss2",
1089200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	"VHT MCS9 ss2"
1090200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	};
1091200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle
1092200e8ee5097134010a6edee8d031bb02ff7eeb5avandwallevoid printLinkStats(wifi_iface_stat link_stat, wifi_radio_stat trx_stat)
10939427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng{
1094200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("Printing link layer statistics:\n");
1095200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("-------------------------------\n");
10969427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("beacon_rx = %d\n", link_stat.beacon_rx);
1097200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("RSSI = %d\n", link_stat.rssi_mgmt);
10989427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("AC_BE:\n");
10999427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("txmpdu = %d\n", link_stat.ac[WIFI_AC_BE].tx_mpdu);
11009427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("rxmpdu = %d\n", link_stat.ac[WIFI_AC_BE].rx_mpdu);
11019427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("mpdu_lost = %d\n", link_stat.ac[WIFI_AC_BE].mpdu_lost);
11029427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("retries = %d\n", link_stat.ac[WIFI_AC_BE].retries);
11039427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("AC_BK:\n");
11049427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("txmpdu = %d\n", link_stat.ac[WIFI_AC_BK].tx_mpdu);
11059427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("rxmpdu = %d\n", link_stat.ac[WIFI_AC_BK].rx_mpdu);
11069427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("mpdu_lost = %d\n", link_stat.ac[WIFI_AC_BK].mpdu_lost);
11079427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("AC_VI:\n");
11089427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("txmpdu = %d\n", link_stat.ac[WIFI_AC_VI].tx_mpdu);
11099427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("rxmpdu = %d\n", link_stat.ac[WIFI_AC_VI].rx_mpdu);
11109427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("mpdu_lost = %d\n", link_stat.ac[WIFI_AC_VI].mpdu_lost);
11119427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("AC_VO:\n");
11129427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("txmpdu = %d\n", link_stat.ac[WIFI_AC_VO].tx_mpdu);
11139427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("rxmpdu = %d\n", link_stat.ac[WIFI_AC_VO].rx_mpdu);
11149427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    printMsg("mpdu_lost = %d\n", link_stat.ac[WIFI_AC_VO].mpdu_lost);
1115200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("\n");
1116200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("Printing radio statistics:\n");
1117200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("--------------------------\n");
1118200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("on time = %d\n", trx_stat.on_time);
1119200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("tx time = %d\n", trx_stat.tx_time);
1120200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("rx time = %d\n", trx_stat.rx_time);
1121200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("\n");
1122200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("Printing rate statistics:\n");
1123200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("-------------------------\n");
1124200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    printMsg("%27s %12s %14s %15s\n", "TX",  "RX", "LOST", "RETRIES");
1125200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    for (int i=0; i < 32; i++) {
1126200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        printMsg("%-15s  %10d   %10d    %10d    %10d\n",
1127200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	    rates[i], rate_stat[i].tx_mpdu, rate_stat[i].rx_mpdu,
1128200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle	    rate_stat[i].mpdu_lost, rate_stat[i].retries);
1129200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle    }
11309427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng}
11319427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng
11329427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ngvoid getLinkStats(void)
11339427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng{
11349427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    wifi_stats_result_handler handler;
11359427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    memset(&handler, 0, sizeof(handler));
11369427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    handler.on_link_stats_results = &onLinkStatsResults;
11379427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng
11389427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    int result = wifi_get_link_stats(0, wlan0Handle, handler);
11399427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    if (result < 0) {
11409427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng        printMsg("failed to get link statistics - %d\n", result);
11419427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    } else {
1142200e8ee5097134010a6edee8d031bb02ff7eeb5avandwalle        printLinkStats(link_stat, trx_stat);
11439427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    }
11449427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng}
11459427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng
114617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhatvoid getChannelList(void)
114717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat{
114817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    wifi_channel channel[MAX_CH_BUF_SIZE];
114917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    int num_channels = 0, i;
115017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
115117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    int result = wifi_get_valid_channels(wlan0Handle, band, MAX_CH_BUF_SIZE,
115217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat                     channel, &num_channels);
115317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("Number of channels - %d\nChannel List:\n",num_channels);
115417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    for (i = 0; i < num_channels; i++) {
115517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printMsg("%d MHz\n", channel[i]);
115617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    }
115717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat}
115817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
115917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhatvoid getFeatureSet(void)
116017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat{
116117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    feature_set set;
116217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    int result = wifi_get_supported_feature_set(wlan0Handle, &set);
116317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
116417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    if (result < 0) {
116517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printMsg("Error %d\n",result);
116617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        return;
116717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    }
116817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printFeatureListBitMask();
116917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printMsg("Supported feature set bit mask - %x\n", set);
117017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    return;
117117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat}
117217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
117317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhatvoid getFeatureSetMatrix(void)
117417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat{
117517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    feature_set set[MAX_FEATURE_SET];
117617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    int size;
117717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
117817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    int result = wifi_get_concurrency_matrix(wlan0Handle, MAX_FEATURE_SET, set, &size);
117917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
118017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    if (result < 0) {
118117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printMsg("Error %d\n",result);
118217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        return;
118317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    }
118417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    printFeatureListBitMask();
118517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    for (int i = 0; i < size; i++)
118617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printMsg("Concurrent feature set - %x\n", set[i]);
118717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    return;
118817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat}
118917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
119017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
119117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat
11927f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndeint main(int argc, char *argv[]) {
11937f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1194ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_init(&printMutex, NULL);
1195ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
11967f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    if (init() != 0) {
1197ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("could not initiate HAL");
11987f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        return -1;
11997f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    } else {
1200ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("successfully initialized HAL; wlan0 = %p\n", wlan0Handle);
12017f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
12027f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1203ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_cond_init(&eventCacheCondition, NULL);
1204ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_init(&eventCacheMutex, NULL);
1205ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
1206ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_t tidEvent;
1207ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_create(&tidEvent, NULL, &eventThreadFunc, NULL);
12087f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
12097f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    sleep(2);     // let the thread start
12107f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1211ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (argc < 2 || argv[1][0] != '-') {
1212ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf("Usage:  halutil [OPTION]\n");
1213ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -s               start AP scan test\n");
1214ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -swc             start Significant Wifi change test\n");
1215ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -h               start Hotlist APs scan test\n");
1216ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -ss              stop scan test\n");
1217ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -max_ap          Max AP for scan \n");
1218ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -base_period     Base period for scan \n");
1219ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -threshold       Threshold scan test\n");
1220ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -avg_RSSI        samples for averaging RSSI\n");
1221ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -ap_loss         samples to confirm AP loss\n");
1222ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -ap_breach       APs breaching threshold\n");
1223ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -ch_threshold    Change in threshold\n");
1224ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -wt_event        Waiting event for test\n");
1225ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -low_th          Low threshold for hotlist APs\n");
1226ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -hight_th        High threshold for hotlist APs\n");
1227ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -hotlist_bssids  BSSIDs for hotlist test\n");
122817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printf(" -stats       print link layer statistics\n");
122917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printf(" -get_ch_list <a/bg/abg/a_nodfs/abg_nodfs/dfs>  Get channel list\n");
123017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printf(" -get_feature_set  Get Feature set\n");
123117bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        printf(" -get_feature_matrix  Get concurrent feature matrix\n");
123251da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printf(" -rtt             Run RTT on nearby APs\n");
123351da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        printf(" -rtt_samples     Run RTT on nearby APs\n");
1234a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        printf(" -scan_mac_oui XY:AB:CD\n");
1235a0177b901f9229e4f32d2758b4b7ee39dd90f159Dmitry Shmidt        printf(" -nodfs <0|1>     Turn OFF/ON non-DFS locales\n");
1236ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        goto cleanup;
1237ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
1238a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    memset(mac_oui, 0, 3);
12397f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1240ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (strcmp(argv[1], "-s") == 0) {
1241ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        readTestOptions(argc, argv);
1242a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        setPnoMacOui();
1243ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        testScan();
1244ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else if(strcmp(argv[1], "-swc") == 0){
1245ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        readTestOptions(argc, argv);
1246a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        setPnoMacOui();
1247ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        trackSignificantChange();
1248ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else if (strcmp(argv[1], "-ss") == 0) {
1249a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        // Stop scan so clear the OUI too
1250a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        setPnoMacOui();
1251ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        testStopScan();
125217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    }else if ((strcmp(argv[1], "-h") == 0)  ||
125317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat              (strcmp(argv[1], "-hotlist_bssids") == 0)) {
1254ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        readTestOptions(argc, argv);
1255a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        setPnoMacOui();
1256ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        testHotlistAPs();
12579427264abccbd59b8fd64132f7d2a3895a8d4398Chilam Ng    }else if (strcmp(argv[1], "-stats") == 0) {
125817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        getLinkStats();
125917bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    } else if ((strcmp(argv[1], "-rtt") == 0)) {
126017bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        readTestOptions(argc, argv);
126151da80208c650a8271a18b0ca8681279ba060e1fVinit Deshpande        testRTT();
126217bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    } else if ((strcmp(argv[1], "-get_ch_list") == 0)) {
126317bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        readTestOptions(argc, argv);
126417bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        getChannelList();
126517bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    } else if ((strcmp(argv[1], "-get_feature_set") == 0)) {
126617bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        getFeatureSet();
126717bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat    } else if ((strcmp(argv[1], "-get_feature_matrix") == 0)) {
126817bc83f7111e1af5fe8af048cc996b2e7e037d15Ashwin Bhat        getFeatureSetMatrix();
1269a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin    } else if ((strcmp(argv[1], "-scan_mac_oui") == 0)) {
1270a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        readTestOptions(argc, argv);
1271a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        setPnoMacOui();
1272a3334ddcfda7eea94e82ad0725dcf4b887c148acAshwin        testScan();
1273a0177b901f9229e4f32d2758b4b7ee39dd90f159Dmitry Shmidt    } else if (strcmp(argv[1], "-nodfs") == 0) {
1274a0177b901f9229e4f32d2758b4b7ee39dd90f159Dmitry Shmidt        u32 nodfs = 0;
1275a0177b901f9229e4f32d2758b4b7ee39dd90f159Dmitry Shmidt        if (argc > 2)
1276a0177b901f9229e4f32d2758b4b7ee39dd90f159Dmitry Shmidt            nodfs = (u32)atoi(argv[2]);
1277a0177b901f9229e4f32d2758b4b7ee39dd90f159Dmitry Shmidt        wifi_set_nodfs_flag(wlan0Handle, nodfs);
12787f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
12797f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndecleanup:
12807f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    cleanup();
12817f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    return 0;
12827f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1283