halutil.cpp revision ff658ac8e6c092521e11e3c58764c77be2de2ffa
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
27a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
287f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde#define EVENT_BUF_SIZE 2048
297f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
307f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic wifi_handle halHandle;
317f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic wifi_interface_handle *ifaceHandles;
32a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapndestatic wifi_interface_handle wlan0Handle;
33a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapndestatic wifi_interface_handle p2p0Handle;
347f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int numIfaceHandles;
357f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int cmdId = 0;
36a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapndestatic int ioctl_sock = 0;
37ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int max_event_wait = 5;
38ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int stest_max_ap = 10;
39ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int stest_base_period = 1000;
40ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int stest_threshold = 80;
41ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int swctest_rssi_sample_size =  3;
42ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int swctest_rssi_lost_ap =  3;
43ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int swctest_rssi_min_breaching =  2;
44ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int swctest_rssi_ch_threshold =  1;
45ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int htest_low_threshold =  90;
46ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int htest_high_threshold =  10;
47ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
48ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannmac_addr hotlist_bssids[16];
49ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannint num_hotlist_bssids = 0;
50a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
51a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapndeint linux_set_iface_flags(int sock, const char *ifname, int dev_up)
52a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde{
53ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    struct ifreq ifr;
54ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int ret;
55a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
56ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("setting interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
57a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
58ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (sock < 0) {
59ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Bad socket: %d\n", sock);
60ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      return -1;
61ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
62a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
63ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&ifr, 0, sizeof(ifr));
64ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
65a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
66ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("reading old value\n");
67a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
68ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
69ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      ret = errno ? -errno : -999;
70ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Could not read interface %s flags: %d\n", ifname, errno);
71ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      return ret;
72ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else {
73ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("writing new value\n");
74ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
75a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
76ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (dev_up) {
77ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      if (ifr.ifr_flags & IFF_UP) {
78ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("interface %s is already up\n", ifname);
79ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return 0;
80ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      }
81ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      ifr.ifr_flags |= IFF_UP;
82ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else {
83ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      if (!(ifr.ifr_flags & IFF_UP)) {
84ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("interface %s is already down\n", ifname);
85ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return 0;
86ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      }
87ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      ifr.ifr_flags &= ~IFF_UP;
88ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
89a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
90ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
91ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Could not set interface %s flags \n", ifname);
92ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      return ret;
93ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else {
94ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("set interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
95ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
96ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Done\n");
97ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    return 0;
98a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde}
99a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
1007f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1017f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int init() {
102a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
103a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
104a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    if (ioctl_sock < 0) {
105ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Bad socket: %d\n", ioctl_sock);
106ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      return errno;
107a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    } else {
108ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Good socket: %d\n", ioctl_sock);
109a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    }
110a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
111a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    int ret = linux_set_iface_flags(ioctl_sock, "wlan0", 1);
112a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    if (ret < 0) {
113a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde        return ret;
114a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    }
115a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde
1167f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    wifi_error res = wifi_initialize(&halHandle);
1177f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    if (res < 0) {
1187f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        return res;
1197f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
1207f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1217f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    res = wifi_get_ifaces(halHandle, &numIfaceHandles, &ifaceHandles);
1227f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    if (res < 0) {
1237f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        return res;
1247f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
1257f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1267f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    char buf[EVENT_BUF_SIZE];
1277f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    for (int i = 0; i < numIfaceHandles; i++) {
1287f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
129a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde            if (strcmp(buf, "wlan0") == 0) {
130ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                printMsg("found interface %s\n", buf);
131a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde                wlan0Handle = ifaceHandles[i];
132a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde            } else if (strcmp(buf, "p2p0") == 0) {
133ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                printMsg("found interface %s\n", buf);
134a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde                p2p0Handle = ifaceHandles[i];
135a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde            }
1367f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        }
1377f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
1387f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1397f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    return res;
1407f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1417f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1427f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic void cleaned_up_handler(wifi_handle handle) {
143ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("HAL cleaned up handler\n");
1447f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    halHandle = NULL;
1457f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    ifaceHandles = NULL;
1467f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1477f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1487f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic void cleanup() {
149ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("cleaning up HAL\n");
1507f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    wifi_cleanup(halHandle, cleaned_up_handler);
1517f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1527f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1537f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic void *eventThreadFunc(void *context) {
1547f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
155ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("starting wifi event loop\n");
1567f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    wifi_event_loop(halHandle);
157ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("out of wifi event loop\n");
1587f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1597f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    return NULL;
1607f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1617f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1627f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1637f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int getNewCmdId() {
1647f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    return cmdId++;
1657f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1667f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1677f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
1687f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* helpers                                      */
1697f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
1707f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
171ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid printScanHeader() {
172ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("SSID\t\t\t\t\tBSSID\t\t  RSSI\tchannel\ttimestamp\tRTT\tRTT SD\n");
173ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
174ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
1757f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndevoid printScanResult(wifi_scan_result result) {
1767f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
177ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%-32s\t", result.ssid);
1787f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
179ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%02x:%02x:%02x:%02x:%02x:%02x ", result.bssid[0], result.bssid[1],
1807f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde            result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]);
1817f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
182ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%d\t", result.rssi);
183ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%d\t", result.channel);
184ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%lld\t", result.ts);
185ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%lld\t", result.rtt);
186ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("%lld\n", result.rtt_sd);
1877f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
1887f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
18999d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapndevoid printScanCapabilities(wifi_gscan_capabilities capabilities)
19099d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde{
191ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_scan_cache_size = %d\n", capabilities.max_scan_cache_size);
192ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_scan_buckets = %d\n", capabilities.max_scan_buckets);
193ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_ap_cache_per_scan = %d\n", capabilities.max_ap_cache_per_scan);
194ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_rssi_sample_size = %d\n", capabilities.max_rssi_sample_size);
195ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_scan_reporting_threshold = %d\n", capabilities.max_scan_reporting_threshold);
196ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_hotlist_aps = %d\n", capabilities.max_hotlist_aps);
197ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("max_significant_wifi_change_aps = %d\n", capabilities.max_significant_wifi_change_aps);
19899d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde}
19999d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde
2007f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
2017f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
2027f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* commands and events                          */
2037f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
2047f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
205ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Manntypedef enum {
206ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EVENT_TYPE_SCAN_RESULTS_AVAILABLE = 1000,
207ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EVENT_TYPE_HOTLIST_AP_FOUND = 1001,
208ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE = 1002
209ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann} EventType;
210ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
211ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Manntypedef struct {
212ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int type;
213ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    char buf[256];
214ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann} EventInfo;
215ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
216ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannconst int MAX_EVENTS_IN_CACHE = 256;
217ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh MannEventInfo eventCache[256];
218ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannint eventsInCache = 0;
219ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannpthread_cond_t eventCacheCondition;
220ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannpthread_mutex_t eventCacheMutex;
221ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
222ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid putEventInCache(int type, const char *msg) {
223ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_lock(&eventCacheMutex);
224ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (eventsInCache + 1 < MAX_EVENTS_IN_CACHE) {
225ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        eventCache[eventsInCache].type = type;
226ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        strcpy(eventCache[eventsInCache].buf, msg);
227ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        eventsInCache++;
228ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        pthread_cond_signal(&eventCacheCondition);
229ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        //printf("put new event in cache; size = %d\n", eventsInCache);
230ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
231ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf("Too many events in the cache\n");
232ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
233ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_unlock(&eventCacheMutex);
234ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
2357f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
236ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid getEventFromCache(EventInfo& info) {
237ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_lock(&eventCacheMutex);
238ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    while (true) {
239ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        if (eventsInCache > 0) {
240ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            //printf("found an event in cache; size = %d\n", eventsInCache);
241ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            info.type = eventCache[0].type;
242ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            strcpy(info.buf, eventCache[0].buf);
243ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            eventsInCache--;
244ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            memmove(&eventCache[0], &eventCache[1], sizeof(EventInfo) * eventsInCache);
245ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            pthread_mutex_unlock(&eventCacheMutex);
246ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            return;
247ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        } else {
248ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            pthread_cond_wait(&eventCacheCondition, &eventCacheMutex);
249ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            //printf("pthread_cond_wait unblocked ...\n");
250ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        }
251ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
252ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
2537f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
254ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannint numScanResultsAvailable = 0;
255ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void onScanResultsAvailable(wifi_request_id id, unsigned num_results) {
256ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Received scan results available event\n");
257ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    numScanResultsAvailable = num_results;
258ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    putEventInCache(EVENT_TYPE_SCAN_RESULTS_AVAILABLE, "New scan results are available");
2597f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
2607f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
2617f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic int scanCmdId;
262ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int hotlistCmdId;
263ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int significantChangeCmdId;
2647f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
265ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic bool startScan( void (*pfnOnResultsAvailable)(wifi_request_id, unsigned),
266ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                       int max_ap_per_scan, int base_period, int report_threshold) {
2677f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
26899d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    /* Get capabilties */
26999d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    wifi_gscan_capabilities capabilities;
27099d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    int result = wifi_get_gscan_capabilities(wlan0Handle, &capabilities);
27199d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    if (result < 0) {
272ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("failed to get scan capabilities - %d\n", result);
273ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("trying scan anyway ..\n");
27499d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    } else {
27599d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde        printScanCapabilities(capabilities);
27699d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde    }
27799d5547cc6c8e4e577020098da3b7cb3aa1f8408Vinit Deshapnde
2787f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    wifi_scan_cmd_params params;
2797f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    memset(&params, 0, sizeof(params));
2807f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
281ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    /* create a schedule to scan channels 1, 6, 11 every 5 second and
282ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     * scan 36, 40, 44, 149, 153, 157, 161 165 every 10 second */
283ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
284ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.max_ap_per_scan = max_ap_per_scan;
285ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.base_period = base_period;                      // 5 second
286ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.report_threshold = report_threshold;
287ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.num_buckets = 2;
288ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
289ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[0].bucket = 0;
290ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[0].band = WIFI_BAND_UNSPECIFIED;
291ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[0].period = 5000;                // 5 second
292ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[0].num_channels = 3;
293ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
294ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[0].channels[0].channel = 2412;
295ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[0].channels[1].channel = 2437;
296ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[0].channels[2].channel = 2462;
297ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
298ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].bucket = 1;
299ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].band = WIFI_BAND_UNSPECIFIED;
300ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].period = 10000;               // 10 second
301ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].num_channels = 8;
302ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
303ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].channels[0].channel = 5180;
304ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].channels[1].channel = 5200;
305ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].channels[2].channel = 5220;
306ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].channels[3].channel = 5745;
307ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].channels[4].channel = 5765;
308ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].channels[5].channel = 5785;
309ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].channels[6].channel = 5805;
310ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.buckets[1].channels[7].channel = 5825;
311ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
3127f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    wifi_scan_result_handler handler;
3137f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    memset(&handler, 0, sizeof(handler));
314ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    handler.on_scan_results_available = pfnOnResultsAvailable;
3157f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
3167f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    scanCmdId = getNewCmdId();
317ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Starting scan --->\n");
318a53b553e481f71ec7bddda6daf03beeb7ebcd932Vinit Deshapnde    return wifi_start_gscan(scanCmdId, wlan0Handle, params, handler) == WIFI_SUCCESS;
3197f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
3207f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
3217f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndestatic void stopScan() {
3227f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    if (scanCmdId != 0) {
323ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        wifi_stop_gscan(scanCmdId, wlan0Handle);
3247f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        scanCmdId = 0;
325ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
326ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        wifi_scan_cmd_params params;
327ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        memset(&params, 0, sizeof(params));
328ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        /* create a schedule to scan channels 1, 6, 11 every 5 second */
329ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
330ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.max_ap_per_scan = 10;
331ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.base_period = 5000;                      // 5 second
332ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.report_threshold = 80;
333ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.num_buckets = 1;
334ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
335ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.buckets[0].bucket = 0;
336ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.buckets[0].band = WIFI_BAND_UNSPECIFIED;
337ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.buckets[0].period = 5000;                // 5 second
338ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.buckets[0].num_channels = 3;
339ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
340ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.buckets[0].channels[0].channel = 2412;
341ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.buckets[0].channels[1].channel = 2437;
342ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.buckets[0].channels[2].channel = 2462;
343ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
344ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        wifi_scan_result_handler handler;
345ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        memset(&handler, 0, sizeof(handler));
346ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        handler.on_scan_results_available = &onScanResultsAvailable;
347ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
348ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        scanCmdId = getNewCmdId();
349ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        if (wifi_start_gscan(scanCmdId, wlan0Handle, params, handler) == WIFI_SUCCESS) {
350ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            wifi_stop_gscan(scanCmdId, wlan0Handle);
351ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        }
352ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
353ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
354ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
355ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void retrieveScanResults() {
356ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
357ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_scan_result results[256];
358ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(results, 0, sizeof(wifi_scan_result) * 256);
359ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Retrieve Scan results available -->\n");
360ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int num_results = 256;
361ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int result = wifi_get_cached_gscan_results(wlan0Handle, 1, results, &num_results);
362ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (result < 0) {
363ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("failed to fetch scan results : %d\n", result);
364ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return;
365ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
366ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("fetched %d scan results\n", num_results);
367ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
368ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
369ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printScanHeader();
370ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < num_results; i++) {
371ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printScanResult(results[i]);
372ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
373ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
374ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
375ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void onHotlistAPFound(wifi_request_id id, unsigned num_results, wifi_scan_result *results) {
376ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
377ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Found hotlist APs\n");
378ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (unsigned i = 0; i < num_results; i++) {
379ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printScanResult(results[i]);
380ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
381ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    putEventInCache(EVENT_TYPE_HOTLIST_AP_FOUND, "Found a hotlist AP");
382ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
383ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
384ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic wifi_error setHotlistAPsUsingScanResult(wifi_bssid_hotlist_params *params){
385ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("testHotlistAPs Scan started, waiting for event ...\n");
386ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EventInfo info;
387ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&info, 0, sizeof(info));
388ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    getEventFromCache(info);
389ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
390ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_scan_result results[256];
391ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(results, 0, sizeof(wifi_scan_result) * 256);
392ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
393ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Retrieving scan results for Hotlist AP setting\n");
394ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int num_results = 256;
395ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int result = wifi_get_cached_gscan_results(wlan0Handle, 1, results, &num_results);
396ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (result < 0) {
397ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("failed to fetch scan results : %d\n", result);
398ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return WIFI_ERROR_UNKNOWN;
399ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
400ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("fetched %d scan results\n", num_results);
401ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
402ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
403ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < num_results; i++) {
404ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printScanResult(results[i]);
405ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
406ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
407ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < stest_max_ap; i++) {
408ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        memcpy(params->bssids[i].bssid, results[i].bssid, sizeof(mac_addr));
409ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params->bssids[i].low  = -htest_low_threshold;
410ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params->bssids[i].high = -htest_high_threshold;
411ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
412ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params->num = stest_max_ap;
413ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    return WIFI_SUCCESS;
414ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
415ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
416ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic wifi_error setHotlistAPs() {
417ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_bssid_hotlist_params params;
418ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&params, 0, sizeof(params));
419ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
420ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (num_hotlist_bssids > 0) {
421ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      for (int i = 0; i < num_hotlist_bssids; i++) {
422ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann          memcpy(params.bssids[i].bssid, hotlist_bssids[i], sizeof(mac_addr));
423ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann          params.bssids[i].low  = -htest_low_threshold;
424ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann          params.bssids[i].high = -htest_high_threshold;
425ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      }
426ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      params.num = num_hotlist_bssids;
427ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
428ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      setHotlistAPsUsingScanResult(&params);
429ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
430ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
431ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("BSSID\t\t\tHIGH\tLOW\n");
432ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < params.num; i++) {
433ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        mac_addr &addr = params.bssids[i].bssid;
434ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("%02x:%02x:%02x:%02x:%02x:%02x\t%d\t%d\n", addr[0],
435ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                addr[1], addr[2], addr[3], addr[4], addr[5],
436ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                params.bssids[i].high, params.bssids[i].low);
437ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
438ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
439ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_hotlist_ap_found_handler handler;
440ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    handler.on_hotlist_ap_found = &onHotlistAPFound;
441ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
442ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    hotlistCmdId = getNewCmdId();
443ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Setting hotlist APs threshold\n");
444ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    return wifi_set_bssid_hotlist(hotlistCmdId, wlan0Handle, params, handler);
445ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
446ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
447ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void resetHotlistAPs() {
448ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg(", stoping Hotlist AP scanning\n");
449ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_reset_bssid_hotlist(hotlistCmdId, wlan0Handle);
450ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
451ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
452ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
453ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void testHotlistAPs(){
454ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
455ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EventInfo info;
456ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&info, 0, sizeof(info));
457ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
458ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("starting Hotlist AP scanning\n");
459ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (!startScan(&onScanResultsAvailable, stest_max_ap,stest_base_period, stest_threshold)) {
460ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("testHotlistAPs failed to start scan!!\n");
461ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      return;
462ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
463ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
464ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int result = setHotlistAPs();
465ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (result == WIFI_SUCCESS) {
466ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Waiting for Hotlist AP event\n");
467ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      while (true) {
468ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        memset(&info, 0, sizeof(info));
469ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        getEventFromCache(info);
470ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
471ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE) {
472ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            retrieveScanResults();
473ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        } else if (info.type == EVENT_TYPE_HOTLIST_AP_FOUND) {
474ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            printMsg("Found Hotlist APs");
475ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            if (--max_event_wait > 0)
476ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann              printMsg(", waiting for more event ::%d\n", max_event_wait);
477ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            else
478ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann              break;
479ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        }
480ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      }
481ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      resetHotlistAPs();
482ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
483ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Could not set AP hotlist : %d\n", result);
484ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
485ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
486ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
487ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
488ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void onSignificantWifiChange(wifi_request_id id,
489ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        unsigned num_results, wifi_scan_result *results)
490ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann{
491ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Significant wifi change for %d\n", num_results);
492ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (unsigned i = 0; i < num_results; i++) {
493ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printScanResult(results[i]);
4947f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
495ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    putEventInCache(EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE, "significant wifi change noticed");
4967f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
4977f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
498ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic int SelectSignificantAPsFromScanResults() {
499ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_scan_result results[256];
500ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(results, 0, sizeof(wifi_scan_result) * 256);
501ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Retrieving scan results for significant wifi change setting\n");
502ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int num_results = 256;
503ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int result = wifi_get_cached_gscan_results(wlan0Handle, 1, results, &num_results);
504ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (result < 0) {
505ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("failed to fetch scan results : %d\n", result);
506ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return WIFI_ERROR_UNKNOWN;
507ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
508ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("fetched %d scan results\n", num_results);
509ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
510ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
511ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < num_results; i++) {
512ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printScanResult(results[i]);
513ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
514ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
515ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_significant_change_params params;
516ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&params, 0, sizeof(params));
517ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
518ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.rssi_sample_size = swctest_rssi_sample_size;
519ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.lost_ap_sample_size = swctest_rssi_lost_ap;
520ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.min_breaching = swctest_rssi_min_breaching;
521ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
522ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < stest_max_ap; i++) {
523ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        memcpy(params.bssids[i].bssid, results[i].bssid, sizeof(mac_addr));
524ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.bssids[i].low  = results[i].rssi - swctest_rssi_ch_threshold;
525ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        params.bssids[i].high = results[i].rssi + swctest_rssi_ch_threshold;
526ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
527ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    params.num = stest_max_ap;
528ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
529ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("Settting Significant change params rssi_sample_size#%d lost_ap_sample_size#%d"
530ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        " and min_breaching#%d\n", params.rssi_sample_size, params.lost_ap_sample_size , params.min_breaching);
531ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("BSSID\t\t\tHIGH\tLOW\n");
532ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    for (int i = 0; i < params.num; i++) {
533ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        mac_addr &addr = params.bssids[i].bssid;
534ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("%02x:%02x:%02x:%02x:%02x:%02x\t%d\t%d\n", addr[0],
535ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                addr[1], addr[2], addr[3], addr[4], addr[5],
536ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                params.bssids[i].high, params.bssids[i].low);
537ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
538ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_significant_change_handler handler;
539ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&handler, 0, sizeof(handler));
540ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    handler.on_significant_change = &onSignificantWifiChange;
541ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
542ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int id = getNewCmdId();
543ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    return wifi_set_significant_change_handler(id, wlan0Handle, params, handler);
544ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
545ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
546ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
547ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void untrackSignificantChange() {
548ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg(", Stop tracking SignificantChange\n");
549ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    wifi_reset_bssid_hotlist(hotlistCmdId, wlan0Handle);
550ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
551ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
552ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannstatic void trackSignificantChange() {
553ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("starting trackSignificantChange\n");
554ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
555ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (!startScan(&onScanResultsAvailable, stest_max_ap,stest_base_period, stest_threshold)) {
556ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("trackSignificantChange failed to start scan!!\n");
557ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return;
558ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    } else {
559ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("trackSignificantChange Scan started, waiting for event ...\n");
560ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
561ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
562ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    EventInfo info;
563ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    memset(&info, 0, sizeof(info));
564ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    getEventFromCache(info);
565ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
566ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    int result = SelectSignificantAPsFromScanResults();
567ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if(result == WIFI_SUCCESS){
568ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Waiting for significant wifi change event\n");
569ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      while(true) {
570ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann          memset(&info, 0, sizeof(info));
571ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann          getEventFromCache(info);
572ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
573ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann          if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE) {
574ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann              retrieveScanResults();
575ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann          }else if(info.type == EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE){
576ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann              printMsg("Received significant wifi change");
577ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann              if(--max_event_wait > 0)
578ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                printMsg(", waiting for more event ::%d\n", max_event_wait);
579ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann              else
580ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann                break;
581ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann          }
582ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      }
583ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      untrackSignificantChange();
584ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else{
585ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann      printMsg("Failed to set significant change  ::%d\n", result);
586ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
587ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
588ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
589ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
590ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
591ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
592ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
5937f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
5947f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* tests                                        */
5957f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde/* -------------------------------------------  */
5967f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
5977f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndevoid testScan() {
598ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printf("starting scan with max_ap_per_scan#%d  base_period#%d  threshold#%d \n",
599ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann           stest_max_ap,stest_base_period, stest_threshold);
600ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (!startScan(&onScanResultsAvailable, stest_max_ap,stest_base_period, stest_threshold)) {
601ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("failed to start scan!!\n");
602ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return;
6037f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    } else {
604ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        EventInfo info;
605ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        memset(&info, 0, sizeof(info));
606ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
607ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        while (true) {
608ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            getEventFromCache(info);
609ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            printMsg("retrieved event %d : %s\n", info.type, info.buf);
610ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            retrieveScanResults();
611ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            if(--max_event_wait > 0)
612ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann              printMsg("Waiting for more :: %d event \n", max_event_wait);
613ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            else
614ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann              break;
615ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        }
616ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
6177f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        stopScan();
618ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("stopped scan\n");
6197f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
6207f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
6217f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
622ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid testStopScan() {
623ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    stopScan();
624ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("stopped scan\n");
625ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
626ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
627ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannbyte parseHexChar(char ch) {
628ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (isdigit(ch))
629ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return ch - '0';
630ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    else if ('A' <= ch && ch <= 'F')
631ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return ch - 'A' + 10;
632ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    else if ('a' <= ch && ch <= 'f')
633ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return ch - 'a' + 10;
634ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    else {
635ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("invalid character in bssid %c", ch);
636ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        return 0;
637ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
638ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
639ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
640ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannbyte parseHexByte(char ch1, char ch2) {
641ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    return (parseHexChar(ch1) << 4) | parseHexChar(ch2);
642ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
643ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
644ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid parseMacAddress(char *str, mac_addr addr) {
645ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[0] = parseHexByte(str[0], str[1]);
646ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[1] = parseHexByte(str[3], str[4]);
647ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[2] = parseHexByte(str[6], str[7]);
648ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[3] = parseHexByte(str[9], str[10]);
649ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[4] = parseHexByte(str[12], str[13]);
650ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    addr[5] = parseHexByte(str[15], str[16]);
651ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    printMsg("read mac addr: %02x:%02x:%02x:%02x:%02x:%02x\n", addr[0],
652ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann            addr[1], addr[2], addr[3], addr[4], addr[5]);
653ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
654ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
655ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mannvoid readTestOptions(int argc, char *argv[]){
656ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
657ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann   printf("Total number of argc #%d\n", argc);
658ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann   for(int j = 1; j < argc-1; j++){
659ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     if (strcmp(argv[j], "-max_ap") == 0 && isdigit(argv[j+1][0])) {
660ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       stest_max_ap = atoi(argv[++j]);
661ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       printf(" max_ap #%d\n", stest_max_ap);
662ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     } else if (strcmp(argv[j], "-base_period") == 0 && isdigit(argv[j+1][0])) {
663ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       stest_base_period = atoi(argv[++j]);
664ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       printf(" base_period #%d\n", stest_base_period);
665ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     } else if (strcmp(argv[j], "-threshold") == 0 && isdigit(argv[j+1][0])) {
666ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       stest_threshold = atoi(argv[++j]);
667ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       printf(" threshold #%d\n", stest_threshold);
668ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     } else if (strcmp(argv[j], "-avg_RSSI") == 0 && isdigit(argv[j+1][0])) {
669ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       swctest_rssi_sample_size = atoi(argv[++j]);
670ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       printf(" avg_RSSI #%d\n", swctest_rssi_sample_size);
671ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     } else if (strcmp(argv[j], "-ap_loss") == 0 && isdigit(argv[j+1][0])) {
672ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       swctest_rssi_lost_ap = atoi(argv[++j]);
673ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       printf(" ap_loss #%d\n", swctest_rssi_lost_ap);
674ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     } else if (strcmp(argv[j], "-ap_breach") == 0 && isdigit(argv[j+1][0])) {
675ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       swctest_rssi_min_breaching = atoi(argv[++j]);
676ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       printf(" ap_breach #%d\n", swctest_rssi_min_breaching);
677ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     } else if (strcmp(argv[j], "-ch_threshold") == 0 && isdigit(argv[j+1][0])) {
678ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       swctest_rssi_ch_threshold = atoi(argv[++j]);
679ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       printf(" ch_threshold #%d\n", swctest_rssi_ch_threshold);
680ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     } else if (strcmp(argv[j], "-wt_event") == 0 && isdigit(argv[j+1][0])) {
681ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       max_event_wait = atoi(argv[++j]);
682ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       printf(" wt_event #%d\n", max_event_wait);
683ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     } else if (strcmp(argv[j], "-low_th") == 0 && isdigit(argv[j+1][0])) {
684ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       htest_low_threshold = atoi(argv[++j]);
685ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       printf(" low_threshold #-%d\n", htest_low_threshold);
686ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     } else if (strcmp(argv[j], "-high_th") == 0 && isdigit(argv[j+1][0])) {
687ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       htest_high_threshold = atoi(argv[++j]);
688ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       printf(" high_threshold #-%d\n", htest_high_threshold);
689ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     } else if (strcmp(argv[j], "-hotlist_bssids") == 0 && isxdigit(argv[j+1][0])) {
690ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       j++;
691ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       for (num_hotlist_bssids = 0; j < argc && isxdigit(argv[j][0]); j++, num_hotlist_bssids++) {
692ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann         parseMacAddress(argv[j], hotlist_bssids[num_hotlist_bssids]);
693ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       }
694ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann       j -= 1;
695ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann     }
696ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
697ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann   }
698ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann}
699ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
7007f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndeint main(int argc, char *argv[]) {
7017f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
702ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_init(&printMutex, NULL);
703ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
7047f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    if (init() != 0) {
705ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("could not initiate HAL");
7067f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde        return -1;
7077f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    } else {
708ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printMsg("successfully initialized HAL; wlan0 = %p\n", wlan0Handle);
7097f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
7107f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
711ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_cond_init(&eventCacheCondition, NULL);
712ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_mutex_init(&eventCacheMutex, NULL);
713ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann
714ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_t tidEvent;
715ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    pthread_create(&tidEvent, NULL, &eventThreadFunc, NULL);
7167f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
7177f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    sleep(2);     // let the thread start
7187f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
719ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (argc < 2 || argv[1][0] != '-') {
720ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf("Usage:  halutil [OPTION]\n");
721ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -s               start AP scan test\n");
722ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -swc             start Significant Wifi change test\n");
723ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -h               start Hotlist APs scan test\n");
724ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -ss              stop scan test\n");
725ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -max_ap          Max AP for scan \n");
726ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -base_period     Base period for scan \n");
727ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -threshold       Threshold scan test\n");
728ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -avg_RSSI        samples for averaging RSSI\n");
729ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -ap_loss         samples to confirm AP loss\n");
730ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -ap_breach       APs breaching threshold\n");
731ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -ch_threshold    Change in threshold\n");
732ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -wt_event        Waiting event for test\n");
733ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -low_th          Low threshold for hotlist APs\n");
734ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -hight_th        High threshold for hotlist APs\n");
735ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        printf(" -hotlist_bssids  BSSIDs for hotlist test\n");
736ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        goto cleanup;
737ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }
7387f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
739ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    if (strcmp(argv[1], "-s") == 0) {
740ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        readTestOptions(argc, argv);
741ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        testScan();
742ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else if(strcmp(argv[1], "-swc") == 0){
743ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        readTestOptions(argc, argv);
744ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        trackSignificantChange();
745ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else if (strcmp(argv[1], "-ss") == 0) {
746ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        testStopScan();
747ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann    }else if(strcmp(argv[1], "-h") == 0) {
748ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        readTestOptions(argc, argv);
749ff658ac8e6c092521e11e3c58764c77be2de2ffaNavtej Singh Mann        testHotlistAPs();
7507f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
7517f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
7527f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapndecleanup:
7537f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    cleanup();
7547f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    return 0;
7557f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde}
756