Update to android 10 wifi hal lineage-18.1 lineage-19.1
authorAaron Kling <webgeek1234@gmail.com>
Sat, 3 Jul 2021 05:50:53 +0000 (00:50 -0500)
committerAaron Kling <webgeek1234@gmail.com>
Sat, 3 Jul 2021 06:24:35 +0000 (01:24 -0500)
24 files changed:
wlan/Android.mk [new file with mode: 0644]
wlan/wifi_hal/Android.mk
wlan/wifi_hal/common.h
wlan/wifi_hal/gscan.cpp [deleted file]
wlan/wifi_hal/link_layer_stats.cpp [deleted file]
wlan/wifi_hal/rtt.cpp [deleted file]
wlan/wifi_hal/rtw_wifi_gscan.cpp [new file with mode: 0644]
wlan/wifi_hal/rtw_wifi_hal.cpp [new file with mode: 0644]
wlan/wifi_hal/rtw_wifi_llstats.cpp [new file with mode: 0644]
wlan/wifi_hal/rtw_wifi_logger.cpp [new file with mode: 0644]
wlan/wifi_hal/rtw_wifi_offload.cpp [new file with mode: 0644]
wlan/wifi_hal/rtw_wifi_rtt.cpp [new file with mode: 0644]
wlan/wifi_hal/version.h [new file with mode: 0644]
wlan/wifi_hal/wifi_hal.cpp [deleted file]
wlan/wifi_hal/wifi_logger.cpp [deleted file]
wlan/wifi_hal/wifi_offload.cpp [deleted file]
wlan/wpa_supplicant_8_lib/Android.mk [new file with mode: 0644]
wlan/wpa_supplicant_8_lib/MODULE_LICENSE_BSD [new file with mode: 0644]
wlan/wpa_supplicant_8_lib/NOTICE [new file with mode: 0644]
wlan/wpa_supplicant_8_lib/driver_cmd_nl80211.c [new file with mode: 0644]
wlan/wpa_supplicant_8_lib/driver_cmd_wext.c [new file with mode: 0644]
wlan/wpa_supplicant_8_lib/driver_cmd_wext.h [new file with mode: 0644]
wlan/wpa_supplicant_8_lib/driver_nl80211.h [new file with mode: 0644]
wlan/wpa_supplicant_8_lib/rtw_version.h [new file with mode: 0644]

diff --git a/wlan/Android.mk b/wlan/Android.mk
new file mode 100644 (file)
index 0000000..644f883
--- /dev/null
@@ -0,0 +1,3 @@
+ifeq ($(BOARD_WLAN_DEVICE), realtek)
+       include $(call all-subdir-makefiles)
+endif
index fc8267ec4c088955214101a8dcab42cbe635fef8..43683c8318f9c4d38c8bd5de9c580ebf23eabca0 100644 (file)
@@ -26,22 +26,24 @@ LOCAL_CFLAGS := \
     -Wno-unused-function \
     -Wno-unused-parameter \
     -Wno-unused-private-field \
-    -Wno-unused-variable \
+    -Wno-unused-variable 
+#    -DCONFIG_WIFI_HAL_DEBUG
 
 LOCAL_C_INCLUDES += \
        external/libnl/include \
        $(call include-path-for, libhardware_legacy)/hardware_legacy \
        external/wpa_supplicant_8/src/drivers
 
+LOCAL_HEADER_LIBRARIES := libutils_headers liblog_headers
 LOCAL_SRC_FILES := \
-       wifi_hal.cpp \
-       rtt.cpp \
+       rtw_wifi_hal.cpp \
+       rtw_wifi_rtt.cpp \
        common.cpp \
        cpp_bindings.cpp \
-       gscan.cpp \
-       link_layer_stats.cpp \
-       wifi_logger.cpp \
-       wifi_offload.cpp
+       rtw_wifi_gscan.cpp \
+       rtw_wifi_llstats.cpp \
+       rtw_wifi_logger.cpp \
+       rtw_wifi_offload.cpp
 
 LOCAL_MODULE := libwifi-hal-rtk
 LOCAL_PROPRIETARY_MODULE := true
index a8d60b73926cb93a19aaefda6010d99ca24eddd4..27101b751d0d5508cccc31fbcb73451452a9feb2 100644 (file)
@@ -21,7 +21,7 @@
 
 #define LOG_TAG  "WifiHAL"
 
-#include <utils/Log.h>
+#include <log/log.h>
 #include "nl80211_copy.h"
 #include "sync.h"
 
diff --git a/wlan/wifi_hal/gscan.cpp b/wlan/wifi_hal/gscan.cpp
deleted file mode 100644 (file)
index d33ac93..0000000
+++ /dev/null
@@ -1,1856 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/rtnetlink.h>
-#include <netpacket/packet.h>
-#include <linux/filter.h>
-#include <linux/errqueue.h>
-
-#include <linux/pkt_sched.h>
-#include <netlink/object-api.h>
-#include <netlink/netlink.h>
-#include <netlink/socket.h>
-#include <netlink/handlers.h>
-
-#include "sync.h"
-
-#define LOG_TAG  "WifiHAL"
-//#define LOG_NDEBUG 0         //uncomment to enable verbose logging
-
-#include <utils/Log.h>
-
-#include "wifi_hal.h"
-#include "common.h"
-#include "cpp_bindings.h"
-
-typedef enum {
-
-    GSCAN_ATTRIBUTE_NUM_BUCKETS = 10,
-    GSCAN_ATTRIBUTE_BASE_PERIOD,
-    GSCAN_ATTRIBUTE_BUCKETS_BAND,
-    GSCAN_ATTRIBUTE_BUCKET_ID,
-    GSCAN_ATTRIBUTE_BUCKET_PERIOD,
-    GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS,
-    GSCAN_ATTRIBUTE_BUCKET_CHANNELS,
-    GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN,
-    GSCAN_ATTRIBUTE_REPORT_THRESHOLD,
-    GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE,
-    GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND,
-
-    GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20,
-    GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE,              /* indicates no more results */
-    GSCAN_ATTRIBUTE_FLUSH_FEATURE,                      /* Flush all the configs */
-    GSCAN_ENABLE_FULL_SCAN_RESULTS,
-    GSCAN_ATTRIBUTE_REPORT_EVENTS,
-
-    /* remaining reserved for additional attributes */
-    GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30,
-    GSCAN_ATTRIBUTE_FLUSH_RESULTS,
-    GSCAN_ATTRIBUTE_SCAN_RESULTS,                       /* flat array of wifi_scan_result */
-    GSCAN_ATTRIBUTE_SCAN_ID,                            /* indicates scan number */
-    GSCAN_ATTRIBUTE_SCAN_FLAGS,                         /* indicates if scan was aborted */
-    GSCAN_ATTRIBUTE_AP_FLAGS,                           /* flags on significant change event */
-    GSCAN_ATTRIBUTE_NUM_CHANNELS,
-    GSCAN_ATTRIBUTE_CHANNEL_LIST,
-    GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK,
-    /* remaining reserved for additional attributes */
-
-    GSCAN_ATTRIBUTE_SSID = 40,
-    GSCAN_ATTRIBUTE_BSSID,
-    GSCAN_ATTRIBUTE_CHANNEL,
-    GSCAN_ATTRIBUTE_RSSI,
-    GSCAN_ATTRIBUTE_TIMESTAMP,
-    GSCAN_ATTRIBUTE_RTT,
-    GSCAN_ATTRIBUTE_RTTSD,
-
-    /* remaining reserved for additional attributes */
-
-    GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50,
-    GSCAN_ATTRIBUTE_RSSI_LOW,
-    GSCAN_ATTRIBUTE_RSSI_HIGH,
-    GSCAN_ATTRIBUTE_HOTLIST_ELEM,
-    GSCAN_ATTRIBUTE_HOTLIST_FLUSH,
-    GSCAN_ATTRIBUTE_HOTLIST_BSSID_COUNT,
-
-    /* remaining reserved for additional attributes */
-    GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60,
-    GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE,
-    GSCAN_ATTRIBUTE_MIN_BREACHING,
-    GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS,
-    GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH,
-
-    /* EPNO */
-    GSCAN_ATTRIBUTE_EPNO_SSID_LIST = 70,
-    GSCAN_ATTRIBUTE_EPNO_SSID,
-    GSCAN_ATTRIBUTE_EPNO_SSID_LEN,
-    GSCAN_ATTRIBUTE_EPNO_RSSI,
-    GSCAN_ATTRIBUTE_EPNO_FLAGS,
-    GSCAN_ATTRIBUTE_EPNO_AUTH,
-    GSCAN_ATTRIBUTE_EPNO_SSID_NUM,
-    GSCAN_ATTRIBUTE_EPNO_FLUSH,
-
-    /* remaining reserved for additional attributes */
-
-    GSCAN_ATTRIBUTE_WHITELIST_SSID = 80,
-    GSCAN_ATTRIBUTE_NUM_WL_SSID,
-    GSCAN_ATTRIBUTE_WL_SSID_LEN,
-    GSCAN_ATTRIBUTE_WL_SSID_FLUSH,
-    GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM,
-    GSCAN_ATTRIBUTE_NUM_BSSID,
-    GSCAN_ATTRIBUTE_BSSID_PREF_LIST,
-    GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH,
-    GSCAN_ATTRIBUTE_BSSID_PREF,
-    GSCAN_ATTRIBUTE_RSSI_MODIFIER,
-
-    /* remaining reserved for additional attributes */
-
-    GSCAN_ATTRIBUTE_A_BAND_BOOST_THRESHOLD = 90,
-    GSCAN_ATTRIBUTE_A_BAND_PENALTY_THRESHOLD,
-    GSCAN_ATTRIBUTE_A_BAND_BOOST_FACTOR,
-    GSCAN_ATTRIBUTE_A_BAND_PENALTY_FACTOR,
-    GSCAN_ATTRIBUTE_A_BAND_MAX_BOOST,
-    GSCAN_ATTRIBUTE_LAZY_ROAM_HYSTERESIS,
-    GSCAN_ATTRIBUTE_ALERT_ROAM_RSSI_TRIGGER,
-    GSCAN_ATTRIBUTE_LAZY_ROAM_ENABLE,
-
-    /* BSSID blacklist */
-    GSCAN_ATTRIBUTE_BSSID_BLACKLIST_FLUSH = 100,
-    GSCAN_ATTRIBUTE_BLACKLIST_BSSID,
-
-    /* ANQPO */
-    GSCAN_ATTRIBUTE_ANQPO_HS_LIST = 110,
-    GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE,
-    GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID,
-    GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM,
-    GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID,
-    GSCAN_ATTRIBUTE_ANQPO_HS_PLMN,
-
-    /* Adaptive scan attributes */
-    GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT = 120,
-    GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD,
-
-    /* ePNO cfg */
-    GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR = 130,
-    GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR,
-    GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX,
-    GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS,
-    GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS,
-    GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS,
-    GSCAN_ATTRIBUTE_EPNO_5G_BONUS,
-
-    GSCAN_ATTRIBUTE_MAX
-
-} GSCAN_ATTRIBUTE;
-
-
-// helper methods
-wifi_error wifi_enable_full_scan_results(wifi_request_id id, wifi_interface_handle iface,
-         wifi_scan_result_handler handler);
-wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface);
-int wifi_handle_full_scan_event(wifi_request_id id, WifiEvent& event,
-         wifi_scan_result_handler handler);
-void convert_to_hal_result(wifi_scan_result *to, wifi_gscan_result_t *from);
-
-
-void convert_to_hal_result(wifi_scan_result *to, wifi_gscan_result_t *from)
-{
-    to->ts = from->ts;
-    to->channel = from->channel;
-    to->rssi = from->rssi;
-    to->rtt = from->rtt;
-    to->rtt_sd = from->rtt_sd;
-    to->beacon_period = from->beacon_period;
-    to->capability = from->capability;
-    memcpy(to->ssid, from->ssid, (DOT11_MAX_SSID_LEN+1));
-    memcpy(&to->bssid, &from->bssid, sizeof(mac_addr));
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-class GetCapabilitiesCommand : public WifiCommand
-{
-    wifi_gscan_capabilities *mCapabilities;
-public:
-    GetCapabilitiesCommand(wifi_interface_handle iface, wifi_gscan_capabilities *capabitlites)
-        : WifiCommand("GetGscanCapabilitiesCommand", iface, 0), mCapabilities(capabitlites)
-    {
-        memset(mCapabilities, 0, sizeof(*mCapabilities));
-    }
-
-    virtual int create() {
-        ALOGV("Creating message to get scan capablities; iface = %d", mIfaceInfo->id);
-
-        int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CAPABILITIES);
-        if (ret < 0) {
-            return ret;
-        }
-
-        return ret;
-    }
-
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-
-        ALOGV("In GetCapabilities::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-
-        void *data = reply.get_vendor_data();
-        int len = reply.get_vendor_data_len();
-
-        ALOGV("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
-                    sizeof(*mCapabilities));
-
-        memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities)));
-
-        return NL_OK;
-    }
-};
-
-
-wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle,
-        wifi_gscan_capabilities *capabilities)
-{
-    GetCapabilitiesCommand command(handle, capabilities);
-    return (wifi_error) command.requestResponse();
-}
-
-class GetChannelListCommand : public WifiCommand
-{
-    wifi_channel *channels;
-    int max_channels;
-    int *num_channels;
-    int band;
-public:
-    GetChannelListCommand(wifi_interface_handle iface, wifi_channel *channel_buf, int *ch_num,
-        int num_max_ch, int band)
-        : WifiCommand("GetChannelListCommand", iface, 0), channels(channel_buf),
-            max_channels(num_max_ch), num_channels(ch_num), band(band)
-    {
-        memset(channels, 0, sizeof(wifi_channel) * max_channels);
-    }
-    virtual int create() {
-        ALOGV("Creating message to get channel list; iface = %d", mIfaceInfo->id);
-
-        int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CHANNEL_LIST);
-        if (ret < 0) {
-            return ret;
-        }
-
-        nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
-        ret = mMsg.put_u32(GSCAN_ATTRIBUTE_BAND, band);
-        if (ret < 0) {
-            return ret;
-        }
-
-        mMsg.attr_end(data);
-
-        return ret;
-    }
-
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-
-        ALOGV("In GetChannelList::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-        int num_channels_to_copy = 0;
-
-        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = reply.get_vendor_data_len();
-
-        ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
-        if (vendor_data == NULL || len == 0) {
-            ALOGE("no vendor data in GetChannelList response; ignoring it");
-            return NL_SKIP;
-        }
-
-        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
-            if (it.get_type() == GSCAN_ATTRIBUTE_NUM_CHANNELS) {
-                num_channels_to_copy = it.get_u32();
-                ALOGI("Got channel list with %d channels", num_channels_to_copy);
-                if(num_channels_to_copy > max_channels)
-                    num_channels_to_copy = max_channels;
-                *num_channels = num_channels_to_copy;
-            } else if (it.get_type() == GSCAN_ATTRIBUTE_CHANNEL_LIST && num_channels_to_copy) {
-                memcpy(channels, it.get_data(), sizeof(int) * num_channels_to_copy);
-            } else {
-                ALOGW("Ignoring invalid attribute type = %d, size = %d",
-                        it.get_type(), it.get_len());
-            }
-        }
-
-        return NL_OK;
-    }
-};
-
-wifi_error wifi_get_valid_channels(wifi_interface_handle handle,
-        int band, int max_channels, wifi_channel *channels, int *num_channels)
-{
-#if 0
-    GetChannelListCommand command(handle, channels, num_channels,
-                                        max_channels, band);
-    return (wifi_error) command.requestResponse();
-#endif
-       *num_channels = 12;
-       return WIFI_SUCCESS;
-}
-/////////////////////////////////////////////////////////////////////////////
-
-/* helper functions */
-
-static int parseScanResults(wifi_scan_result *results, int num, nlattr *attr)
-{
-    memset(results, 0, sizeof(wifi_scan_result) * num);
-
-    int i = 0;
-    for (nl_iterator it(attr); it.has_next() && i < num; it.next(), i++) {
-
-        int index = it.get_type();
-        ALOGI("retrieved scan result %d", index);
-        nlattr *sc_data = (nlattr *) it.get_data();
-        wifi_scan_result *result = results + i;
-
-        for (nl_iterator it2(sc_data); it2.has_next(); it2.next()) {
-            int type = it2.get_type();
-            if (type == GSCAN_ATTRIBUTE_SSID) {
-                strncpy(result->ssid, (char *) it2.get_data(), it2.get_len());
-                result->ssid[it2.get_len()] = 0;
-            } else if (type == GSCAN_ATTRIBUTE_BSSID) {
-                memcpy(result->bssid, (byte *) it2.get_data(), sizeof(mac_addr));
-            } else if (type == GSCAN_ATTRIBUTE_TIMESTAMP) {
-                result->ts = it2.get_u64();
-            } else if (type == GSCAN_ATTRIBUTE_CHANNEL) {
-                result->ts = it2.get_u16();
-            } else if (type == GSCAN_ATTRIBUTE_RSSI) {
-                result->rssi = it2.get_u8();
-            } else if (type == GSCAN_ATTRIBUTE_RTT) {
-                result->rtt = it2.get_u64();
-            } else if (type == GSCAN_ATTRIBUTE_RTTSD) {
-                result->rtt_sd = it2.get_u64();
-            }
-        }
-
-    }
-
-    if (i >= num) {
-        ALOGE("Got too many results; skipping some");
-    }
-
-    return i;
-}
-
-int createFeatureRequest(WifiRequest& request, int subcmd, int enable) {
-
-    int result = request.create(GOOGLE_OUI, subcmd);
-    if (result < 0) {
-        return result;
-    }
-
-    nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-    result = request.put_u32(GSCAN_ATTRIBUTE_ENABLE_FEATURE, enable);
-    if (result < 0) {
-        return result;
-    }
-
-    request.attr_end(data);
-    return WIFI_SUCCESS;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-class FullScanResultsCommand : public WifiCommand
-{
-    int *mParams;
-    wifi_scan_result_handler mHandler;
-public:
-    FullScanResultsCommand(wifi_interface_handle iface, int id, int *params,
-                wifi_scan_result_handler handler)
-        : WifiCommand("FullScanResultsCommand", iface, id), mParams(params), mHandler(handler)
-    { }
-
-    int createRequest(WifiRequest& request, int subcmd, int enable) {
-        int result = request.create(GOOGLE_OUI, subcmd);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u32(GSCAN_ENABLE_FULL_SCAN_RESULTS, enable);
-        if (result < 0) {
-            return result;
-        }
-
-        request.attr_end(data);
-        return WIFI_SUCCESS;
-
-    }
-
-    int start() {
-        ALOGV("Enabling Full scan results");
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 1);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create request; result = %d", result);
-            return result;
-        }
-
-        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to enable full scan results; result = %d", result);
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
-            return result;
-        }
-
-        return result;
-    }
-
-    virtual int cancel() {
-        ALOGV("Disabling Full scan results");
-
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 0);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create request; result = %d", result);
-        } else {
-            result = requestResponse(request);
-            if (result != WIFI_SUCCESS) {
-                ALOGE("failed to disable full scan results;result = %d", result);
-            }
-        }
-
-        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
-        return WIFI_SUCCESS;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-         ALOGD("Request complete!");
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        ALOGV("Full scan results:  Got an event");
-        return wifi_handle_full_scan_event(id(), event, mHandler);
-    }
-
-};
-/////////////////////////////////////////////////////////////////////////////
-
-class ScanCommand : public WifiCommand
-{
-    wifi_scan_cmd_params *mParams;
-    wifi_scan_result_handler mHandler;
-public:
-    ScanCommand(wifi_interface_handle iface, int id, wifi_scan_cmd_params *params,
-                wifi_scan_result_handler handler)
-        : WifiCommand("ScanCommand", iface, id), mParams(params), mHandler(handler)
-    { }
-
-    int createSetupRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_CONFIG);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u32(GSCAN_ATTRIBUTE_BASE_PERIOD, mParams->base_period);
-        if (result < 0) {
-            return result;
-        }
-
-        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_BUCKETS, mParams->num_buckets);
-        if (result < 0) {
-            return result;
-        }
-
-        for (int i = 0; i < mParams->num_buckets; i++) {
-            nlattr * bucket = request.attr_start(i);    // next bucket
-            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_ID, mParams->buckets[i].bucket);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_PERIOD, mParams->buckets[i].period);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKETS_BAND,
-                    mParams->buckets[i].band);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT,
-                    mParams->buckets[i].step_count);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD,
-                    mParams->buckets[i].max_period);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_EVENTS,
-                    mParams->buckets[i].report_events);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS,
-                    mParams->buckets[i].num_channels);
-            if (result < 0) {
-                return result;
-            }
-
-            if (mParams->buckets[i].num_channels) {
-                nlattr *channels = request.attr_start(GSCAN_ATTRIBUTE_BUCKET_CHANNELS);
-                ALOGV(" channels: ");
-                for (int j = 0; j < mParams->buckets[i].num_channels; j++) {
-                    result = request.put_u32(j, mParams->buckets[i].channels[j].channel);
-                    ALOGV(" %u", mParams->buckets[i].channels[j].channel);
-
-                    if (result < 0) {
-                        return result;
-                    }
-                }
-                request.attr_end(channels);
-            }
-
-            request.attr_end(bucket);
-        }
-
-        request.attr_end(data);
-        return WIFI_SUCCESS;
-    }
-
-    int createScanConfigRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SCAN_CONFIG);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, mParams->max_ap_per_scan);
-        if (result < 0) {
-            return result;
-        }
-
-        result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_THRESHOLD,
-                mParams->report_threshold_percent);
-        if (result < 0) {
-            return result;
-        }
-
-        int num_scans = mParams->report_threshold_num_scans;
-
-        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, num_scans);
-        if (result < 0) {
-            return result;
-        }
-
-        request.attr_end(data);
-        return WIFI_SUCCESS;
-    }
-
-    int createStartRequest(WifiRequest& request) {
-        return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1);
-    }
-
-    int createStopRequest(WifiRequest& request) {
-        return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 0);
-    }
-
-    int start() {
-        ALOGV("GSCAN start");
-        WifiRequest request(familyId(), ifaceId());
-        int result = createSetupRequest(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create setup request; result = %d", result);
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to configure setup; result = %d", result);
-            return result;
-        }
-
-        request.destroy();
-
-        result = createScanConfigRequest(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create scan config request; result = %d", result);
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to configure scan; result = %d", result);
-            return result;
-        }
-
-        ALOGV(" ....starting scan");
-
-        result = createStartRequest(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create start request; result = %d", result);
-            return result;
-        }
-
-        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
-        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
-        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to start scan; result = %d", result);
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
-            return result;
-        }
-        return result;
-    }
-
-    virtual int cancel() {
-        ALOGV("Stopping scan");
-
-        WifiRequest request(familyId(), ifaceId());
-        int result = createStopRequest(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create stop request; result = %d", result);
-        } else {
-            result = requestResponse(request);
-            if (result != WIFI_SUCCESS) {
-                ALOGE("failed to stop scan; result = %d", result);
-            }
-        }
-
-        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
-        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
-        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
-        return WIFI_SUCCESS;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        ALOGV("Got a scan results event");
-        //event.log();
-
-        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = event.get_vendor_data_len();
-        int event_id = event.get_vendor_subcmd();
-
-        if ((event_id == GSCAN_EVENT_COMPLETE_SCAN) ||
-            (event_id == GSCAN_EVENT_SCAN_RESULTS_AVAILABLE)) {
-            if (vendor_data == NULL || len != 4) {
-                ALOGI("Bad event data!");
-                return NL_SKIP;
-            }
-            wifi_scan_event evt_type;
-            evt_type = (wifi_scan_event) event.get_u32(NL80211_ATTR_VENDOR_DATA);
-            ALOGV("Received event type %d", evt_type);
-            if(*mHandler.on_scan_event)
-                (*mHandler.on_scan_event)(id(), evt_type);
-        } else if (event_id == GSCAN_EVENT_FULL_SCAN_RESULTS) {
-            wifi_handle_full_scan_event(id(), event, mHandler);
-        }
-        return NL_SKIP;
-    }
-};
-
-wifi_error wifi_start_gscan(
-        wifi_request_id id,
-        wifi_interface_handle iface,
-        wifi_scan_cmd_params params,
-        wifi_scan_result_handler handler)
-{
-    wifi_handle handle = getWifiHandle(iface);
-
-    ALOGV("Starting GScan, halHandle = %p", handle);
-
-    ScanCommand *cmd = new ScanCommand(iface, id, &params, handler);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = wifi_register_cmd(handle, id, cmd);
-    if (result != WIFI_SUCCESS) {
-        cmd->releaseRef();
-        return result;
-    }
-    result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-        cmd->releaseRef();
-        return result;
-    }
-    return result;
-}
-
-wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface)
-{
-    wifi_handle handle = getWifiHandle(iface);
-    ALOGV("Stopping GScan, wifi_request_id = %d, halHandle = %p", id, handle);
-
-    if (id == -1) {
-        wifi_scan_result_handler handler;
-        wifi_scan_cmd_params dummy_params;
-        wifi_handle handle = getWifiHandle(iface);
-        memset(&handler, 0, sizeof(handler));
-
-        ScanCommand *cmd = new ScanCommand(iface, id, &dummy_params, handler);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        cmd->cancel();
-        cmd->releaseRef();
-        return WIFI_SUCCESS;
-    }
-
-    return wifi_cancel_cmd(id, iface);
-}
-
-wifi_error wifi_enable_full_scan_results(
-        wifi_request_id id,
-        wifi_interface_handle iface,
-        wifi_scan_result_handler handler)
-{
-    wifi_handle handle = getWifiHandle(iface);
-    int params_dummy;
-
-    ALOGV("Enabling full scan results, halHandle = %p", handle);
-
-    FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, id, &params_dummy, handler);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = wifi_register_cmd(handle, id, cmd);
-    if (result != WIFI_SUCCESS) {
-        cmd->releaseRef();
-        return result;
-    }
-    result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-        cmd->releaseRef();
-        return result;
-    }
-    return result;
-}
-
-int wifi_handle_full_scan_event(
-        wifi_request_id id,
-        WifiEvent& event,
-        wifi_scan_result_handler handler)
-{
-    nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-    unsigned int len = event.get_vendor_data_len();
-
-    if (vendor_data == NULL || len < sizeof(wifi_gscan_full_result_t)) {
-        ALOGI("Full scan results: No scan results found");
-        return NL_SKIP;
-    }
-
-    wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data();
-    /* To protect against corrupted data, put a ceiling */
-    int ie_len = min(MAX_PROBE_RESP_IE_LEN, drv_res->ie_length);
-    wifi_scan_result *full_scan_result;
-    wifi_gscan_result_t *fixed = &drv_res->fixed;
-
-    if ((ie_len + offsetof(wifi_gscan_full_result_t, ie_data)) > len) {
-        ALOGE("BAD event data, len %d ie_len %d fixed length %d!\n", len,
-            ie_len, offsetof(wifi_gscan_full_result_t, ie_data));
-        return NL_SKIP;
-    }
-    full_scan_result = (wifi_scan_result *) malloc((ie_len + offsetof(wifi_scan_result, ie_data)));
-    if (!full_scan_result) {
-        ALOGE("Full scan results: Can't malloc!\n");
-        return NL_SKIP;
-    }
-    convert_to_hal_result(full_scan_result, fixed);
-    full_scan_result->ie_length = ie_len;
-    memcpy(full_scan_result->ie_data, drv_res->ie_data, ie_len);
-    if(handler.on_full_scan_result)
-        handler.on_full_scan_result(id, full_scan_result, drv_res->scan_ch_bucket);
-
-    ALOGV("Full scan result: %-32s %02x:%02x:%02x:%02x:%02x:%02x %d %d %lld %lld %lld %x %d\n",
-        fixed->ssid, fixed->bssid[0], fixed->bssid[1], fixed->bssid[2], fixed->bssid[3],
-        fixed->bssid[4], fixed->bssid[5], fixed->rssi, fixed->channel, fixed->ts,
-        fixed->rtt, fixed->rtt_sd, drv_res->scan_ch_bucket, drv_res->ie_length);
-    free(full_scan_result);
-    return NL_SKIP;
-}
-
-
-wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface)
-{
-    ALOGV("Disabling full scan results");
-    wifi_handle handle = getWifiHandle(iface);
-
-    if(id == -1) {
-        wifi_scan_result_handler handler;
-        wifi_handle handle = getWifiHandle(iface);
-        int params_dummy;
-
-        memset(&handler, 0, sizeof(handler));
-        FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, 0, &params_dummy, handler);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        cmd->cancel();
-        cmd->releaseRef();
-        return WIFI_SUCCESS;
-    }
-
-    return wifi_cancel_cmd(id, iface);
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-class GetScanResultsCommand : public WifiCommand {
-    wifi_cached_scan_results *mScans;
-    int mMax;
-    int *mNum;
-    int mRetrieved;
-    byte mFlush;
-    int mCompleted;
-public:
-    GetScanResultsCommand(wifi_interface_handle iface, byte flush,
-            wifi_cached_scan_results *results, int max, int *num)
-        : WifiCommand("GetScanResultsCommand", iface, -1), mScans(results), mMax(max), mNum(num),
-                mRetrieved(0), mFlush(flush), mCompleted(0)
-    { }
-
-    int createRequest(WifiRequest& request, int num, byte flush) {
-        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_SCAN_RESULTS);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_OF_RESULTS, num);
-        if (result < 0) {
-            return result;
-        }
-
-        result = request.put_u8(GSCAN_ATTRIBUTE_FLUSH_RESULTS, flush);
-        if (result < 0) {
-            return result;
-        }
-
-        request.attr_end(data);
-        return WIFI_SUCCESS;
-    }
-
-    int execute() {
-        WifiRequest request(familyId(), ifaceId());
-        ALOGV("retrieving %d scan results", mMax);
-
-        for (int i = 0; i < 10 && mRetrieved < mMax; i++) {
-            int num_to_retrieve = mMax - mRetrieved;
-            // ALOGI("retrieving %d scan results in one shot", num_to_retrieve);
-            int result = createRequest(request, num_to_retrieve, mFlush);
-            if (result < 0) {
-                ALOGE("failed to create request");
-                return result;
-            }
-
-            int prev_retrieved = mRetrieved;
-
-            result = requestResponse(request);
-
-            if (result != WIFI_SUCCESS) {
-                ALOGE("failed to retrieve scan results; result = %d", result);
-                return result;
-            }
-
-            if (mRetrieved == prev_retrieved || mCompleted) {
-                /* no more items left to retrieve */
-                break;
-            }
-
-            request.destroy();
-        }
-
-        ALOGV("GetScanResults read %d results", mRetrieved);
-        *mNum = mRetrieved;
-        return WIFI_SUCCESS;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        ALOGV("In GetScanResultsCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-
-        ALOGV("Id = %0x, subcmd = %d", id, subcmd);
-
-        /*
-        if (subcmd != GSCAN_SUBCMD_SCAN_RESULTS) {
-            ALOGE("Invalid response to GetScanResultsCommand; ignoring it");
-            return NL_SKIP;
-        }
-        */
-
-        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = reply.get_vendor_data_len();
-
-        if (vendor_data == NULL || len == 0) {
-            ALOGE("no vendor data in GetScanResults response; ignoring it");
-            return NL_SKIP;
-        }
-
-        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
-            if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE) {
-                mCompleted = it.get_u8();
-                ALOGV("retrieved mCompleted flag : %d", mCompleted);
-            } else if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS || it.get_type() == 0) {
-                int scan_id = 0, flags = 0, num = 0, scan_ch_bucket_mask = 0;
-                for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
-                    if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_ID) {
-                        scan_id = it2.get_u32();
-                        ALOGV("retrieved scan_id : 0x%0x", scan_id);
-                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_FLAGS) {
-                        flags = it2.get_u8();
-                        ALOGV("retrieved scan_flags : 0x%0x", flags);
-                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) {
-                        num = it2.get_u32();
-                        ALOGV("retrieved num_results: %d", num);
-                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK) {
-                        scan_ch_bucket_mask = it2.get_u32();
-                        ALOGD("retrieved scan_ch_bucket_mask: %x", scan_ch_bucket_mask);
-                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS && num) {
-                        if (mRetrieved >= mMax) {
-                            ALOGW("Stored %d scans, ignoring excess results", mRetrieved);
-                            break;
-                        }
-                        num = min(num, (int)(it2.get_len()/sizeof(wifi_gscan_result)));
-                        num = min(num, (int)MAX_AP_CACHE_PER_SCAN);
-                        ALOGV("Copying %d scan results", num);
-                        wifi_gscan_result_t *results = (wifi_gscan_result_t *)it2.get_data();
-                        wifi_scan_result *mScanResults = mScans[mRetrieved].results;
-
-                        for (int i = 0; i < num; i++) {
-                            wifi_gscan_result_t *result = &results[i];
-                            convert_to_hal_result(&mScanResults[i], result);
-                            mScanResults[i].ie_length = 0;
-                            ALOGV("%02d  %-32s  %02x:%02x:%02x:%02x:%02x:%02x  %04d", i,
-                                result->ssid, result->bssid[0], result->bssid[1], result->bssid[2],
-                                result->bssid[3], result->bssid[4], result->bssid[5],
-                                result->rssi);
-                        }
-                        mScans[mRetrieved].scan_id = scan_id;
-                        mScans[mRetrieved].flags = flags;
-                        mScans[mRetrieved].num_results = num;
-                        mScans[mRetrieved].buckets_scanned = scan_ch_bucket_mask;
-                        ALOGV("Setting result of scan_id : 0x%0x", mScans[mRetrieved].scan_id);
-                        mRetrieved++;
-                    } else {
-                        ALOGW("Ignoring invalid attribute type = %d, size = %d",
-                                it.get_type(), it.get_len());
-                    }
-                }
-            } else {
-                ALOGW("Ignoring invalid attribute type = %d, size = %d",
-                        it.get_type(), it.get_len());
-            }
-        }
-        ALOGV("GetScanResults read %d results", mRetrieved);
-        return NL_OK;
-    }
-};
-
-wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, byte flush,
-        int max, wifi_cached_scan_results *results, int *num) {
-    ALOGV("Getting cached scan results, iface handle = %p, num = %d", iface, *num);
-
-    GetScanResultsCommand *cmd = new GetScanResultsCommand(iface, flush, results, max, num);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error err = (wifi_error)cmd->execute();
-    cmd->releaseRef();
-    return err;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-class BssidHotlistCommand : public WifiCommand
-{
-private:
-    wifi_bssid_hotlist_params mParams;
-    wifi_hotlist_ap_found_handler mHandler;
-    static const int MAX_RESULTS = 64;
-    wifi_scan_result mResults[MAX_RESULTS];
-public:
-    BssidHotlistCommand(wifi_interface_handle handle, int id,
-            wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler)
-        : WifiCommand("BssidHotlistCommand", handle, id), mParams(params), mHandler(handler)
-    { }
-
-    int createSetupRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_HOTLIST);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u8(GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 1);
-        if (result < 0) {
-            return result;
-        }
-
-        result = request.put_u32(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, mParams.lost_ap_sample_size);
-        if (result < 0) {
-            return result;
-        }
-
-        result = request.put_u32(GSCAN_ATTRIBUTE_HOTLIST_BSSID_COUNT, mParams.num_bssid);
-        if (result < 0) {
-            return result;
-        }
-
-        struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS);
-        for (int i = 0; i < mParams.num_bssid; i++) {
-            nlattr *attr2 = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_ELEM);
-            if (attr2 == NULL) {
-                return WIFI_ERROR_OUT_OF_MEMORY;
-            }
-            result = request.put_addr(GSCAN_ATTRIBUTE_BSSID, mParams.ap[i].bssid);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH, mParams.ap[i].high);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW, mParams.ap[i].low);
-            if (result < 0) {
-                return result;
-            }
-            request.attr_end(attr2);
-        }
-
-        request.attr_end(attr);
-        request.attr_end(data);
-        return result;
-    }
-
-    int createTeardownRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_HOTLIST);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u8(GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 1);
-        if (result < 0) {
-            return result;
-        }
-
-        struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS);
-        request.attr_end(attr);
-        request.attr_end(data);
-        return result;
-    }
-
-    int start() {
-        ALOGI("Executing hotlist setup request, num = %d", mParams.num_bssid);
-        WifiRequest request(familyId(), ifaceId());
-        int result = createSetupRequest(request);
-        if (result < 0) {
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result < 0) {
-            ALOGI("Failed to execute hotlist setup request, result = %d", result);
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
-            return result;
-        }
-
-        ALOGI("Successfully set %d APs in the hotlist ", mParams.num_bssid);
-        result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1);
-        if (result < 0) {
-            return result;
-        }
-
-        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
-        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
-
-        result = requestResponse(request);
-        if (result < 0) {
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
-            return result;
-        }
-
-        ALOGI("successfully restarted the scan");
-        return result;
-    }
-
-    virtual int cancel() {
-        /* unregister event handler */
-        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
-        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
-        /* create set hotlist message with empty hotlist */
-        WifiRequest request(familyId(), ifaceId());
-        int result = createTeardownRequest(request);
-        if (result < 0) {
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result < 0) {
-            return result;
-        }
-
-        ALOGI("Successfully reset APs in current hotlist");
-        return result;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        ALOGI("Hotlist AP event");
-        int event_id = event.get_vendor_subcmd();
-        // event.log();
-
-        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = event.get_vendor_data_len();
-
-        if (vendor_data == NULL || len == 0) {
-            ALOGI("No scan results found");
-            return NL_SKIP;
-        }
-
-        memset(mResults, 0, sizeof(wifi_scan_result) * MAX_RESULTS);
-
-        int num = len / sizeof(wifi_gscan_result_t);
-        wifi_gscan_result_t *inp = (wifi_gscan_result_t *)event.get_vendor_data();
-        num = min(MAX_RESULTS, num);
-        for (int i = 0; i < num; i++, inp++) {
-            convert_to_hal_result(&(mResults[i]), inp);
-        }
-
-        if (event_id == GSCAN_EVENT_HOTLIST_RESULTS_FOUND) {
-            ALOGI("FOUND %d hotlist APs", num);
-            if (*mHandler.on_hotlist_ap_found)
-                (*mHandler.on_hotlist_ap_found)(id(), num, mResults);
-        } else if (event_id == GSCAN_EVENT_HOTLIST_RESULTS_LOST) {
-            ALOGI("LOST %d hotlist APs", num);
-            if (*mHandler.on_hotlist_ap_lost)
-                (*mHandler.on_hotlist_ap_lost)(id(), num, mResults);
-        }
-        return NL_SKIP;
-    }
-};
-
-class ePNOCommand : public WifiCommand
-{
-private:
-    wifi_epno_params epno_params;
-    wifi_epno_handler mHandler;
-    wifi_scan_result mResults[MAX_EPNO_NETWORKS];
-public:
-    ePNOCommand(wifi_interface_handle handle, int id,
-            const wifi_epno_params *params, wifi_epno_handler handler)
-        : WifiCommand("ePNOCommand", handle, id), mHandler(handler)
-    {
-        if (params != NULL) {
-            memcpy(&epno_params, params, sizeof(wifi_epno_params));
-        } else {
-            memset(&epno_params, 0, sizeof(wifi_epno_params));
-        }
-    }
-    int createSetupRequest(WifiRequest& request) {
-        if (epno_params.num_networks > MAX_EPNO_NETWORKS) {
-            ALOGE("wrong epno num_networks:%d", epno_params.num_networks);
-            return WIFI_ERROR_INVALID_ARGS;
-        }
-        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_EPNO_SSID);
-        if (result < 0) {
-            return result;
-        }
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_FLUSH, 1);
-        if (result < 0) {
-            return result;
-        }
-
-        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR,
-                            (u8)epno_params.min5GHz_rssi);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR,
-                            (u8)epno_params.min24GHz_rssi);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX,
-                            epno_params.initial_score_max);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS,
-                            epno_params.current_connection_bonus);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS,
-                            epno_params.same_network_bonus);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS,
-                            epno_params.secure_bonus);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_5G_BONUS,
-                            epno_params.band5GHz_bonus);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_SSID_NUM,
-                        epno_params.num_networks);
-        if (result < 0) {
-            return result;
-        }
-        struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_EPNO_SSID_LIST);
-        wifi_epno_network *ssid_list = epno_params.networks;
-        for (int i = 0; i < epno_params.num_networks; i++) {
-            nlattr *attr2 = request.attr_start(i);
-            if (attr2 == NULL) {
-                return WIFI_ERROR_OUT_OF_MEMORY;
-            }
-            result = request.put(GSCAN_ATTRIBUTE_EPNO_SSID, ssid_list[i].ssid, DOT11_MAX_SSID_LEN);
-            ALOGI("PNO network: SSID %s flags %x auth %x", ssid_list[i].ssid,
-                ssid_list[i].flags,
-                ssid_list[i].auth_bit_field);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_SSID_LEN, strlen(ssid_list[i].ssid));
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_FLAGS, ssid_list[i].flags);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_AUTH, ssid_list[i].auth_bit_field);
-            if (result < 0) {
-                return result;
-            }
-            request.attr_end(attr2);
-        }
-        request.attr_end(attr);
-        request.attr_end(data);
-        return result;
-    }
-
-    int createTeardownRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_EPNO_SSID);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_FLUSH, 1);
-        if (result < 0) {
-            return result;
-        }
-        request.attr_end(data);
-        return result;
-    }
-
-    int start() {
-        ALOGI("Executing ePNO setup request, num = %d", epno_params.num_networks);
-        WifiRequest request(familyId(), ifaceId());
-        int result = createSetupRequest(request);
-        if (result < 0) {
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result < 0) {
-            ALOGI("Failed to execute ePNO setup request, result = %d", result);
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT);
-            return result;
-        }
-
-        ALOGI("Successfully set %d SSIDs for ePNO", epno_params.num_networks);
-        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT);
-        ALOGI("successfully restarted the scan");
-        return result;
-    }
-
-    virtual int cancel() {
-        /* unregister event handler */
-        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT);
-        /* create set hotlist message with empty hotlist */
-        WifiRequest request(familyId(), ifaceId());
-        int result = createTeardownRequest(request);
-        if (result < 0) {
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result < 0) {
-            return result;
-        }
-
-        ALOGI("Successfully reset APs in current hotlist");
-        return result;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        ALOGI("ePNO event");
-        int event_id = event.get_vendor_subcmd();
-        // event.log();
-
-        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = event.get_vendor_data_len();
-
-        if (vendor_data == NULL || len == 0) {
-            ALOGI("No scan results found");
-            return NL_SKIP;
-        }
-
-        memset(mResults, 0, sizeof(wifi_scan_result) * MAX_EPNO_NETWORKS);
-
-        unsigned int num = len / sizeof(wifi_pno_result_t);
-        unsigned int i;
-        num = min(MAX_EPNO_NETWORKS, num);
-        wifi_pno_result_t *res = (wifi_pno_result_t *) event.get_vendor_data();
-        for (i = 0; i < num; i++) {
-            if (res[i].flags == PNO_SSID_FOUND) {
-                memcpy(mResults[i].ssid, res[i].ssid, res[i].ssid_len);
-                memcpy(mResults[i].bssid, res[i].bssid, sizeof(mac_addr));
-
-                mResults[i].ssid[res[i].ssid_len] = '\0';
-                mResults[i].channel = res[i].channel;
-                mResults[i].rssi = res[i].rssi;
-            }
-        }
-        if (*mHandler.on_network_found)
-            (*mHandler.on_network_found)(id(), num, mResults);
-        return NL_SKIP;
-    }
-};
-
-wifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface,
-        wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler)
-{
-    wifi_handle handle = getWifiHandle(iface);
-
-    BssidHotlistCommand *cmd = new BssidHotlistCommand(iface, id, params, handler);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = wifi_register_cmd(handle, id, cmd);
-    if (result != WIFI_SUCCESS) {
-        cmd->releaseRef();
-        return result;
-    }
-    result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-        cmd->releaseRef();
-        return result;
-    }
-    return result;
-}
-
-wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface)
-{
-    return wifi_cancel_cmd(id, iface);
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-class SignificantWifiChangeCommand : public WifiCommand
-{
-    typedef struct {
-        mac_addr bssid;                     // BSSID
-        wifi_channel channel;               // channel frequency in MHz
-        int num_rssi;                       // number of rssi samples
-        wifi_rssi rssi[8];                   // RSSI history in db
-    } wifi_significant_change_result_internal;
-
-private:
-    wifi_significant_change_params mParams;
-    wifi_significant_change_handler mHandler;
-    static const int MAX_RESULTS = 64;
-    wifi_significant_change_result_internal mResultsBuffer[MAX_RESULTS];
-    wifi_significant_change_result *mResults[MAX_RESULTS];
-public:
-    SignificantWifiChangeCommand(wifi_interface_handle handle, int id,
-            wifi_significant_change_params params, wifi_significant_change_handler handler)
-        : WifiCommand("SignificantWifiChangeCommand", handle, id), mParams(params),
-            mHandler(handler)
-    { }
-
-    int createSetupRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u8(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u16(GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE, mParams.rssi_sample_size);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u16(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, mParams.lost_ap_sample_size);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u16(GSCAN_ATTRIBUTE_MIN_BREACHING, mParams.min_breaching);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u16(GSCAN_ATTRIBUTE_NUM_BSSID, mParams.num_bssid);
-        if (result < 0) {
-            return result;
-        }
-        if (mParams.num_bssid != 0) {
-            nlattr* attr = request.attr_start(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS);
-            if (attr == NULL) {
-                return WIFI_ERROR_OUT_OF_MEMORY;
-            }
-
-            for (int i = 0; i < mParams.num_bssid; i++) {
-                nlattr* attr2 = request.attr_start(i);
-                if (attr2 == NULL) {
-                    return WIFI_ERROR_OUT_OF_MEMORY;
-                }
-                result = request.put_addr(GSCAN_ATTRIBUTE_BSSID, mParams.ap[i].bssid);
-                if (result < 0) {
-                    return result;
-                }
-                result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH, mParams.ap[i].high);
-                if (result < 0) {
-                    return result;
-                }
-                result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW, mParams.ap[i].low);
-                if (result < 0) {
-                    return result;
-                }
-                request.attr_end(attr2);
-            }
-
-            request.attr_end(attr);
-        }
-        request.attr_end(data);
-
-        return result;
-    }
-
-    int createTeardownRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u16(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1);
-        if (result < 0) {
-            return result;
-        }
-
-        request.attr_end(data);
-        return result;
-    }
-
-    int start() {
-        ALOGI("Set significant wifi change config");
-        WifiRequest request(familyId(), ifaceId());
-
-        int result = createSetupRequest(request);
-        if (result < 0) {
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result < 0) {
-            ALOGI("failed to set significant wifi change config %d", result);
-            return result;
-        }
-
-        ALOGI("successfully set significant wifi change config");
-
-        result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1);
-        if (result < 0) {
-            return result;
-        }
-
-        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS);
-
-        result = requestResponse(request);
-        if (result < 0) {
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS);
-            return result;
-        }
-
-        ALOGI("successfully restarted the scan");
-        return result;
-    }
-
-    virtual int cancel() {
-        /* unregister event handler */
-        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS);
-
-        /* create set significant change monitor message with empty hotlist */
-        WifiRequest request(familyId(), ifaceId());
-
-        int result = createTeardownRequest(request);
-        if (result < 0) {
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result < 0) {
-            return result;
-        }
-
-        ALOGI("successfully reset significant wifi change config");
-        return result;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        ALOGV("Got a significant wifi change event");
-
-        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = event.get_vendor_data_len();
-
-        if (vendor_data == NULL || len == 0) {
-            ALOGI("No scan results found");
-            return NL_SKIP;
-        }
-
-        typedef struct {
-            uint16_t flags;
-            uint16_t channel;
-            mac_addr bssid;
-            s8 rssi_history[8];
-        } ChangeInfo;
-
-        int num = min(len / sizeof(ChangeInfo), MAX_RESULTS);
-        ChangeInfo *ci = (ChangeInfo *)event.get_vendor_data();
-
-        for (int i = 0; i < num; i++) {
-            memcpy(mResultsBuffer[i].bssid, ci[i].bssid, sizeof(mac_addr));
-            mResultsBuffer[i].channel = ci[i].channel;
-            mResultsBuffer[i].num_rssi = 8;
-            for (int j = 0; j < mResultsBuffer[i].num_rssi; j++)
-                mResultsBuffer[i].rssi[j] = (int) ci[i].rssi_history[j];
-            mResults[i] = reinterpret_cast<wifi_significant_change_result *>(&(mResultsBuffer[i]));
-        }
-
-        ALOGV("Retrieved %d scan results", num);
-
-        if (num != 0) {
-            (*mHandler.on_significant_change)(id(), num, mResults);
-        } else {
-            ALOGW("No significant change reported");
-        }
-
-        return NL_SKIP;
-    }
-};
-
-wifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interface_handle iface,
-        wifi_significant_change_params params, wifi_significant_change_handler handler)
-{
-    wifi_handle handle = getWifiHandle(iface);
-
-    SignificantWifiChangeCommand *cmd = new SignificantWifiChangeCommand(
-            iface, id, params, handler);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = wifi_register_cmd(handle, id, cmd);
-    if (result != WIFI_SUCCESS) {
-        cmd->releaseRef();
-        return result;
-    }
-    result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-        cmd->releaseRef();
-        return result;
-    }
-    return result;
-}
-
-wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface)
-{
-    return wifi_cancel_cmd(id, iface);
-}
-
-wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface)
-{
-    if (id == -1) {
-        wifi_epno_handler handler;
-        wifi_handle handle = getWifiHandle(iface);
-
-        memset(&handler, 0, sizeof(handler));
-        ePNOCommand *cmd = new ePNOCommand(iface, id, NULL, handler);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        cmd->cancel();
-        cmd->releaseRef();
-        return WIFI_SUCCESS;
-    }
-    return wifi_cancel_cmd(id, iface);
-}
-
-wifi_error wifi_set_epno_list(wifi_request_id id, wifi_interface_handle iface,
-        const wifi_epno_params *params, wifi_epno_handler handler)
-{
-    wifi_handle handle = getWifiHandle(iface);
-
-    ePNOCommand *cmd = new ePNOCommand(iface, id, params, handler);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = wifi_register_cmd(handle, id, cmd);
-    if (result != WIFI_SUCCESS) {
-        cmd->releaseRef();
-        return result;
-    }
-    result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-        cmd->releaseRef();
-        return result;
-    }
-    return result;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-class AnqpoConfigureCommand : public WifiCommand
-{
-    int num_hs;
-    wifi_passpoint_network *mNetworks;
-    wifi_passpoint_event_handler mHandler;
-    wifi_scan_result *mResult;
-public:
-    AnqpoConfigureCommand(wifi_request_id id, wifi_interface_handle iface,
-        int num, wifi_passpoint_network *hs_list, wifi_passpoint_event_handler handler)
-        : WifiCommand("AnqpoConfigureCommand", iface, id), num_hs(num), mNetworks(hs_list),
-            mHandler(handler)
-    {
-        mResult = NULL;
-    }
-
-    int createRequest(WifiRequest& request, int val) {
-
-        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_ANQPO_CONFIG);
-        result = request.put_u32(GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE, num_hs);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-
-        struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_ANQPO_HS_LIST);
-        for (int i = 0; i < num_hs; i++) {
-            nlattr *attr2 = request.attr_start(i);
-            if (attr2 == NULL) {
-                return WIFI_ERROR_OUT_OF_MEMORY;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID, mNetworks[i].id);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM, mNetworks[i].realm, 256);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID,
-                         mNetworks[i].roamingConsortiumIds, 128);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_PLMN, mNetworks[i].plmn, 3);
-            if (result < 0) {
-                return result;
-            }
-
-            request.attr_end(attr2);
-        }
-
-        request.attr_end(attr);
-        request.attr_end(data);
-
-        return WIFI_SUCCESS;
-    }
-
-    int start() {
-
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request, num_hs);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create request; result = %d", result);
-            return result;
-        }
-
-        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH);
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to set ANQPO networks; result = %d", result);
-            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH);
-            return result;
-        }
-
-        return result;
-    }
-
-    virtual int cancel() {
-
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request, 0);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create request; result = %d", result);
-        } else {
-            result = requestResponse(request);
-            if (result != WIFI_SUCCESS) {
-                ALOGE("failed to reset ANQPO networks;result = %d", result);
-            }
-        }
-
-        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH);
-        return WIFI_SUCCESS;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-         ALOGD("Request complete!");
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        typedef struct {
-            u16 channel;        /* channel of GAS protocol */
-            u8  dialog_token;   /* GAS dialog token */
-            u8  fragment_id;    /* fragment id */
-            u16 status_code;    /* status code on GAS completion */
-            u16 data_len;       /* length of data to follow */
-            u8  data[1];        /* variable length specified by data_len */
-        } wifi_anqp_gas_resp;
-
-        ALOGI("ANQPO hotspot matched event!");
-
-        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        unsigned int len = event.get_vendor_data_len();
-
-        if (vendor_data == NULL || len < sizeof(wifi_scan_result)) {
-            ALOGI("No scan results found");
-            return NL_SKIP;
-        }
-        mResult = (wifi_scan_result *)malloc(sizeof(wifi_scan_result));
-        if (!mResult) {
-            return NL_SKIP;
-        }
-        wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data();
-        wifi_gscan_result_t *fixed = &drv_res->fixed;
-        convert_to_hal_result(mResult, fixed);
-
-        byte *anqp = (byte *)drv_res + offsetof(wifi_gscan_full_result_t, ie_data) + drv_res->ie_length;
-        wifi_anqp_gas_resp *gas = (wifi_anqp_gas_resp *)anqp;
-        int anqp_len = offsetof(wifi_anqp_gas_resp, data) + gas->data_len;
-        int networkId = *(int *)((byte *)anqp + anqp_len);
-
-        ALOGI("%-32s\t", mResult->ssid);
-
-        ALOGI("%02x:%02x:%02x:%02x:%02x:%02x ", mResult->bssid[0], mResult->bssid[1],
-                mResult->bssid[2], mResult->bssid[3], mResult->bssid[4], mResult->bssid[5]);
-
-        ALOGI("%d\t", mResult->rssi);
-        ALOGI("%d\t", mResult->channel);
-        ALOGI("%lld\t", mResult->ts);
-        ALOGI("%lld\t", mResult->rtt);
-        ALOGI("%lld\n", mResult->rtt_sd);
-
-        if(*mHandler.on_passpoint_network_found)
-            (*mHandler.on_passpoint_network_found)(id(), networkId, mResult, anqp_len, anqp);
-        free(mResult);
-        return NL_SKIP;
-    }
-};
-
-wifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_interface_handle iface, int num,
-        wifi_passpoint_network *networks, wifi_passpoint_event_handler handler)
-{
-    wifi_handle handle = getWifiHandle(iface);
-
-    AnqpoConfigureCommand *cmd = new AnqpoConfigureCommand(id, iface, num, networks, handler);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = wifi_register_cmd(handle, id, cmd);
-    if (result != WIFI_SUCCESS) {
-        cmd->releaseRef();
-        return result;
-    }
-    result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-        cmd->releaseRef();
-        return result;
-    }
-    return result;
-}
-
-wifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle iface)
-{
-    return wifi_cancel_cmd(id, iface);
-}
diff --git a/wlan/wifi_hal/link_layer_stats.cpp b/wlan/wifi_hal/link_layer_stats.cpp
deleted file mode 100644 (file)
index 31e43e6..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/rtnetlink.h>
-#include <netpacket/packet.h>
-#include <linux/filter.h>
-#include <linux/errqueue.h>
-
-#include <linux/pkt_sched.h>
-#include <netlink/object-api.h>
-#include <netlink/netlink.h>
-#include <netlink/socket.h>
-#include <netlink/handlers.h>
-
-#include "sync.h"
-
-#define LOG_TAG  "WifiHAL"
-
-#include <utils/Log.h>
-
-#include "wifi_hal.h"
-#include "common.h"
-#include "cpp_bindings.h"
-
-/* Internal radio statistics structure in the driver */
-typedef struct {
-       wifi_radio radio;
-       uint32_t on_time;
-       uint32_t tx_time;
-       uint32_t rx_time;
-       uint32_t on_time_scan;
-       uint32_t on_time_nbd;
-       uint32_t on_time_gscan;
-       uint32_t on_time_roam_scan;
-       uint32_t on_time_pno_scan;
-       uint32_t on_time_hs20;
-       uint32_t num_channels;
-       wifi_channel_stat channels[];
-} wifi_radio_stat_internal;
-
-enum {
-    LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START,
-       LSTATS_SUBCMD_SET_INFO,
-       LSTATS_SUBCMD_CLEAR_INFO,
-};
-
-class GetLinkStatsCommand : public WifiCommand
-{
-    wifi_stats_result_handler mHandler;
-public:
-    GetLinkStatsCommand(wifi_interface_handle iface, wifi_stats_result_handler handler)
-        : WifiCommand("GetLinkStatsCommand", iface, 0), mHandler(handler)
-    { }
-
-    virtual int create() {
-        // ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
-
-        int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_GET_INFO);
-        if (ret < 0) {
-            ALOGE("Failed to create %x - %d", LSTATS_SUBCMD_GET_INFO, ret);
-            return ret;
-        }
-
-        return ret;
-    }
-
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-
-        // ALOGI("In GetLinkStatsCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-
-        // ALOGI("Id = %0x, subcmd = %d", id, subcmd);
-
-        void *data = reply.get_vendor_data();
-        int len = reply.get_vendor_data_len();
-        wifi_radio_stat *radio_stat = (wifi_radio_stat *)data;
-               ALOGE("radio: = %d", radio_stat->radio);
-        ALOGE("on_time: = %u ms", radio_stat->on_time);
-        ALOGE("tx_time: = %u ms", radio_stat->tx_time);
-               ALOGE("num_tx_levels: = %u", radio_stat->num_tx_levels);
-               radio_stat->tx_time_per_levels = (u32*)((char*)data + sizeof(wifi_radio_stat) + sizeof(wifi_iface_stat));
-               ALOGE("tx_time_per_levels: = %u ms", radio_stat->tx_time_per_levels[0]);
-        ALOGE("rx_time: = %u ms", radio_stat->rx_time);
-        ALOGE("on_time_scan: = %u ms", radio_stat->on_time_scan);
-        ALOGE("on_time_nbd: = %u ms", radio_stat->on_time_nbd);
-        ALOGE("on_time_gscan: = %u ms", radio_stat->on_time_gscan);
-        ALOGE("on_time_pno_scan: = %u ms", radio_stat->on_time_pno_scan);
-        ALOGE("on_time_hs20: = %u ms", radio_stat->on_time_hs20);
-        if (!radio_stat) {
-            ALOGE("Invalid stats pointer received");
-            return NL_SKIP;
-        }
-        if (radio_stat->num_channels > 11) {
-            ALOGE("Incorrect number of channels = %d", radio_stat->num_channels);
-            // dump data before num_channels
-            ALOGE("radio: = %d", radio_stat->radio);
-            ALOGE("on_time: = %u ms", radio_stat->on_time);
-            ALOGE("tx_time: = %u ms", radio_stat->tx_time);
-            ALOGE("rx_time: = %u ms", radio_stat->rx_time);
-            ALOGE("on_time_scan: = %u ms", radio_stat->on_time_scan);
-            ALOGE("on_time_nbd: = %u ms", radio_stat->on_time_nbd);
-            ALOGE("on_time_gscan: = %u ms", radio_stat->on_time_gscan);
-            ALOGE("on_time_pno_scan: = %u ms", radio_stat->on_time_pno_scan);
-            ALOGE("on_time_hs20: = %u ms", radio_stat->on_time_hs20);
-            free(radio_stat);
-            return NL_SKIP;
-        }
-               wifi_iface_stat *iface_stat = NULL;
-               iface_stat = (wifi_iface_stat *)((char* )data + sizeof(wifi_radio_stat));
-
-               if(*mHandler.on_link_stats_results == NULL) {
-                       ALOGE("*mHandler.on_link_stats_results is NULL");
-               } else {
-               (*mHandler.on_link_stats_results)(id, iface_stat, 1, radio_stat);
-               }
-        //free(radio_stat);
-        return NL_OK;
-    }
-
-};
-
-class SetLinkStatsCommand : public WifiCommand
-{
-    wifi_stats_result_handler mHandler;
-public:
-    SetLinkStatsCommand(wifi_interface_handle iface)
-        : WifiCommand("SetLinkStatsCommand", iface, 0)
-    { }
-
-    virtual int create() {
-        // ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
-
-        int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_SET_INFO);
-        if (ret < 0) {
-            ALOGE("Failed to create %x - %d", LSTATS_SUBCMD_SET_INFO, ret);
-            return ret;
-        }
-
-        return ret;
-    }
-
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-
-        // ALOGI("In GetLinkStatsCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-
-        // ALOGI("Id = %0x, subcmd = %d", id, subcmd);
-
-        void *data = reply.get_vendor_data();
-        int len = reply.get_vendor_data_len();
-         return NL_OK;
-    }
-
-};
-
-class ClearLinkStatsCommand : public WifiCommand
-{
-    wifi_stats_result_handler mHandler;
-public:
-    ClearLinkStatsCommand(wifi_interface_handle iface)
-        : WifiCommand("ClearLinkStatsCommand", iface, 0)
-    { }
-
-    virtual int create() {
-        // ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
-
-        int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_CLEAR_INFO);
-        if (ret < 0) {
-            ALOGE("Failed to create %x - %d", LSTATS_SUBCMD_CLEAR_INFO, ret);
-            return ret;
-        }
-
-        return ret;
-    }
-
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-
-        // ALOGI("In GetLinkStatsCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-
-        // ALOGI("Id = %0x, subcmd = %d", id, subcmd);
-
-        void *data = reply.get_vendor_data();
-        int len = reply.get_vendor_data_len();
-         return NL_OK;
-    }
-
-};
-
-wifi_error wifi_get_link_stats(wifi_request_id id,
-        wifi_interface_handle iface, wifi_stats_result_handler handler)
-{
-    GetLinkStatsCommand command(iface, handler);
-    return (wifi_error) command.requestResponse();
-}
-
-wifi_error wifi_set_link_stats(
-        wifi_interface_handle iface, wifi_link_layer_params params)
-{
-    
-       SetLinkStatsCommand command(iface);
-    return (wifi_error) command.requestResponse();
-    //return WIFI_SUCCESS;
-}
-
-wifi_error wifi_clear_link_stats(wifi_interface_handle iface,
-      u32 stats_clear_req_mask, u32 *stats_clear_rsp_mask, u8 stop_req, u8 *stop_rsp)
-{
-    
-       ClearLinkStatsCommand command(iface);
-    return (wifi_error) command.requestResponse();
-    //return WIFI_SUCCESS;
-}
diff --git a/wlan/wifi_hal/rtt.cpp b/wlan/wifi_hal/rtt.cpp
deleted file mode 100644 (file)
index 048f339..0000000
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/rtnetlink.h>
-#include <netpacket/packet.h>
-#include <linux/filter.h>
-#include <linux/errqueue.h>
-
-#include <linux/pkt_sched.h>
-#include <netlink/object-api.h>
-#include <netlink/netlink.h>
-#include <netlink/socket.h>
-#include <netlink-private/object-api.h>
-#include <netlink-private/types.h>
-
-#include "nl80211_copy.h"
-
-#include "sync.h"
-
-#define LOG_TAG  "WifiHAL"
-
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "wifi_hal.h"
-#include "common.h"
-#include "cpp_bindings.h"
-
-using namespace android;
-#define RTT_RESULT_SIZE (sizeof(wifi_rtt_result));
-typedef enum {
-
-    RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
-    RTT_SUBCMD_CANCEL_CONFIG,
-    RTT_SUBCMD_GETCAPABILITY,
-    RTT_SUBCMD_GETAVAILCHANNEL,
-    RTT_SUBCMD_SET_RESPONDER,
-    RTT_SUBCMD_CANCEL_RESPONDER,
-} RTT_SUB_COMMAND;
-
-typedef enum {
-    RTT_ATTRIBUTE_TARGET_CNT = 0,
-    RTT_ATTRIBUTE_TARGET_INFO,
-    RTT_ATTRIBUTE_TARGET_MAC,
-    RTT_ATTRIBUTE_TARGET_TYPE,
-    RTT_ATTRIBUTE_TARGET_PEER,
-    RTT_ATTRIBUTE_TARGET_CHAN,
-    RTT_ATTRIBUTE_TARGET_PERIOD,
-    RTT_ATTRIBUTE_TARGET_NUM_BURST,
-    RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
-    RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
-    RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
-    RTT_ATTRIBUTE_TARGET_LCI,
-    RTT_ATTRIBUTE_TARGET_LCR,
-    RTT_ATTRIBUTE_TARGET_BURST_DURATION,
-    RTT_ATTRIBUTE_TARGET_PREAMBLE,
-    RTT_ATTRIBUTE_TARGET_BW,
-    RTT_ATTRIBUTE_RESULTS_COMPLETE = 30,
-    RTT_ATTRIBUTE_RESULTS_PER_TARGET,
-    RTT_ATTRIBUTE_RESULT_CNT,
-    RTT_ATTRIBUTE_RESULT
-} RTT_ATTRIBUTE;
-typedef struct strmap_entry {
-    int                        id;
-    String8            text;
-} strmap_entry_t;
-struct dot11_rm_ie {
-    u8 id;
-    u8 len;
-    u8 token;
-    u8 mode;
-    u8 type;
-} __attribute__ ((packed));
-typedef struct dot11_rm_ie dot11_rm_ie_t;
-#define DOT11_HDR_LEN 2
-#define DOT11_RM_IE_LEN       5
-#define DOT11_MNG_MEASURE_REQUEST_ID           38      /* 11H MeasurementRequest */
-#define DOT11_MEASURE_TYPE_LCI         8   /* d11 measurement LCI type */
-#define DOT11_MEASURE_TYPE_CIVICLOC    11  /* d11 measurement location civic */
-
-static const strmap_entry_t err_info[] = {
-    {RTT_STATUS_SUCCESS, String8("Success")},
-    {RTT_STATUS_FAILURE, String8("Failure")},
-    {RTT_STATUS_FAIL_NO_RSP, String8("No reponse")},
-    {RTT_STATUS_FAIL_INVALID_TS, String8("Invalid Timestamp")},
-    {RTT_STATUS_FAIL_PROTOCOL, String8("Protocol error")},
-    {RTT_STATUS_FAIL_REJECTED, String8("Rejected")},
-    {RTT_STATUS_FAIL_NOT_SCHEDULED_YET, String8("not scheduled")},
-    {RTT_STATUS_FAIL_SCHEDULE,  String8("schedule failed")},
-    {RTT_STATUS_FAIL_TM_TIMEOUT, String8("timeout")},
-    {RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, String8("AP is on difference channel")},
-    {RTT_STATUS_FAIL_NO_CAPABILITY, String8("no capability")},
-    {RTT_STATUS_FAIL_BUSY_TRY_LATER, String8("busy and try later")},
-    {RTT_STATUS_ABORTED, String8("aborted")}
-};
-
-    static const char*
-get_err_info(int status)
-{
-    int i;
-    const strmap_entry_t *p_entry;
-    int num_entries = sizeof(err_info)/ sizeof(err_info[0]);
-    /* scan thru the table till end */
-    p_entry = err_info;
-    for (i = 0; i < (int) num_entries; i++)
-    {
-        if (p_entry->id == status)
-            return p_entry->text;
-        p_entry++;             /* next entry */
-    }
-    return "unknown error";                    /* not found */
-}
-
-class GetRttCapabilitiesCommand : public WifiCommand
-{
-    wifi_rtt_capabilities *mCapabilities;
-public:
-    GetRttCapabilitiesCommand(wifi_interface_handle iface, wifi_rtt_capabilities *capabitlites)
-        : WifiCommand("GetRttCapabilitiesCommand", iface, 0), mCapabilities(capabitlites)
-    {
-        memset(mCapabilities, 0, sizeof(*mCapabilities));
-    }
-
-    virtual int create() {
-        ALOGD("Creating message to get scan capablities; iface = %d", mIfaceInfo->id);
-
-        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETCAPABILITY);
-        if (ret < 0) {
-            return ret;
-        }
-
-        return ret;
-    }
-
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-
-        ALOGD("In GetRttCapabilitiesCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-
-        void *data = reply.get_vendor_data();
-        int len = reply.get_vendor_data_len();
-
-        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
-                sizeof(*mCapabilities));
-
-        memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities)));
-
-        return NL_OK;
-    }
-};
-
-
-class GetRttResponderInfoCommand : public WifiCommand
-{
-    wifi_rtt_responder* mResponderInfo;
-public:
-    GetRttResponderInfoCommand(wifi_interface_handle iface, wifi_rtt_responder *responderInfo)
-        : WifiCommand("GetRttResponderInfoCommand", iface, 0), mResponderInfo(responderInfo)
-    {
-        memset(mResponderInfo, 0 , sizeof(*mResponderInfo));
-
-    }
-
-    virtual int create() {
-        ALOGD("Creating message to get responder info ; iface = %d", mIfaceInfo->id);
-
-        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETAVAILCHANNEL);
-        if (ret < 0) {
-            return ret;
-        }
-
-        return ret;
-    }
-
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-
-        ALOGD("In GetRttResponderInfoCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-
-        void *data = reply.get_vendor_data();
-        int len = reply.get_vendor_data_len();
-
-        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
-                sizeof(*mResponderInfo));
-
-        memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
-
-        return NL_OK;
-    }
-};
-
-
-class EnableResponderCommand : public WifiCommand
-{
-    wifi_channel_info  mChannelInfo;
-    wifi_rtt_responder* mResponderInfo;
-    unsigned m_max_duration_sec;
-public:
-    EnableResponderCommand(wifi_interface_handle iface, int id, wifi_channel_info channel_hint,
-            unsigned max_duration_seconds, wifi_rtt_responder *responderInfo)
-            : WifiCommand("EnableResponderCommand", iface, 0), mChannelInfo(channel_hint),
-            m_max_duration_sec(max_duration_seconds), mResponderInfo(responderInfo)
-    {
-        memset(mResponderInfo, 0, sizeof(*mResponderInfo));
-    }
-
-    virtual int create() {
-        ALOGD("Creating message to set responder ; iface = %d", mIfaceInfo->id);
-
-        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_SET_RESPONDER);
-        if (ret < 0) {
-            return ret;
-        }
-
-        return ret;
-    }
-
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-
-        ALOGD("In EnableResponderCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-
-        void *data = reply.get_vendor_data();
-        int len = reply.get_vendor_data_len();
-
-        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
-                sizeof(*mResponderInfo));
-
-        memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
-
-        return NL_OK;
-    }
-};
-
-
-class CancelResponderCommand : public WifiCommand
-{
-
-public:
-    CancelResponderCommand(wifi_interface_handle iface, int id)
-        : WifiCommand("CancelResponderCommand", iface, 0)/*, mChannelInfo(channel)*/
-    {
-
-    }
-
-    virtual int create() {
-        ALOGD("Creating message to cancel responder ; iface = %d", mIfaceInfo->id);
-
-        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_RESPONDER);
-        if (ret < 0) {
-            return ret;
-        }
-
-        return ret;
-    }
-
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-};
-
-
-class RttCommand : public WifiCommand
-{
-    unsigned numRttParams;
-    int mCompleted;
-    int currentIdx;
-    int totalCnt;
-    static const int MAX_RESULTS = 1024;
-    wifi_rtt_result *rttResults[MAX_RESULTS];
-    wifi_rtt_config *rttParams;
-    wifi_rtt_event_handler rttHandler;
-public:
-    RttCommand(wifi_interface_handle iface, int id, unsigned num_rtt_config,
-            wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
-        : WifiCommand("RttCommand", iface, id), numRttParams(num_rtt_config), rttParams(rtt_config),
-        rttHandler(handler)
-    {
-        memset(rttResults, 0, sizeof(rttResults));
-        currentIdx = 0;
-        mCompleted = 0;
-        totalCnt = 0;
-    }
-
-    RttCommand(wifi_interface_handle iface, int id)
-        : WifiCommand("RttCommand", iface, id)
-    {
-        currentIdx = 0;
-        mCompleted = 0;
-        totalCnt = 0;
-        numRttParams = 0;
-    }
-
-    int createSetupRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, RTT_SUBCMD_SET_CONFIG);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, numRttParams);
-        if (result < 0) {
-            return result;
-        }
-        nlattr *rtt_config = request.attr_start(RTT_ATTRIBUTE_TARGET_INFO);
-        for (unsigned i = 0; i < numRttParams; i++) {
-            nlattr *attr2 = request.attr_start(i);
-            if (attr2 == NULL) {
-                return WIFI_ERROR_OUT_OF_MEMORY;
-            }
-
-            result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, rttParams[i].addr);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u8(RTT_ATTRIBUTE_TARGET_TYPE, rttParams[i].type);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u8(RTT_ATTRIBUTE_TARGET_PEER, rttParams[i].peer);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put(RTT_ATTRIBUTE_TARGET_CHAN, &rttParams[i].channel,
-                    sizeof(wifi_channel_info));
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_BURST, rttParams[i].num_burst);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
-                    rttParams[i].num_frames_per_burst);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
-                    rttParams[i].num_retries_per_rtt_frame);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
-                    rttParams[i].num_retries_per_ftmr);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u32(RTT_ATTRIBUTE_TARGET_PERIOD,
-                    rttParams[i].burst_period);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u32(RTT_ATTRIBUTE_TARGET_BURST_DURATION,
-                    rttParams[i].burst_duration);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCI,
-                    rttParams[i].LCI_request);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCR,
-                    rttParams[i].LCR_request);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u8(RTT_ATTRIBUTE_TARGET_BW,
-                    rttParams[i].bw);
-            if (result < 0) {
-                return result;
-            }
-
-            result = request.put_u8(RTT_ATTRIBUTE_TARGET_PREAMBLE,
-                    rttParams[i].preamble);
-            if (result < 0) {
-                return result;
-            }
-            request.attr_end(attr2);
-        }
-
-        request.attr_end(rtt_config);
-        request.attr_end(data);
-        return WIFI_SUCCESS;
-    }
-
-    int createTeardownRequest(WifiRequest& request, unsigned num_devices, mac_addr addr[]) {
-        int result = request.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_CONFIG);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, num_devices);
-        for(unsigned i = 0; i < num_devices; i++) {
-            result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, addr[i]);
-            if (result < 0) {
-                return result;
-            }
-        }
-        request.attr_end(data);
-        return result;
-    }
-    int start() {
-        ALOGD("Setting RTT configuration");
-        WifiRequest request(familyId(), ifaceId());
-        int result = createSetupRequest(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create setup request; result = %d", result);
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to configure RTT setup; result = %d", result);
-            return result;
-        }
-
-        registerVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
-        ALOGI("Successfully started RTT operation");
-        return result;
-    }
-
-    virtual int cancel() {
-        ALOGD("Stopping RTT");
-
-        WifiRequest request(familyId(), ifaceId());
-        int result = createTeardownRequest(request, 0, NULL);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create stop request; result = %d", result);
-        } else {
-            result = requestResponse(request);
-            if (result != WIFI_SUCCESS) {
-                ALOGE("failed to stop scan; result = %d", result);
-            }
-        }
-
-        unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
-        return WIFI_SUCCESS;
-    }
-
-    int cancel_specific(unsigned num_devices, mac_addr addr[]) {
-        ALOGE("Stopping RTT");
-
-        WifiRequest request(familyId(), ifaceId());
-        int result = createTeardownRequest(request, num_devices, addr);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create stop request; result = %d", result);
-        } else {
-            result = requestResponse(request);
-            if (result != WIFI_SUCCESS) {
-                ALOGE("failed to stop RTT; result = %d", result);
-            }
-        }
-
-        unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
-        return WIFI_SUCCESS;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        ALOGI("Got an RTT event");
-        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = event.get_vendor_data_len();
-        if (vendor_data == NULL || len == 0) {
-            ALOGI("No rtt results found");
-        }
-        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
-            if (it.get_type() == RTT_ATTRIBUTE_RESULTS_COMPLETE) {
-                mCompleted = it.get_u32();
-                ALOGI("retrieved completed flag : %d\n", mCompleted);
-            } else if (it.get_type() == RTT_ATTRIBUTE_RESULTS_PER_TARGET) {
-                int result_cnt = 0;
-                mac_addr bssid;
-                for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
-                    if (it2.get_type() == RTT_ATTRIBUTE_TARGET_MAC) {
-                        memcpy(bssid, it2.get_data(), sizeof(mac_addr));
-                        ALOGI("retrived target mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
-                                bssid[0],
-                                bssid[1],
-                                bssid[2],
-                                bssid[3],
-                                bssid[4],
-                                bssid[5]);
-                    } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_CNT) {
-                        result_cnt = it2.get_u32();
-                        ALOGI("retrieved result_cnt : %d\n", result_cnt);
-                    } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT) {
-                        int result_len = it2.get_len();
-                        rttResults[currentIdx] =  (wifi_rtt_result *)malloc(it2.get_len());
-                        wifi_rtt_result *rtt_result = rttResults[currentIdx];
-                        if (rtt_result == NULL) {
-                            mCompleted = 1;
-                            ALOGE("failed to allocate the wifi_rtt_result\n");
-                            break;
-                        }
-                        memcpy(rtt_result, it2.get_data(), it2.get_len());
-                        result_len -= sizeof(wifi_rtt_result);
-                        if (result_len > 0) {
-                            result_len -= sizeof(wifi_rtt_result);
-                            dot11_rm_ie_t *ele_1;
-                            dot11_rm_ie_t *ele_2;
-                            /* The result has LCI or LCR element */
-                            ele_1 = (dot11_rm_ie_t *)(rtt_result + 1);
-                            if (ele_1->id == DOT11_MNG_MEASURE_REQUEST_ID) {
-                                if (ele_1->type == DOT11_MEASURE_TYPE_LCI) {
-                                    rtt_result->LCI = (wifi_information_element *)ele_1;
-                                    result_len -= (ele_1->len + DOT11_HDR_LEN);
-                                    /* get a next rm ie */
-                                    if (result_len > 0) {
-                                        ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN));
-                                        if ((ele_2->id == DOT11_MNG_MEASURE_REQUEST_ID) &&
-                                                (ele_2->type == DOT11_MEASURE_TYPE_CIVICLOC)) {
-                                            rtt_result->LCR = (wifi_information_element *)ele_2;
-                                        }
-                                    }
-                                } else if (ele_1->type == DOT11_MEASURE_TYPE_CIVICLOC){
-                                    rtt_result->LCR = (wifi_information_element *)ele_1;
-                                    result_len -= (ele_1->len + DOT11_HDR_LEN);
-                                    /* get a next rm ie */
-                                    if (result_len > 0) {
-                                        ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN));
-                                        if ((ele_2->id == DOT11_MNG_MEASURE_REQUEST_ID) &&
-                                                (ele_2->type == DOT11_MEASURE_TYPE_LCI)) {
-                                            rtt_result->LCI = (wifi_information_element *)ele_2;
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                        totalCnt++;
-                        ALOGI("retrived rtt_result : \n\tburst_num :%d, measurement_number : %d, success_number : %d\n"
-                                "\tnumber_per_burst_peer : %d, status : %s, retry_after_duration : %d s\n"
-                                "\trssi : %d dbm, rx_rate : %d Kbps, rtt : %llu ns, rtt_sd : %llu\n"
-                                "\tdistance : %d, burst_duration : %d ms, negotiated_burst_num : %d\n",
-                                rtt_result->burst_num, rtt_result->measurement_number,
-                                rtt_result->success_number, rtt_result->number_per_burst_peer,
-                                get_err_info(rtt_result->status), rtt_result->retry_after_duration,
-                                rtt_result->rssi, rtt_result->rx_rate.bitrate * 100,
-                                rtt_result->rtt/10, rtt_result->rtt_sd, rtt_result->distance_mm / 10,
-                                rtt_result->burst_duration, rtt_result->negotiated_burst_num);
-                        currentIdx++;
-                    }
-                }
-            }
-
-        }
-        if (mCompleted) {
-            unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
-            (*rttHandler.on_rtt_results)(id(), totalCnt, rttResults);
-            for (int i = 0; i < currentIdx; i++) {
-                free(rttResults[i]);
-                rttResults[i] = NULL;
-            }
-            totalCnt = currentIdx = 0;
-            WifiCommand *cmd = wifi_unregister_cmd(wifiHandle(), id());
-            if (cmd)
-                cmd->releaseRef();
-        }
-        return NL_SKIP;
-    }
-};
-
-
-/* API to request RTT measurement */
-wifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle iface,
-        unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
-{
-    wifi_handle handle = getWifiHandle(iface);
-    RttCommand *cmd = new RttCommand(iface, id, num_rtt_config, rtt_config, handler);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = wifi_register_cmd(handle, id, cmd);
-    if (result != WIFI_SUCCESS) {
-        cmd->releaseRef();
-        return result;
-    }
-    result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-        cmd->releaseRef();
-        return result;
-    }
-    return result;
-}
-
-/* API to cancel RTT measurements */
-wifi_error wifi_rtt_range_cancel(wifi_request_id id,  wifi_interface_handle iface,
-        unsigned num_devices, mac_addr addr[])
-{
-    wifi_handle handle = getWifiHandle(iface);
-    RttCommand *cmd = new RttCommand(iface, id);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    cmd->cancel_specific(num_devices, addr);
-    cmd->releaseRef();
-    return WIFI_SUCCESS;
-}
-
-/* API to get RTT capability */
-wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
-        wifi_rtt_capabilities *capabilities)
-{
-    GetRttCapabilitiesCommand command(iface, capabilities);
-    return (wifi_error) command.requestResponse();
-}
-
-/* API to get the responder information */
-wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
-        wifi_rtt_responder* responderInfo)
-{
-    GetRttResponderInfoCommand command(iface, responderInfo);
-    return (wifi_error) command.requestResponse();
-
-}
-
-/**
- * Enable RTT responder mode.
- * channel_hint - hint of the channel information where RTT responder should be enabled on.
- * max_duration_seconds - timeout of responder mode.
- * wifi_rtt_responder - information for RTT responder e.g. channel used and preamble supported.
- */
-wifi_error wifi_enable_responder(wifi_request_id id, wifi_interface_handle iface,
-                                wifi_channel_info channel_hint, unsigned max_duration_seconds,
-                                wifi_rtt_responder* responderInfo)
-{
-    EnableResponderCommand command(iface, id, channel_hint, max_duration_seconds, responderInfo);
-    return (wifi_error) command.requestResponse();
-}
-
-/**
- * Disable RTT responder mode.
- */
-wifi_error wifi_disable_responder(wifi_request_id id, wifi_interface_handle iface)
-{
-    CancelResponderCommand command(iface, id);
-    return (wifi_error) command.requestResponse();
-}
-
diff --git a/wlan/wifi_hal/rtw_wifi_gscan.cpp b/wlan/wifi_hal/rtw_wifi_gscan.cpp
new file mode 100644 (file)
index 0000000..10b588a
--- /dev/null
@@ -0,0 +1,1856 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink/handlers.h>
+
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL"
+//#define LOG_NDEBUG 0         //uncomment to enable verbose logging
+
+#include <log/log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+typedef enum {
+
+    GSCAN_ATTRIBUTE_NUM_BUCKETS = 10,
+    GSCAN_ATTRIBUTE_BASE_PERIOD,
+    GSCAN_ATTRIBUTE_BUCKETS_BAND,
+    GSCAN_ATTRIBUTE_BUCKET_ID,
+    GSCAN_ATTRIBUTE_BUCKET_PERIOD,
+    GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS,
+    GSCAN_ATTRIBUTE_BUCKET_CHANNELS,
+    GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN,
+    GSCAN_ATTRIBUTE_REPORT_THRESHOLD,
+    GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE,
+    GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND,
+
+    GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20,
+    GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE,              /* indicates no more results */
+    GSCAN_ATTRIBUTE_FLUSH_FEATURE,                      /* Flush all the configs */
+    GSCAN_ENABLE_FULL_SCAN_RESULTS,
+    GSCAN_ATTRIBUTE_REPORT_EVENTS,
+
+    /* remaining reserved for additional attributes */
+    GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30,
+    GSCAN_ATTRIBUTE_FLUSH_RESULTS,
+    GSCAN_ATTRIBUTE_SCAN_RESULTS,                       /* flat array of wifi_scan_result */
+    GSCAN_ATTRIBUTE_SCAN_ID,                            /* indicates scan number */
+    GSCAN_ATTRIBUTE_SCAN_FLAGS,                         /* indicates if scan was aborted */
+    GSCAN_ATTRIBUTE_AP_FLAGS,                           /* flags on significant change event */
+    GSCAN_ATTRIBUTE_NUM_CHANNELS,
+    GSCAN_ATTRIBUTE_CHANNEL_LIST,
+    GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK,
+    /* remaining reserved for additional attributes */
+
+    GSCAN_ATTRIBUTE_SSID = 40,
+    GSCAN_ATTRIBUTE_BSSID,
+    GSCAN_ATTRIBUTE_CHANNEL,
+    GSCAN_ATTRIBUTE_RSSI,
+    GSCAN_ATTRIBUTE_TIMESTAMP,
+    GSCAN_ATTRIBUTE_RTT,
+    GSCAN_ATTRIBUTE_RTTSD,
+
+    /* remaining reserved for additional attributes */
+
+    GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50,
+    GSCAN_ATTRIBUTE_RSSI_LOW,
+    GSCAN_ATTRIBUTE_RSSI_HIGH,
+    GSCAN_ATTRIBUTE_HOTLIST_ELEM,
+    GSCAN_ATTRIBUTE_HOTLIST_FLUSH,
+    GSCAN_ATTRIBUTE_HOTLIST_BSSID_COUNT,
+
+    /* remaining reserved for additional attributes */
+    GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60,
+    GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE,
+    GSCAN_ATTRIBUTE_MIN_BREACHING,
+    GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS,
+    GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH,
+
+    /* EPNO */
+    GSCAN_ATTRIBUTE_EPNO_SSID_LIST = 70,
+    GSCAN_ATTRIBUTE_EPNO_SSID,
+    GSCAN_ATTRIBUTE_EPNO_SSID_LEN,
+    GSCAN_ATTRIBUTE_EPNO_RSSI,
+    GSCAN_ATTRIBUTE_EPNO_FLAGS,
+    GSCAN_ATTRIBUTE_EPNO_AUTH,
+    GSCAN_ATTRIBUTE_EPNO_SSID_NUM,
+    GSCAN_ATTRIBUTE_EPNO_FLUSH,
+
+    /* remaining reserved for additional attributes */
+
+    GSCAN_ATTRIBUTE_WHITELIST_SSID = 80,
+    GSCAN_ATTRIBUTE_NUM_WL_SSID,
+    GSCAN_ATTRIBUTE_WL_SSID_LEN,
+    GSCAN_ATTRIBUTE_WL_SSID_FLUSH,
+    GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM,
+    GSCAN_ATTRIBUTE_NUM_BSSID,
+    GSCAN_ATTRIBUTE_BSSID_PREF_LIST,
+    GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH,
+    GSCAN_ATTRIBUTE_BSSID_PREF,
+    GSCAN_ATTRIBUTE_RSSI_MODIFIER,
+
+    /* remaining reserved for additional attributes */
+
+    GSCAN_ATTRIBUTE_A_BAND_BOOST_THRESHOLD = 90,
+    GSCAN_ATTRIBUTE_A_BAND_PENALTY_THRESHOLD,
+    GSCAN_ATTRIBUTE_A_BAND_BOOST_FACTOR,
+    GSCAN_ATTRIBUTE_A_BAND_PENALTY_FACTOR,
+    GSCAN_ATTRIBUTE_A_BAND_MAX_BOOST,
+    GSCAN_ATTRIBUTE_LAZY_ROAM_HYSTERESIS,
+    GSCAN_ATTRIBUTE_ALERT_ROAM_RSSI_TRIGGER,
+    GSCAN_ATTRIBUTE_LAZY_ROAM_ENABLE,
+
+    /* BSSID blacklist */
+    GSCAN_ATTRIBUTE_BSSID_BLACKLIST_FLUSH = 100,
+    GSCAN_ATTRIBUTE_BLACKLIST_BSSID,
+
+    /* ANQPO */
+    GSCAN_ATTRIBUTE_ANQPO_HS_LIST = 110,
+    GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE,
+    GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID,
+    GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM,
+    GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID,
+    GSCAN_ATTRIBUTE_ANQPO_HS_PLMN,
+
+    /* Adaptive scan attributes */
+    GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT = 120,
+    GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD,
+
+    /* ePNO cfg */
+    GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR = 130,
+    GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR,
+    GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX,
+    GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS,
+    GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS,
+    GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS,
+    GSCAN_ATTRIBUTE_EPNO_5G_BONUS,
+
+    GSCAN_ATTRIBUTE_MAX
+
+} GSCAN_ATTRIBUTE;
+
+
+// helper methods
+wifi_error wifi_enable_full_scan_results(wifi_request_id id, wifi_interface_handle iface,
+         wifi_scan_result_handler handler);
+wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface);
+int wifi_handle_full_scan_event(wifi_request_id id, WifiEvent& event,
+         wifi_scan_result_handler handler);
+void convert_to_hal_result(wifi_scan_result *to, wifi_gscan_result_t *from);
+
+
+void convert_to_hal_result(wifi_scan_result *to, wifi_gscan_result_t *from)
+{
+    to->ts = from->ts;
+    to->channel = from->channel;
+    to->rssi = from->rssi;
+    to->rtt = from->rtt;
+    to->rtt_sd = from->rtt_sd;
+    to->beacon_period = from->beacon_period;
+    to->capability = from->capability;
+    memcpy(to->ssid, from->ssid, (DOT11_MAX_SSID_LEN+1));
+    memcpy(&to->bssid, &from->bssid, sizeof(mac_addr));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class GetCapabilitiesCommand : public WifiCommand
+{
+    wifi_gscan_capabilities *mCapabilities;
+public:
+    GetCapabilitiesCommand(wifi_interface_handle iface, wifi_gscan_capabilities *capabitlites)
+        : WifiCommand("GetGscanCapabilitiesCommand", iface, 0), mCapabilities(capabitlites)
+    {
+        memset(mCapabilities, 0, sizeof(*mCapabilities));
+    }
+
+    virtual int create() {
+        ALOGV("Creating message to get scan capablities; iface = %d", mIfaceInfo->id);
+
+        int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CAPABILITIES);
+        if (ret < 0) {
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        ALOGV("In GetCapabilities::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        void *data = reply.get_vendor_data();
+        int len = reply.get_vendor_data_len();
+
+        ALOGV("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
+                    sizeof(*mCapabilities));
+
+        memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities)));
+
+        return NL_OK;
+    }
+};
+
+
+wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle,
+        wifi_gscan_capabilities *capabilities)
+{
+    GetCapabilitiesCommand command(handle, capabilities);
+    return (wifi_error) command.requestResponse();
+}
+
+class GetChannelListCommand : public WifiCommand
+{
+    wifi_channel *channels;
+    int max_channels;
+    int *num_channels;
+    int band;
+public:
+    GetChannelListCommand(wifi_interface_handle iface, wifi_channel *channel_buf, int *ch_num,
+        int num_max_ch, int band)
+        : WifiCommand("GetChannelListCommand", iface, 0), channels(channel_buf),
+            max_channels(num_max_ch), num_channels(ch_num), band(band)
+    {
+        memset(channels, 0, sizeof(wifi_channel) * max_channels);
+    }
+    virtual int create() {
+        ALOGV("Creating message to get channel list; iface = %d", mIfaceInfo->id);
+
+        int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CHANNEL_LIST);
+        if (ret < 0) {
+            return ret;
+        }
+
+        nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
+        ret = mMsg.put_u32(GSCAN_ATTRIBUTE_BAND, band);
+        if (ret < 0) {
+            return ret;
+        }
+
+        mMsg.attr_end(data);
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        ALOGV("In GetChannelList::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+        int num_channels_to_copy = 0;
+
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = reply.get_vendor_data_len();
+
+        ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("no vendor data in GetChannelList response; ignoring it");
+            return NL_SKIP;
+        }
+
+        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+            if (it.get_type() == GSCAN_ATTRIBUTE_NUM_CHANNELS) {
+                num_channels_to_copy = it.get_u32();
+                ALOGI("Got channel list with %d channels", num_channels_to_copy);
+                if(num_channels_to_copy > max_channels)
+                    num_channels_to_copy = max_channels;
+                *num_channels = num_channels_to_copy;
+            } else if (it.get_type() == GSCAN_ATTRIBUTE_CHANNEL_LIST && num_channels_to_copy) {
+                memcpy(channels, it.get_data(), sizeof(int) * num_channels_to_copy);
+            } else {
+                ALOGW("Ignoring invalid attribute type = %d, size = %d",
+                        it.get_type(), it.get_len());
+            }
+        }
+
+        return NL_OK;
+    }
+};
+
+wifi_error wifi_get_valid_channels(wifi_interface_handle handle,
+        int band, int max_channels, wifi_channel *channels, int *num_channels)
+{
+#if 0
+    GetChannelListCommand command(handle, channels, num_channels,
+                                        max_channels, band);
+    return (wifi_error) command.requestResponse();
+#endif
+       *num_channels = 12;
+       return WIFI_SUCCESS;
+}
+/////////////////////////////////////////////////////////////////////////////
+
+/* helper functions */
+
+static int parseScanResults(wifi_scan_result *results, int num, nlattr *attr)
+{
+    memset(results, 0, sizeof(wifi_scan_result) * num);
+
+    int i = 0;
+    for (nl_iterator it(attr); it.has_next() && i < num; it.next(), i++) {
+
+        int index = it.get_type();
+        ALOGI("retrieved scan result %d", index);
+        nlattr *sc_data = (nlattr *) it.get_data();
+        wifi_scan_result *result = results + i;
+
+        for (nl_iterator it2(sc_data); it2.has_next(); it2.next()) {
+            int type = it2.get_type();
+            if (type == GSCAN_ATTRIBUTE_SSID) {
+                strncpy(result->ssid, (char *) it2.get_data(), it2.get_len());
+                result->ssid[it2.get_len()] = 0;
+            } else if (type == GSCAN_ATTRIBUTE_BSSID) {
+                memcpy(result->bssid, (byte *) it2.get_data(), sizeof(mac_addr));
+            } else if (type == GSCAN_ATTRIBUTE_TIMESTAMP) {
+                result->ts = it2.get_u64();
+            } else if (type == GSCAN_ATTRIBUTE_CHANNEL) {
+                result->ts = it2.get_u16();
+            } else if (type == GSCAN_ATTRIBUTE_RSSI) {
+                result->rssi = it2.get_u8();
+            } else if (type == GSCAN_ATTRIBUTE_RTT) {
+                result->rtt = it2.get_u64();
+            } else if (type == GSCAN_ATTRIBUTE_RTTSD) {
+                result->rtt_sd = it2.get_u64();
+            }
+        }
+
+    }
+
+    if (i >= num) {
+        ALOGE("Got too many results; skipping some");
+    }
+
+    return i;
+}
+
+int createFeatureRequest(WifiRequest& request, int subcmd, int enable) {
+
+    int result = request.create(GOOGLE_OUI, subcmd);
+    if (result < 0) {
+        return result;
+    }
+
+    nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+    result = request.put_u32(GSCAN_ATTRIBUTE_ENABLE_FEATURE, enable);
+    if (result < 0) {
+        return result;
+    }
+
+    request.attr_end(data);
+    return WIFI_SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+class FullScanResultsCommand : public WifiCommand
+{
+    int *mParams;
+    wifi_scan_result_handler mHandler;
+public:
+    FullScanResultsCommand(wifi_interface_handle iface, int id, int *params,
+                wifi_scan_result_handler handler)
+        : WifiCommand("FullScanResultsCommand", iface, id), mParams(params), mHandler(handler)
+    { }
+
+    int createRequest(WifiRequest& request, int subcmd, int enable) {
+        int result = request.create(GOOGLE_OUI, subcmd);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(GSCAN_ENABLE_FULL_SCAN_RESULTS, enable);
+        if (result < 0) {
+            return result;
+        }
+
+        request.attr_end(data);
+        return WIFI_SUCCESS;
+
+    }
+
+    int start() {
+        ALOGV("Enabling Full scan results");
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 1);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create request; result = %d", result);
+            return result;
+        }
+
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to enable full scan results; result = %d", result);
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
+            return result;
+        }
+
+        return result;
+    }
+
+    virtual int cancel() {
+        ALOGV("Disabling Full scan results");
+
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 0);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create request; result = %d", result);
+        } else {
+            result = requestResponse(request);
+            if (result != WIFI_SUCCESS) {
+                ALOGE("failed to disable full scan results;result = %d", result);
+            }
+        }
+
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+         ALOGD("Request complete!");
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        ALOGV("Full scan results:  Got an event");
+        return wifi_handle_full_scan_event(id(), event, mHandler);
+    }
+
+};
+/////////////////////////////////////////////////////////////////////////////
+
+class ScanCommand : public WifiCommand
+{
+    wifi_scan_cmd_params *mParams;
+    wifi_scan_result_handler mHandler;
+public:
+    ScanCommand(wifi_interface_handle iface, int id, wifi_scan_cmd_params *params,
+                wifi_scan_result_handler handler)
+        : WifiCommand("ScanCommand", iface, id), mParams(params), mHandler(handler)
+    { }
+
+    int createSetupRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_CONFIG);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(GSCAN_ATTRIBUTE_BASE_PERIOD, mParams->base_period);
+        if (result < 0) {
+            return result;
+        }
+
+        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_BUCKETS, mParams->num_buckets);
+        if (result < 0) {
+            return result;
+        }
+
+        for (int i = 0; i < mParams->num_buckets; i++) {
+            nlattr * bucket = request.attr_start(i);    // next bucket
+            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_ID, mParams->buckets[i].bucket);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_PERIOD, mParams->buckets[i].period);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKETS_BAND,
+                    mParams->buckets[i].band);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT,
+                    mParams->buckets[i].step_count);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD,
+                    mParams->buckets[i].max_period);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_EVENTS,
+                    mParams->buckets[i].report_events);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS,
+                    mParams->buckets[i].num_channels);
+            if (result < 0) {
+                return result;
+            }
+
+            if (mParams->buckets[i].num_channels) {
+                nlattr *channels = request.attr_start(GSCAN_ATTRIBUTE_BUCKET_CHANNELS);
+                ALOGV(" channels: ");
+                for (int j = 0; j < mParams->buckets[i].num_channels; j++) {
+                    result = request.put_u32(j, mParams->buckets[i].channels[j].channel);
+                    ALOGV(" %u", mParams->buckets[i].channels[j].channel);
+
+                    if (result < 0) {
+                        return result;
+                    }
+                }
+                request.attr_end(channels);
+            }
+
+            request.attr_end(bucket);
+        }
+
+        request.attr_end(data);
+        return WIFI_SUCCESS;
+    }
+
+    int createScanConfigRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SCAN_CONFIG);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, mParams->max_ap_per_scan);
+        if (result < 0) {
+            return result;
+        }
+
+        result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_THRESHOLD,
+                mParams->report_threshold_percent);
+        if (result < 0) {
+            return result;
+        }
+
+        int num_scans = mParams->report_threshold_num_scans;
+
+        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, num_scans);
+        if (result < 0) {
+            return result;
+        }
+
+        request.attr_end(data);
+        return WIFI_SUCCESS;
+    }
+
+    int createStartRequest(WifiRequest& request) {
+        return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1);
+    }
+
+    int createStopRequest(WifiRequest& request) {
+        return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 0);
+    }
+
+    int start() {
+        ALOGV("GSCAN start");
+        WifiRequest request(familyId(), ifaceId());
+        int result = createSetupRequest(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create setup request; result = %d", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to configure setup; result = %d", result);
+            return result;
+        }
+
+        request.destroy();
+
+        result = createScanConfigRequest(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create scan config request; result = %d", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to configure scan; result = %d", result);
+            return result;
+        }
+
+        ALOGV(" ....starting scan");
+
+        result = createStartRequest(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create start request; result = %d", result);
+            return result;
+        }
+
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to start scan; result = %d", result);
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
+            return result;
+        }
+        return result;
+    }
+
+    virtual int cancel() {
+        ALOGV("Stopping scan");
+
+        WifiRequest request(familyId(), ifaceId());
+        int result = createStopRequest(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create stop request; result = %d", result);
+        } else {
+            result = requestResponse(request);
+            if (result != WIFI_SUCCESS) {
+                ALOGE("failed to stop scan; result = %d", result);
+            }
+        }
+
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        ALOGV("Got a scan results event");
+        //event.log();
+
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = event.get_vendor_data_len();
+        int event_id = event.get_vendor_subcmd();
+
+        if ((event_id == GSCAN_EVENT_COMPLETE_SCAN) ||
+            (event_id == GSCAN_EVENT_SCAN_RESULTS_AVAILABLE)) {
+            if (vendor_data == NULL || len != 4) {
+                ALOGI("Bad event data!");
+                return NL_SKIP;
+            }
+            wifi_scan_event evt_type;
+            evt_type = (wifi_scan_event) event.get_u32(NL80211_ATTR_VENDOR_DATA);
+            ALOGV("Received event type %d", evt_type);
+            if(*mHandler.on_scan_event)
+                (*mHandler.on_scan_event)(id(), evt_type);
+        } else if (event_id == GSCAN_EVENT_FULL_SCAN_RESULTS) {
+            wifi_handle_full_scan_event(id(), event, mHandler);
+        }
+        return NL_SKIP;
+    }
+};
+
+wifi_error wifi_start_gscan(
+        wifi_request_id id,
+        wifi_interface_handle iface,
+        wifi_scan_cmd_params params,
+        wifi_scan_result_handler handler)
+{
+    wifi_handle handle = getWifiHandle(iface);
+
+    ALOGV("Starting GScan, halHandle = %p", handle);
+
+    ScanCommand *cmd = new ScanCommand(iface, id, &params, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return result;
+}
+
+wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface)
+{
+    wifi_handle handle = getWifiHandle(iface);
+    ALOGV("Stopping GScan, wifi_request_id = %d, halHandle = %p", id, handle);
+
+    if (id == -1) {
+        wifi_scan_result_handler handler;
+        wifi_scan_cmd_params dummy_params;
+        wifi_handle handle = getWifiHandle(iface);
+        memset(&handler, 0, sizeof(handler));
+
+        ScanCommand *cmd = new ScanCommand(iface, id, &dummy_params, handler);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+
+    return wifi_cancel_cmd(id, iface);
+}
+
+wifi_error wifi_enable_full_scan_results(
+        wifi_request_id id,
+        wifi_interface_handle iface,
+        wifi_scan_result_handler handler)
+{
+    wifi_handle handle = getWifiHandle(iface);
+    int params_dummy;
+
+    ALOGV("Enabling full scan results, halHandle = %p", handle);
+
+    FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, id, &params_dummy, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return result;
+}
+
+int wifi_handle_full_scan_event(
+        wifi_request_id id,
+        WifiEvent& event,
+        wifi_scan_result_handler handler)
+{
+    nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+    unsigned int len = event.get_vendor_data_len();
+
+    if (vendor_data == NULL || len < sizeof(wifi_gscan_full_result_t)) {
+        ALOGI("Full scan results: No scan results found");
+        return NL_SKIP;
+    }
+
+    wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data();
+    /* To protect against corrupted data, put a ceiling */
+    int ie_len = min(MAX_PROBE_RESP_IE_LEN, drv_res->ie_length);
+    wifi_scan_result *full_scan_result;
+    wifi_gscan_result_t *fixed = &drv_res->fixed;
+
+    if ((ie_len + offsetof(wifi_gscan_full_result_t, ie_data)) > len) {
+        ALOGE("BAD event data, len %d ie_len %d fixed length %d!\n", len,
+            ie_len, offsetof(wifi_gscan_full_result_t, ie_data));
+        return NL_SKIP;
+    }
+    full_scan_result = (wifi_scan_result *) malloc((ie_len + offsetof(wifi_scan_result, ie_data)));
+    if (!full_scan_result) {
+        ALOGE("Full scan results: Can't malloc!\n");
+        return NL_SKIP;
+    }
+    convert_to_hal_result(full_scan_result, fixed);
+    full_scan_result->ie_length = ie_len;
+    memcpy(full_scan_result->ie_data, drv_res->ie_data, ie_len);
+    if(handler.on_full_scan_result)
+        handler.on_full_scan_result(id, full_scan_result, drv_res->scan_ch_bucket);
+
+    ALOGV("Full scan result: %-32s %02x:%02x:%02x:%02x:%02x:%02x %d %d %lld %lld %lld %x %d\n",
+        fixed->ssid, fixed->bssid[0], fixed->bssid[1], fixed->bssid[2], fixed->bssid[3],
+        fixed->bssid[4], fixed->bssid[5], fixed->rssi, fixed->channel, fixed->ts,
+        fixed->rtt, fixed->rtt_sd, drv_res->scan_ch_bucket, drv_res->ie_length);
+    free(full_scan_result);
+    return NL_SKIP;
+}
+
+
+wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface)
+{
+    ALOGV("Disabling full scan results");
+    wifi_handle handle = getWifiHandle(iface);
+
+    if(id == -1) {
+        wifi_scan_result_handler handler;
+        wifi_handle handle = getWifiHandle(iface);
+        int params_dummy;
+
+        memset(&handler, 0, sizeof(handler));
+        FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, 0, &params_dummy, handler);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+
+    return wifi_cancel_cmd(id, iface);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+class GetScanResultsCommand : public WifiCommand {
+    wifi_cached_scan_results *mScans;
+    int mMax;
+    int *mNum;
+    int mRetrieved;
+    byte mFlush;
+    int mCompleted;
+public:
+    GetScanResultsCommand(wifi_interface_handle iface, byte flush,
+            wifi_cached_scan_results *results, int max, int *num)
+        : WifiCommand("GetScanResultsCommand", iface, -1), mScans(results), mMax(max), mNum(num),
+                mRetrieved(0), mFlush(flush), mCompleted(0)
+    { }
+
+    int createRequest(WifiRequest& request, int num, byte flush) {
+        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_SCAN_RESULTS);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_OF_RESULTS, num);
+        if (result < 0) {
+            return result;
+        }
+
+        result = request.put_u8(GSCAN_ATTRIBUTE_FLUSH_RESULTS, flush);
+        if (result < 0) {
+            return result;
+        }
+
+        request.attr_end(data);
+        return WIFI_SUCCESS;
+    }
+
+    int execute() {
+        WifiRequest request(familyId(), ifaceId());
+        ALOGV("retrieving %d scan results", mMax);
+
+        for (int i = 0; i < 10 && mRetrieved < mMax; i++) {
+            int num_to_retrieve = mMax - mRetrieved;
+            // ALOGI("retrieving %d scan results in one shot", num_to_retrieve);
+            int result = createRequest(request, num_to_retrieve, mFlush);
+            if (result < 0) {
+                ALOGE("failed to create request");
+                return result;
+            }
+
+            int prev_retrieved = mRetrieved;
+
+            result = requestResponse(request);
+
+            if (result != WIFI_SUCCESS) {
+                ALOGE("failed to retrieve scan results; result = %d", result);
+                return result;
+            }
+
+            if (mRetrieved == prev_retrieved || mCompleted) {
+                /* no more items left to retrieve */
+                break;
+            }
+
+            request.destroy();
+        }
+
+        ALOGV("GetScanResults read %d results", mRetrieved);
+        *mNum = mRetrieved;
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        ALOGV("In GetScanResultsCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        ALOGV("Id = %0x, subcmd = %d", id, subcmd);
+
+        /*
+        if (subcmd != GSCAN_SUBCMD_SCAN_RESULTS) {
+            ALOGE("Invalid response to GetScanResultsCommand; ignoring it");
+            return NL_SKIP;
+        }
+        */
+
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = reply.get_vendor_data_len();
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("no vendor data in GetScanResults response; ignoring it");
+            return NL_SKIP;
+        }
+
+        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+            if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE) {
+                mCompleted = it.get_u8();
+                ALOGV("retrieved mCompleted flag : %d", mCompleted);
+            } else if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS || it.get_type() == 0) {
+                int scan_id = 0, flags = 0, num = 0, scan_ch_bucket_mask = 0;
+                for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
+                    if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_ID) {
+                        scan_id = it2.get_u32();
+                        ALOGV("retrieved scan_id : 0x%0x", scan_id);
+                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_FLAGS) {
+                        flags = it2.get_u8();
+                        ALOGV("retrieved scan_flags : 0x%0x", flags);
+                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) {
+                        num = it2.get_u32();
+                        ALOGV("retrieved num_results: %d", num);
+                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK) {
+                        scan_ch_bucket_mask = it2.get_u32();
+                        ALOGD("retrieved scan_ch_bucket_mask: %x", scan_ch_bucket_mask);
+                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS && num) {
+                        if (mRetrieved >= mMax) {
+                            ALOGW("Stored %d scans, ignoring excess results", mRetrieved);
+                            break;
+                        }
+                        num = min(num, (int)(it2.get_len()/sizeof(wifi_gscan_result)));
+                        num = min(num, (int)MAX_AP_CACHE_PER_SCAN);
+                        ALOGV("Copying %d scan results", num);
+                        wifi_gscan_result_t *results = (wifi_gscan_result_t *)it2.get_data();
+                        wifi_scan_result *mScanResults = mScans[mRetrieved].results;
+
+                        for (int i = 0; i < num; i++) {
+                            wifi_gscan_result_t *result = &results[i];
+                            convert_to_hal_result(&mScanResults[i], result);
+                            mScanResults[i].ie_length = 0;
+                            ALOGV("%02d  %-32s  %02x:%02x:%02x:%02x:%02x:%02x  %04d", i,
+                                result->ssid, result->bssid[0], result->bssid[1], result->bssid[2],
+                                result->bssid[3], result->bssid[4], result->bssid[5],
+                                result->rssi);
+                        }
+                        mScans[mRetrieved].scan_id = scan_id;
+                        mScans[mRetrieved].flags = flags;
+                        mScans[mRetrieved].num_results = num;
+                        mScans[mRetrieved].buckets_scanned = scan_ch_bucket_mask;
+                        ALOGV("Setting result of scan_id : 0x%0x", mScans[mRetrieved].scan_id);
+                        mRetrieved++;
+                    } else {
+                        ALOGW("Ignoring invalid attribute type = %d, size = %d",
+                                it.get_type(), it.get_len());
+                    }
+                }
+            } else {
+                ALOGW("Ignoring invalid attribute type = %d, size = %d",
+                        it.get_type(), it.get_len());
+            }
+        }
+        ALOGV("GetScanResults read %d results", mRetrieved);
+        return NL_OK;
+    }
+};
+
+wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, byte flush,
+        int max, wifi_cached_scan_results *results, int *num) {
+    ALOGV("Getting cached scan results, iface handle = %p, num = %d", iface, *num);
+
+    GetScanResultsCommand *cmd = new GetScanResultsCommand(iface, flush, results, max, num);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error err = (wifi_error)cmd->execute();
+    cmd->releaseRef();
+    return err;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class BssidHotlistCommand : public WifiCommand
+{
+private:
+    wifi_bssid_hotlist_params mParams;
+    wifi_hotlist_ap_found_handler mHandler;
+    static const int MAX_RESULTS = 64;
+    wifi_scan_result mResults[MAX_RESULTS];
+public:
+    BssidHotlistCommand(wifi_interface_handle handle, int id,
+            wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler)
+        : WifiCommand("BssidHotlistCommand", handle, id), mParams(params), mHandler(handler)
+    { }
+
+    int createSetupRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_HOTLIST);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u8(GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 1);
+        if (result < 0) {
+            return result;
+        }
+
+        result = request.put_u32(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, mParams.lost_ap_sample_size);
+        if (result < 0) {
+            return result;
+        }
+
+        result = request.put_u32(GSCAN_ATTRIBUTE_HOTLIST_BSSID_COUNT, mParams.num_bssid);
+        if (result < 0) {
+            return result;
+        }
+
+        struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS);
+        for (int i = 0; i < mParams.num_bssid; i++) {
+            nlattr *attr2 = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_ELEM);
+            if (attr2 == NULL) {
+                return WIFI_ERROR_OUT_OF_MEMORY;
+            }
+            result = request.put_addr(GSCAN_ATTRIBUTE_BSSID, mParams.ap[i].bssid);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH, mParams.ap[i].high);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW, mParams.ap[i].low);
+            if (result < 0) {
+                return result;
+            }
+            request.attr_end(attr2);
+        }
+
+        request.attr_end(attr);
+        request.attr_end(data);
+        return result;
+    }
+
+    int createTeardownRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_HOTLIST);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u8(GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 1);
+        if (result < 0) {
+            return result;
+        }
+
+        struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS);
+        request.attr_end(attr);
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        ALOGI("Executing hotlist setup request, num = %d", mParams.num_bssid);
+        WifiRequest request(familyId(), ifaceId());
+        int result = createSetupRequest(request);
+        if (result < 0) {
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGI("Failed to execute hotlist setup request, result = %d", result);
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
+            return result;
+        }
+
+        ALOGI("Successfully set %d APs in the hotlist ", mParams.num_bssid);
+        result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1);
+        if (result < 0) {
+            return result;
+        }
+
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
+
+        result = requestResponse(request);
+        if (result < 0) {
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
+            return result;
+        }
+
+        ALOGI("successfully restarted the scan");
+        return result;
+    }
+
+    virtual int cancel() {
+        /* unregister event handler */
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
+        /* create set hotlist message with empty hotlist */
+        WifiRequest request(familyId(), ifaceId());
+        int result = createTeardownRequest(request);
+        if (result < 0) {
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            return result;
+        }
+
+        ALOGI("Successfully reset APs in current hotlist");
+        return result;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        ALOGI("Hotlist AP event");
+        int event_id = event.get_vendor_subcmd();
+        // event.log();
+
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = event.get_vendor_data_len();
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGI("No scan results found");
+            return NL_SKIP;
+        }
+
+        memset(mResults, 0, sizeof(wifi_scan_result) * MAX_RESULTS);
+
+        int num = len / sizeof(wifi_gscan_result_t);
+        wifi_gscan_result_t *inp = (wifi_gscan_result_t *)event.get_vendor_data();
+        num = min(MAX_RESULTS, num);
+        for (int i = 0; i < num; i++, inp++) {
+            convert_to_hal_result(&(mResults[i]), inp);
+        }
+
+        if (event_id == GSCAN_EVENT_HOTLIST_RESULTS_FOUND) {
+            ALOGI("FOUND %d hotlist APs", num);
+            if (*mHandler.on_hotlist_ap_found)
+                (*mHandler.on_hotlist_ap_found)(id(), num, mResults);
+        } else if (event_id == GSCAN_EVENT_HOTLIST_RESULTS_LOST) {
+            ALOGI("LOST %d hotlist APs", num);
+            if (*mHandler.on_hotlist_ap_lost)
+                (*mHandler.on_hotlist_ap_lost)(id(), num, mResults);
+        }
+        return NL_SKIP;
+    }
+};
+
+class ePNOCommand : public WifiCommand
+{
+private:
+    wifi_epno_params epno_params;
+    wifi_epno_handler mHandler;
+    wifi_scan_result mResults[MAX_EPNO_NETWORKS];
+public:
+    ePNOCommand(wifi_interface_handle handle, int id,
+            const wifi_epno_params *params, wifi_epno_handler handler)
+        : WifiCommand("ePNOCommand", handle, id), mHandler(handler)
+    {
+        if (params != NULL) {
+            memcpy(&epno_params, params, sizeof(wifi_epno_params));
+        } else {
+            memset(&epno_params, 0, sizeof(wifi_epno_params));
+        }
+    }
+    int createSetupRequest(WifiRequest& request) {
+        if (epno_params.num_networks > MAX_EPNO_NETWORKS) {
+            ALOGE("wrong epno num_networks:%d", epno_params.num_networks);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_EPNO_SSID);
+        if (result < 0) {
+            return result;
+        }
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_FLUSH, 1);
+        if (result < 0) {
+            return result;
+        }
+
+        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR,
+                            (u8)epno_params.min5GHz_rssi);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR,
+                            (u8)epno_params.min24GHz_rssi);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX,
+                            epno_params.initial_score_max);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS,
+                            epno_params.current_connection_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS,
+                            epno_params.same_network_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS,
+                            epno_params.secure_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_5G_BONUS,
+                            epno_params.band5GHz_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_SSID_NUM,
+                        epno_params.num_networks);
+        if (result < 0) {
+            return result;
+        }
+        struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_EPNO_SSID_LIST);
+        wifi_epno_network *ssid_list = epno_params.networks;
+        for (int i = 0; i < epno_params.num_networks; i++) {
+            nlattr *attr2 = request.attr_start(i);
+            if (attr2 == NULL) {
+                return WIFI_ERROR_OUT_OF_MEMORY;
+            }
+            result = request.put(GSCAN_ATTRIBUTE_EPNO_SSID, ssid_list[i].ssid, DOT11_MAX_SSID_LEN);
+            ALOGI("PNO network: SSID %s flags %x auth %x", ssid_list[i].ssid,
+                ssid_list[i].flags,
+                ssid_list[i].auth_bit_field);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_SSID_LEN, strlen(ssid_list[i].ssid));
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_FLAGS, ssid_list[i].flags);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_AUTH, ssid_list[i].auth_bit_field);
+            if (result < 0) {
+                return result;
+            }
+            request.attr_end(attr2);
+        }
+        request.attr_end(attr);
+        request.attr_end(data);
+        return result;
+    }
+
+    int createTeardownRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_EPNO_SSID);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_FLUSH, 1);
+        if (result < 0) {
+            return result;
+        }
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        ALOGI("Executing ePNO setup request, num = %d", epno_params.num_networks);
+        WifiRequest request(familyId(), ifaceId());
+        int result = createSetupRequest(request);
+        if (result < 0) {
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGI("Failed to execute ePNO setup request, result = %d", result);
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT);
+            return result;
+        }
+
+        ALOGI("Successfully set %d SSIDs for ePNO", epno_params.num_networks);
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT);
+        ALOGI("successfully restarted the scan");
+        return result;
+    }
+
+    virtual int cancel() {
+        /* unregister event handler */
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT);
+        /* create set hotlist message with empty hotlist */
+        WifiRequest request(familyId(), ifaceId());
+        int result = createTeardownRequest(request);
+        if (result < 0) {
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            return result;
+        }
+
+        ALOGI("Successfully reset APs in current hotlist");
+        return result;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        ALOGI("ePNO event");
+        int event_id = event.get_vendor_subcmd();
+        // event.log();
+
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = event.get_vendor_data_len();
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGI("No scan results found");
+            return NL_SKIP;
+        }
+
+        memset(mResults, 0, sizeof(wifi_scan_result) * MAX_EPNO_NETWORKS);
+
+        unsigned int num = len / sizeof(wifi_pno_result_t);
+        unsigned int i;
+        num = min(MAX_EPNO_NETWORKS, num);
+        wifi_pno_result_t *res = (wifi_pno_result_t *) event.get_vendor_data();
+        for (i = 0; i < num; i++) {
+            if (res[i].flags == PNO_SSID_FOUND) {
+                memcpy(mResults[i].ssid, res[i].ssid, res[i].ssid_len);
+                memcpy(mResults[i].bssid, res[i].bssid, sizeof(mac_addr));
+
+                mResults[i].ssid[res[i].ssid_len] = '\0';
+                mResults[i].channel = res[i].channel;
+                mResults[i].rssi = res[i].rssi;
+            }
+        }
+        if (*mHandler.on_network_found)
+            (*mHandler.on_network_found)(id(), num, mResults);
+        return NL_SKIP;
+    }
+};
+
+wifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface,
+        wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler)
+{
+    wifi_handle handle = getWifiHandle(iface);
+
+    BssidHotlistCommand *cmd = new BssidHotlistCommand(iface, id, params, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return result;
+}
+
+wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface)
+{
+    return wifi_cancel_cmd(id, iface);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+class SignificantWifiChangeCommand : public WifiCommand
+{
+    typedef struct {
+        mac_addr bssid;                     // BSSID
+        wifi_channel channel;               // channel frequency in MHz
+        int num_rssi;                       // number of rssi samples
+        wifi_rssi rssi[8];                   // RSSI history in db
+    } wifi_significant_change_result_internal;
+
+private:
+    wifi_significant_change_params mParams;
+    wifi_significant_change_handler mHandler;
+    static const int MAX_RESULTS = 64;
+    wifi_significant_change_result_internal mResultsBuffer[MAX_RESULTS];
+    wifi_significant_change_result *mResults[MAX_RESULTS];
+public:
+    SignificantWifiChangeCommand(wifi_interface_handle handle, int id,
+            wifi_significant_change_params params, wifi_significant_change_handler handler)
+        : WifiCommand("SignificantWifiChangeCommand", handle, id), mParams(params),
+            mHandler(handler)
+    { }
+
+    int createSetupRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u8(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE, mParams.rssi_sample_size);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, mParams.lost_ap_sample_size);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_MIN_BREACHING, mParams.min_breaching);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_NUM_BSSID, mParams.num_bssid);
+        if (result < 0) {
+            return result;
+        }
+        if (mParams.num_bssid != 0) {
+            nlattr* attr = request.attr_start(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS);
+            if (attr == NULL) {
+                return WIFI_ERROR_OUT_OF_MEMORY;
+            }
+
+            for (int i = 0; i < mParams.num_bssid; i++) {
+                nlattr* attr2 = request.attr_start(i);
+                if (attr2 == NULL) {
+                    return WIFI_ERROR_OUT_OF_MEMORY;
+                }
+                result = request.put_addr(GSCAN_ATTRIBUTE_BSSID, mParams.ap[i].bssid);
+                if (result < 0) {
+                    return result;
+                }
+                result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH, mParams.ap[i].high);
+                if (result < 0) {
+                    return result;
+                }
+                result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW, mParams.ap[i].low);
+                if (result < 0) {
+                    return result;
+                }
+                request.attr_end(attr2);
+            }
+
+            request.attr_end(attr);
+        }
+        request.attr_end(data);
+
+        return result;
+    }
+
+    int createTeardownRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u16(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1);
+        if (result < 0) {
+            return result;
+        }
+
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        ALOGI("Set significant wifi change config");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = createSetupRequest(request);
+        if (result < 0) {
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGI("failed to set significant wifi change config %d", result);
+            return result;
+        }
+
+        ALOGI("successfully set significant wifi change config");
+
+        result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1);
+        if (result < 0) {
+            return result;
+        }
+
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS);
+
+        result = requestResponse(request);
+        if (result < 0) {
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS);
+            return result;
+        }
+
+        ALOGI("successfully restarted the scan");
+        return result;
+    }
+
+    virtual int cancel() {
+        /* unregister event handler */
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS);
+
+        /* create set significant change monitor message with empty hotlist */
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = createTeardownRequest(request);
+        if (result < 0) {
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            return result;
+        }
+
+        ALOGI("successfully reset significant wifi change config");
+        return result;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        ALOGV("Got a significant wifi change event");
+
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = event.get_vendor_data_len();
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGI("No scan results found");
+            return NL_SKIP;
+        }
+
+        typedef struct {
+            uint16_t flags;
+            uint16_t channel;
+            mac_addr bssid;
+            s8 rssi_history[8];
+        } ChangeInfo;
+
+        int num = min(len / sizeof(ChangeInfo), MAX_RESULTS);
+        ChangeInfo *ci = (ChangeInfo *)event.get_vendor_data();
+
+        for (int i = 0; i < num; i++) {
+            memcpy(mResultsBuffer[i].bssid, ci[i].bssid, sizeof(mac_addr));
+            mResultsBuffer[i].channel = ci[i].channel;
+            mResultsBuffer[i].num_rssi = 8;
+            for (int j = 0; j < mResultsBuffer[i].num_rssi; j++)
+                mResultsBuffer[i].rssi[j] = (int) ci[i].rssi_history[j];
+            mResults[i] = reinterpret_cast<wifi_significant_change_result *>(&(mResultsBuffer[i]));
+        }
+
+        ALOGV("Retrieved %d scan results", num);
+
+        if (num != 0) {
+            (*mHandler.on_significant_change)(id(), num, mResults);
+        } else {
+            ALOGW("No significant change reported");
+        }
+
+        return NL_SKIP;
+    }
+};
+
+wifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interface_handle iface,
+        wifi_significant_change_params params, wifi_significant_change_handler handler)
+{
+    wifi_handle handle = getWifiHandle(iface);
+
+    SignificantWifiChangeCommand *cmd = new SignificantWifiChangeCommand(
+            iface, id, params, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return result;
+}
+
+wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface)
+{
+    return wifi_cancel_cmd(id, iface);
+}
+
+wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface)
+{
+    if (id == -1) {
+        wifi_epno_handler handler;
+        wifi_handle handle = getWifiHandle(iface);
+
+        memset(&handler, 0, sizeof(handler));
+        ePNOCommand *cmd = new ePNOCommand(iface, id, NULL, handler);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+    return wifi_cancel_cmd(id, iface);
+}
+
+wifi_error wifi_set_epno_list(wifi_request_id id, wifi_interface_handle iface,
+        const wifi_epno_params *params, wifi_epno_handler handler)
+{
+    wifi_handle handle = getWifiHandle(iface);
+
+    ePNOCommand *cmd = new ePNOCommand(iface, id, params, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return result;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+class AnqpoConfigureCommand : public WifiCommand
+{
+    int num_hs;
+    wifi_passpoint_network *mNetworks;
+    wifi_passpoint_event_handler mHandler;
+    wifi_scan_result *mResult;
+public:
+    AnqpoConfigureCommand(wifi_request_id id, wifi_interface_handle iface,
+        int num, wifi_passpoint_network *hs_list, wifi_passpoint_event_handler handler)
+        : WifiCommand("AnqpoConfigureCommand", iface, id), num_hs(num), mNetworks(hs_list),
+            mHandler(handler)
+    {
+        mResult = NULL;
+    }
+
+    int createRequest(WifiRequest& request, int val) {
+
+        int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_ANQPO_CONFIG);
+        result = request.put_u32(GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE, num_hs);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_ANQPO_HS_LIST);
+        for (int i = 0; i < num_hs; i++) {
+            nlattr *attr2 = request.attr_start(i);
+            if (attr2 == NULL) {
+                return WIFI_ERROR_OUT_OF_MEMORY;
+            }
+            result = request.put_u32(GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID, mNetworks[i].id);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM, mNetworks[i].realm, 256);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID,
+                         mNetworks[i].roamingConsortiumIds, 128);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_PLMN, mNetworks[i].plmn, 3);
+            if (result < 0) {
+                return result;
+            }
+
+            request.attr_end(attr2);
+        }
+
+        request.attr_end(attr);
+        request.attr_end(data);
+
+        return WIFI_SUCCESS;
+    }
+
+    int start() {
+
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request, num_hs);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create request; result = %d", result);
+            return result;
+        }
+
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH);
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to set ANQPO networks; result = %d", result);
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH);
+            return result;
+        }
+
+        return result;
+    }
+
+    virtual int cancel() {
+
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request, 0);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create request; result = %d", result);
+        } else {
+            result = requestResponse(request);
+            if (result != WIFI_SUCCESS) {
+                ALOGE("failed to reset ANQPO networks;result = %d", result);
+            }
+        }
+
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+         ALOGD("Request complete!");
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        typedef struct {
+            u16 channel;        /* channel of GAS protocol */
+            u8  dialog_token;   /* GAS dialog token */
+            u8  fragment_id;    /* fragment id */
+            u16 status_code;    /* status code on GAS completion */
+            u16 data_len;       /* length of data to follow */
+            u8  data[1];        /* variable length specified by data_len */
+        } wifi_anqp_gas_resp;
+
+        ALOGI("ANQPO hotspot matched event!");
+
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        unsigned int len = event.get_vendor_data_len();
+
+        if (vendor_data == NULL || len < sizeof(wifi_scan_result)) {
+            ALOGI("No scan results found");
+            return NL_SKIP;
+        }
+        mResult = (wifi_scan_result *)malloc(sizeof(wifi_scan_result));
+        if (!mResult) {
+            return NL_SKIP;
+        }
+        wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data();
+        wifi_gscan_result_t *fixed = &drv_res->fixed;
+        convert_to_hal_result(mResult, fixed);
+
+        byte *anqp = (byte *)drv_res + offsetof(wifi_gscan_full_result_t, ie_data) + drv_res->ie_length;
+        wifi_anqp_gas_resp *gas = (wifi_anqp_gas_resp *)anqp;
+        int anqp_len = offsetof(wifi_anqp_gas_resp, data) + gas->data_len;
+        int networkId = *(int *)((byte *)anqp + anqp_len);
+
+        ALOGI("%-32s\t", mResult->ssid);
+
+        ALOGI("%02x:%02x:%02x:%02x:%02x:%02x ", mResult->bssid[0], mResult->bssid[1],
+                mResult->bssid[2], mResult->bssid[3], mResult->bssid[4], mResult->bssid[5]);
+
+        ALOGI("%d\t", mResult->rssi);
+        ALOGI("%d\t", mResult->channel);
+        ALOGI("%lld\t", mResult->ts);
+        ALOGI("%lld\t", mResult->rtt);
+        ALOGI("%lld\n", mResult->rtt_sd);
+
+        if(*mHandler.on_passpoint_network_found)
+            (*mHandler.on_passpoint_network_found)(id(), networkId, mResult, anqp_len, anqp);
+        free(mResult);
+        return NL_SKIP;
+    }
+};
+
+wifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_interface_handle iface, int num,
+        wifi_passpoint_network *networks, wifi_passpoint_event_handler handler)
+{
+    wifi_handle handle = getWifiHandle(iface);
+
+    AnqpoConfigureCommand *cmd = new AnqpoConfigureCommand(id, iface, num, networks, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return result;
+}
+
+wifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle iface)
+{
+    return wifi_cancel_cmd(id, iface);
+}
diff --git a/wlan/wifi_hal/rtw_wifi_hal.cpp b/wlan/wifi_hal/rtw_wifi_hal.cpp
new file mode 100644 (file)
index 0000000..c5d47eb
--- /dev/null
@@ -0,0 +1,1344 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+#include <errno.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink/attr.h>
+#include <netlink/handlers.h>
+#include <netlink/msg.h>
+
+#include <dirent.h>
+#include <net/if.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL"
+
+#include <log/log.h>
+
+#include "version.h"
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include "rtt.h"
+
+/*
+ BUGBUG: normally, libnl allocates ports for all connections it makes; but
+ being a static library, it doesn't really know how many other netlink connections
+ are made by the same process, if connections come from different shared libraries.
+ These port assignments exist to solve that problem - temporarily. We need to fix
+ libnl to try and allocate ports across the entire process.
+ */
+
+#define WIFI_HAL_CMD_SOCK_PORT       644
+#define WIFI_HAL_EVENT_SOCK_PORT     645
+
+static void internal_event_handler(wifi_handle handle, int events);
+static int internal_no_seq_check(nl_msg *msg, void *arg);
+static int internal_valid_message_handler(nl_msg *msg, void *arg);
+static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group);
+static int wifi_add_membership(wifi_handle handle, const char *group);
+static wifi_error wifi_init_interfaces(wifi_handle handle);
+static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
+                        iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh);
+static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface);
+static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
+                            const u8 *program, u32 len);
+static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
+                u32 *version, u32 *max_len);
+static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, u8 enable);
+static wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface,
+                                WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt);
+
+typedef enum wifi_attr {
+    ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
+    ANDR_WIFI_ATTRIBUTE_FEATURE_SET,
+    ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI,
+    ANDR_WIFI_ATTRIBUTE_NODFS_SET,
+    ANDR_WIFI_ATTRIBUTE_COUNTRY,
+    ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE
+    // Add more attribute here
+} wifi_attr_t;
+
+enum wifi_rssi_monitor_attr {
+    RSSI_MONITOR_ATTRIBUTE_MAX_RSSI,
+    RSSI_MONITOR_ATTRIBUTE_MIN_RSSI,
+    RSSI_MONITOR_ATTRIBUTE_START,
+};
+
+enum wifi_apf_attr {
+    APF_ATTRIBUTE_VERSION,
+    APF_ATTRIBUTE_MAX_LEN,
+    APF_ATTRIBUTE_PROGRAM,
+    APF_ATTRIBUTE_PROGRAM_LEN
+};
+
+enum apf_request_type {
+    GET_APF_CAPABILITIES,
+    SET_APF_PROGRAM
+};
+
+/* Initialize/Cleanup */
+
+void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
+{
+    uint32_t pid = getpid() & 0x3FFFFF;
+    nl_socket_set_local_port(sock, pid + (port << 22));
+}
+
+static nl_sock * wifi_create_nl_socket(int port)
+{
+    // ALOGI("Creating socket");
+    struct nl_sock *sock = nl_socket_alloc();
+    if (sock == NULL) {
+        ALOGE("Could not create handle");
+        return NULL;
+    }
+
+    wifi_socket_set_local_port(sock, port);
+
+    struct sockaddr *addr = NULL;
+    // ALOGI("sizeof(sockaddr) = %d, sizeof(sockaddr_nl) = %d", sizeof(*addr), sizeof(*addr_nl));
+
+    // ALOGI("Connecting socket");
+    if (nl_connect(sock, NETLINK_GENERIC)) {
+        ALOGE("Could not connect handle");
+        nl_socket_free(sock);
+        return NULL;
+    }
+
+    // ALOGI("Making socket nonblocking");
+    /*
+    if (nl_socket_set_nonblocking(sock)) {
+        ALOGE("Could make socket non-blocking");
+        nl_socket_free(sock);
+        return NULL;
+    }
+    */
+
+    return sock;
+}
+
+/*initialize function pointer table with Realtek HAL API*/
+wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
+{
+    if (fn == NULL) {
+        return WIFI_ERROR_UNKNOWN;
+    }
+    fn->wifi_initialize = wifi_initialize;
+    fn->wifi_cleanup = wifi_cleanup;
+    fn->wifi_event_loop = wifi_event_loop;
+    fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set;
+    fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix;
+    fn->wifi_set_scanning_mac_oui =  wifi_set_scanning_mac_oui;
+    fn->wifi_get_ifaces = wifi_get_ifaces;
+    fn->wifi_get_iface_name = wifi_get_iface_name;
+    fn->wifi_start_gscan = wifi_start_gscan;
+    fn->wifi_stop_gscan = wifi_stop_gscan;
+    fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results;
+    fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist;
+    fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist;
+    fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler;
+    fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler;
+    fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities;
+    fn->wifi_get_link_stats = wifi_get_link_stats;
+    fn->wifi_set_link_stats = wifi_set_link_stats;
+    fn->wifi_clear_link_stats = wifi_clear_link_stats;
+    fn->wifi_get_valid_channels = wifi_get_valid_channels;
+    fn->wifi_rtt_range_request = wifi_rtt_range_request;
+    fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel;
+    fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities;
+    fn->wifi_rtt_get_responder_info = wifi_rtt_get_responder_info;
+    fn->wifi_enable_responder = wifi_enable_responder;
+    fn->wifi_disable_responder = wifi_disable_responder;
+    fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag;
+    fn->wifi_start_logging = wifi_start_logging;
+    fn->wifi_set_epno_list = wifi_set_epno_list;
+    fn->wifi_reset_epno_list = wifi_reset_epno_list;
+    fn->wifi_set_country_code = wifi_set_country_code;
+    fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump;
+    fn->wifi_set_log_handler = wifi_set_log_handler;
+    fn->wifi_reset_log_handler = wifi_reset_log_handler;
+    fn->wifi_set_alert_handler = wifi_set_alert_handler;
+    fn->wifi_reset_alert_handler = wifi_reset_alert_handler;
+    fn->wifi_get_firmware_version = wifi_get_firmware_version;
+    fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status;
+    fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set;
+    fn->wifi_get_ring_data = wifi_get_ring_data;
+    fn->wifi_get_driver_version = wifi_get_driver_version;
+    fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring;
+    fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring;
+    fn->wifi_configure_nd_offload = wifi_configure_nd_offload;
+    fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet;
+    fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet;
+    fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring;
+    fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates;
+    fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates;
+    fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities;
+    fn->wifi_set_packet_filter = wifi_set_packet_filter;
+       fn->wifi_get_wake_reason_stats = wifi_get_wake_reason_stats;
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_initialize(wifi_handle *handle)
+{
+    srand(getpid());
+
+       ALOGI("Initializing wifi, version : %s", RTW_WIFI_HAL_VERSION);
+    hal_info *info = (hal_info *)malloc(sizeof(hal_info));
+    if (info == NULL) {
+        ALOGE("Could not allocate hal_info");
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    memset(info, 0, sizeof(*info));
+
+    ALOGI("Creating socket");
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, info->cleanup_socks) == -1) {
+        ALOGE("Could not create cleanup sockets");
+        free(info);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT);
+    if (cmd_sock == NULL) {
+        ALOGE("Could not create handle");
+        free(info);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    struct nl_sock *event_sock = wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT);
+    if (event_sock == NULL) {
+        ALOGE("Could not create handle");
+        nl_socket_free(cmd_sock);
+        free(info);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    struct nl_cb *cb = nl_socket_get_cb(event_sock);
+    if (cb == NULL) {
+        ALOGE("Could not create handle");
+        nl_socket_free(cmd_sock);
+        nl_socket_free(event_sock);
+        free(info);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    // ALOGI("cb->refcnt = %d", cb->cb_refcnt);
+    nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, internal_no_seq_check, info);
+    nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler, info);
+    nl_cb_put(cb);
+
+    info->cmd_sock = cmd_sock;
+    info->event_sock = event_sock;
+    info->clean_up = false;
+    info->in_event_loop = false;
+
+    info->event_cb = (cb_info *)malloc(sizeof(cb_info) * DEFAULT_EVENT_CB_SIZE);
+    info->alloc_event_cb = DEFAULT_EVENT_CB_SIZE;
+    info->num_event_cb = 0;
+
+    info->cmd = (cmd_info *)malloc(sizeof(cmd_info) * DEFAULT_CMD_SIZE);
+    info->alloc_cmd = DEFAULT_CMD_SIZE;
+    info->num_cmd = 0;
+
+    info->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211");
+    if (info->nl80211_family_id < 0) {
+        ALOGE("Could not resolve nl80211 familty id");
+        nl_socket_free(cmd_sock);
+        nl_socket_free(event_sock);
+        free(info);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    pthread_mutex_init(&info->cb_lock, NULL);
+
+    *handle = (wifi_handle) info;
+
+    if (wifi_init_interfaces(*handle) != WIFI_SUCCESS) {
+        ALOGE("No wifi interface found");
+        nl_socket_free(cmd_sock);
+        nl_socket_free(event_sock);
+        pthread_mutex_destroy(&info->cb_lock);
+        free(info);
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    if ((wifi_add_membership(*handle, "scan") < 0) ||
+        (wifi_add_membership(*handle, "mlme")  < 0) ||
+        (wifi_add_membership(*handle, "regulatory") < 0) ||
+        (wifi_add_membership(*handle, "vendor") < 0)) {
+        ALOGE("Add membership failed");
+        nl_socket_free(cmd_sock);
+        nl_socket_free(event_sock);
+        pthread_mutex_destroy(&info->cb_lock);
+        free(info);
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    // ALOGI("Found %d interfaces", info->num_interfaces);
+
+    ALOGI("Initialized Wifi HAL Successfully; vendor cmd = %d", NL80211_CMD_VENDOR);
+    return WIFI_SUCCESS;
+}
+
+static int wifi_add_membership(wifi_handle handle, const char *group)
+{
+    hal_info *info = getHalInfo(handle);
+
+    int id = wifi_get_multicast_id(handle, "nl80211", group);
+    if (id < 0) {
+        ALOGE("Could not find group %s", group);
+        return id;
+    }
+
+    int ret = nl_socket_add_membership(info->event_sock, id);
+    if (ret < 0) {
+        ALOGE("Could not add membership to group %s", group);
+    }
+
+    // ALOGI("Successfully added membership for group %s", group);
+    return ret;
+}
+
+static void internal_cleaned_up_handler(wifi_handle handle)
+{
+    hal_info *info = getHalInfo(handle);
+    wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler;
+
+    if (info->cmd_sock != 0) {
+        close(info->cleanup_socks[0]);
+        close(info->cleanup_socks[1]);
+        nl_socket_free(info->cmd_sock);
+        nl_socket_free(info->event_sock);
+        info->cmd_sock = NULL;
+        info->event_sock = NULL;
+    }
+
+    (*cleaned_up_handler)(handle);
+    pthread_mutex_destroy(&info->cb_lock);
+    free(info);
+
+    ALOGI("Internal cleanup completed");
+}
+
+void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)
+{
+    hal_info *info = getHalInfo(handle);
+    char buf[64];
+
+    info->cleaned_up_handler = handler;
+    if (TEMP_FAILURE_RETRY(write(info->cleanup_socks[0], "Exit", 4)) < 1) {
+        // As a fallback set the cleanup flag to TRUE
+        ALOGE("could not write to the cleanup socket");
+    } else {
+        // Listen to the response
+        // Hopefully we dont get errors or get hung up
+        // Not much can be done in that case, but assume that
+        // it has rx'ed the Exit message to exit the thread.
+        // As a fallback set the cleanup flag to TRUE
+        memset(buf, 0, sizeof(buf));
+        ssize_t result = TEMP_FAILURE_RETRY(read(info->cleanup_socks[0], buf, sizeof(buf)));
+        ALOGE("%s: Read after POLL returned %zd, error no = %d (%s)", __FUNCTION__,
+               result, errno, strerror(errno));
+        if (strncmp(buf, "Done", 4) == 0) {
+            ALOGE("Event processing terminated");
+        } else {
+            ALOGD("Rx'ed %s", buf);
+        }
+    }
+    info->clean_up = true;
+    pthread_mutex_lock(&info->cb_lock);
+
+    int bad_commands = 0;
+
+    for (int i = 0; i < info->num_event_cb; i++) {
+        cb_info *cbi = &(info->event_cb[i]);
+        WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
+        ALOGI("Command left in event_cb %p:%s", cmd, (cmd ? cmd->getType(): ""));
+    }
+
+    while (info->num_cmd > bad_commands) {
+        int num_cmd = info->num_cmd;
+        cmd_info *cmdi = &(info->cmd[bad_commands]);
+        WifiCommand *cmd = cmdi->cmd;
+        if (cmd != NULL) {
+            ALOGI("Cancelling command %p:%s", cmd, cmd->getType());
+            pthread_mutex_unlock(&info->cb_lock);
+            cmd->cancel();
+            pthread_mutex_lock(&info->cb_lock);
+            if (num_cmd == info->num_cmd) {
+                ALOGI("Cancelling command %p:%s did not work", cmd, (cmd ? cmd->getType(): ""));
+                bad_commands++;
+            }
+            /* release reference added when command is saved */
+            cmd->releaseRef();
+        }
+    }
+
+    for (int i = 0; i < info->num_event_cb; i++) {
+        cb_info *cbi = &(info->event_cb[i]);
+        WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
+        ALOGE("Leaked command %p", cmd);
+    }
+    pthread_mutex_unlock(&info->cb_lock);
+    internal_cleaned_up_handler(handle);
+}
+
+static int internal_pollin_handler(wifi_handle handle)
+{
+    hal_info *info = getHalInfo(handle);
+    struct nl_cb *cb = nl_socket_get_cb(info->event_sock);
+    int res = nl_recvmsgs(info->event_sock, cb);
+    // ALOGD("nl_recvmsgs returned %d", res);
+    nl_cb_put(cb);
+    return res;
+}
+
+/* Run event handler */
+void wifi_event_loop(wifi_handle handle)
+{
+    hal_info *info = getHalInfo(handle);
+    if (info->in_event_loop) {
+        return;
+    } else {
+        info->in_event_loop = true;
+    }
+
+    pollfd pfd[2];
+    memset(&pfd[0], 0, sizeof(pollfd) * 2);
+
+    pfd[0].fd = nl_socket_get_fd(info->event_sock);
+    pfd[0].events = POLLIN;
+    pfd[1].fd = info->cleanup_socks[1];
+    pfd[1].events = POLLIN;
+
+    char buf[2048];
+    /* TODO: Add support for timeouts */
+
+    do {
+        int timeout = -1;                   /* Infinite timeout */
+        pfd[0].revents = 0;
+        pfd[1].revents = 0;
+        // ALOGI("Polling socket");
+        int result = TEMP_FAILURE_RETRY(poll(pfd, 2, timeout));
+        if (result < 0) {
+            // ALOGE("Error polling socket");
+        } else if (pfd[0].revents & POLLERR) {
+            ALOGE("POLL Error; error no = %d (%s)", errno, strerror(errno));
+            ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[0].fd, buf, sizeof(buf)));
+            ALOGE("Read after POLL returned %zd, error no = %d (%s)", result2,
+                  errno, strerror(errno));
+        } else if (pfd[0].revents & POLLHUP) {
+            ALOGE("Remote side hung up");
+            break;
+        } else if (pfd[0].revents & POLLIN) {
+            // ALOGI("Found some events!!!");
+            internal_pollin_handler(handle);
+        } else if (pfd[1].revents & POLLIN) {
+            memset(buf, 0, sizeof(buf));
+            ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[1].fd, buf, sizeof(buf)));
+            ALOGE("%s: Read after POLL returned %zd, error no = %d (%s)", __FUNCTION__,
+                   result2, errno, strerror(errno));
+            if (strncmp(buf, "Exit", 4) == 0) {
+                ALOGD("Got a signal to exit!!!");
+                if (TEMP_FAILURE_RETRY(write(pfd[1].fd, "Done", 4)) < 1) {
+                    ALOGE("could not write to the cleanup socket");
+                }
+                break;
+            } else {
+                ALOGD("Rx'ed %s on the cleanup socket\n", buf);
+            }
+        } else {
+            ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents);
+        }
+    } while (!info->clean_up);
+    ALOGI("Exit %s", __FUNCTION__);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+static int internal_no_seq_check(struct nl_msg *msg, void *arg)
+{
+    return NL_OK;
+}
+
+static int internal_valid_message_handler(nl_msg *msg, void *arg)
+{
+    // ALOGI("got an event");
+
+    wifi_handle handle = (wifi_handle)arg;
+    hal_info *info = getHalInfo(handle);
+
+    WifiEvent event(msg);
+    int res = event.parse();
+    if (res < 0) {
+        ALOGE("Failed to parse event: %d", res);
+        return NL_SKIP;
+    }
+
+    int cmd = event.get_cmd();
+    uint32_t vendor_id = 0;
+    int subcmd = 0;
+
+    if (cmd == NL80211_CMD_VENDOR) {
+        vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID);
+        subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD);
+        ALOGV("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x",
+                event.get_cmdString(), vendor_id, subcmd);
+    } else {
+        // ALOGV("event received %s", event.get_cmdString());
+    }
+
+    // ALOGV("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id);
+    // event.log();
+
+    bool dispatched = false;
+
+    pthread_mutex_lock(&info->cb_lock);
+
+    for (int i = 0; i < info->num_event_cb; i++) {
+        if (cmd == info->event_cb[i].nl_cmd) {
+            if (cmd == NL80211_CMD_VENDOR
+                && ((vendor_id != info->event_cb[i].vendor_id)
+                || (subcmd != info->event_cb[i].vendor_subcmd)))
+            {
+                /* event for a different vendor, ignore it */
+                continue;
+            }
+
+            cb_info *cbi = &(info->event_cb[i]);
+            nl_recvmsg_msg_cb_t cb_func = cbi->cb_func;
+            void *cb_arg = cbi->cb_arg;
+            WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
+            if (cmd != NULL) {
+                cmd->addRef();
+            }
+            pthread_mutex_unlock(&info->cb_lock);
+            if (cb_func)
+                (*cb_func)(msg, cb_arg);
+            if (cmd != NULL) {
+                cmd->releaseRef();
+            }
+
+            return NL_OK;
+        }
+    }
+
+    pthread_mutex_unlock(&info->cb_lock);
+    return NL_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+class GetMulticastIdCommand : public WifiCommand
+{
+private:
+    const char *mName;
+    const char *mGroup;
+    int   mId;
+public:
+    GetMulticastIdCommand(wifi_handle handle, const char *name, const char *group)
+        : WifiCommand("GetMulticastIdCommand", handle, 0)
+    {
+        mName = name;
+        mGroup = group;
+        mId = -1;
+    }
+
+    int getId() {
+        return mId;
+    }
+
+    virtual int create() {
+        int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl");
+        // ALOGI("ctrl family = %d", nlctrlFamily);
+        int ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0);
+        if (ret < 0) {
+            return ret;
+        }
+        ret = mMsg.put_string(CTRL_ATTR_FAMILY_NAME, mName);
+        return ret;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+
+        // ALOGI("handling reponse in %s", __func__);
+
+        struct nlattr **tb = reply.attributes();
+        struct genlmsghdr *gnlh = reply.header();
+        struct nlattr *mcgrp = NULL;
+        int i;
+
+        if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
+            ALOGI("No multicast groups found");
+            return NL_SKIP;
+        } else {
+            // ALOGI("Multicast groups attr size = %d", nla_len(tb[CTRL_ATTR_MCAST_GROUPS]));
+        }
+
+        for_each_attr(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
+
+            // ALOGI("Processing group");
+            struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
+            nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, (nlattr *)nla_data(mcgrp),
+                nla_len(mcgrp), NULL);
+            if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || !tb2[CTRL_ATTR_MCAST_GRP_ID]) {
+                continue;
+            }
+
+            char *grpName = (char *)nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
+            int grpNameLen = nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
+
+            // ALOGI("Found group name %s", grpName);
+
+            if (strncmp(grpName, mGroup, grpNameLen) != 0)
+                continue;
+
+            mId = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
+            break;
+        }
+
+        return NL_SKIP;
+    }
+
+};
+
+class SetPnoMacAddrOuiCommand : public WifiCommand {
+
+private:
+    byte *mOui;
+    feature_set *fset;
+    feature_set *feature_matrix;
+    int *fm_size;
+    int set_size_max;
+public:
+    SetPnoMacAddrOuiCommand(wifi_interface_handle handle, oui scan_oui)
+        : WifiCommand("SetPnoMacAddrOuiCommand", handle, 0)
+    {
+        mOui = scan_oui;
+    }
+
+    int createRequest(WifiRequest& request, int subcmd, byte *scan_oui) {
+        int result = request.create(GOOGLE_OUI, subcmd);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put(ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, scan_oui, DOT11_OUI_LEN);
+        if (result < 0) {
+            return result;
+        }
+
+        request.attr_end(data);
+        return WIFI_SUCCESS;
+
+    }
+
+    int start() {
+        ALOGD("Sending mac address OUI");
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request, WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, mOui);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create request; result = %d", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to set scanning mac OUI; result = %d", result);
+        }
+
+        return result;
+    }
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+         ALOGD("Request complete!");
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+};
+
+class SetNodfsCommand : public WifiCommand {
+
+private:
+    u32 mNoDfs;
+public:
+    SetNodfsCommand(wifi_interface_handle handle, u32 nodfs)
+        : WifiCommand("SetNodfsCommand", handle, 0) {
+        mNoDfs = nodfs;
+    }
+    virtual int create() {
+        int ret;
+
+        ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_NODFS_SET);
+        if (ret < 0) {
+            ALOGE("Can't create message to send to driver - %d", ret);
+            return ret;
+        }
+
+        nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
+        ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_NODFS_SET, mNoDfs);
+        if (ret < 0) {
+             return ret;
+        }
+
+        mMsg.attr_end(data);
+        return WIFI_SUCCESS;
+    }
+};
+
+class SetCountryCodeCommand : public WifiCommand {
+private:
+    const char *mCountryCode;
+public:
+    SetCountryCodeCommand(wifi_interface_handle handle, const char *country_code)
+        : WifiCommand("SetCountryCodeCommand", handle, 0) {
+        mCountryCode = country_code;
+        }
+    virtual int create() {
+        int ret;
+
+        ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_COUNTRY_CODE);
+        if (ret < 0) {
+             ALOGE("Can't create message to send to driver - %d", ret);
+             return ret;
+        }
+
+        nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
+        ret = mMsg.put_string(ANDR_WIFI_ATTRIBUTE_COUNTRY, mCountryCode);
+        if (ret < 0) {
+            return ret;
+        }
+
+        mMsg.attr_end(data);
+        return WIFI_SUCCESS;
+
+    }
+};
+
+class SetRSSIMonitorCommand : public WifiCommand {
+private:
+    s8 mMax_rssi;
+    s8 mMin_rssi;
+    wifi_rssi_event_handler mHandler;
+public:
+    SetRSSIMonitorCommand(wifi_request_id id, wifi_interface_handle handle,
+                s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
+        : WifiCommand("SetRSSIMonitorCommand", handle, id), mMax_rssi(max_rssi), mMin_rssi
+        (min_rssi), mHandler(eh)
+        {
+        }
+   int createRequest(WifiRequest& request, int enable) {
+        int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0));
+        if (result < 0) {
+            return result;
+        }
+        ALOGD("create request");
+        result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0));
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_START, enable);
+        if (result < 0) {
+            return result;
+        }
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request, 1);
+        if (result < 0) {
+            return result;
+        }
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGI("Failed to set RSSI Monitor, result = %d", result);
+            return result;
+        }
+        ALOGI("Successfully set RSSI monitoring");
+        registerVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
+
+
+        if (result < 0) {
+            unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
+            return result;
+        }
+        ALOGI("Done!");
+        return result;
+    }
+
+    virtual int cancel() {
+
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request, 0);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create request; result = %d", result);
+        } else {
+            result = requestResponse(request);
+            if (result != WIFI_SUCCESS) {
+                ALOGE("failed to stop RSSI monitoring = %d", result);
+            }
+        }
+        unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+   virtual int handleEvent(WifiEvent& event) {
+        ALOGI("Got a RSSI monitor event");
+
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = event.get_vendor_data_len();
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGI("RSSI monitor: No data");
+            return NL_SKIP;
+        }
+        /* driver<->HAL event structure */
+        #define RSSI_MONITOR_EVT_VERSION   1
+        typedef struct {
+            u8 version;
+            s8 cur_rssi;
+            mac_addr BSSID;
+        } rssi_monitor_evt;
+
+        rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data();
+
+        if (data->version != RSSI_MONITOR_EVT_VERSION) {
+            ALOGI("Event version mismatch %d, expected %d", data->version, RSSI_MONITOR_EVT_VERSION);
+            return NL_SKIP;
+        }
+
+        if (*mHandler.on_rssi_threshold_breached) {
+            (*mHandler.on_rssi_threshold_breached)(id(), data->BSSID, data->cur_rssi);
+        } else {
+            ALOGW("No RSSI monitor handler registered");
+        }
+
+        return NL_SKIP;
+    }
+
+};
+
+class AndroidPktFilterCommand : public WifiCommand {
+    private:
+        const u8* mProgram;
+        u32 mProgramLen;
+        u32* mVersion;
+        u32* mMaxLen;
+        int mReqType;
+    public:
+        AndroidPktFilterCommand(wifi_interface_handle handle,
+                u32* version, u32* max_len)
+            : WifiCommand("AndroidPktFilterCommand", handle, 0),
+                    mVersion(version), mMaxLen(max_len),
+                    mReqType(GET_APF_CAPABILITIES)
+        {
+        }
+
+        AndroidPktFilterCommand(wifi_interface_handle handle,
+                const u8* program, u32 len)
+            : WifiCommand("AndroidPktFilterCommand", handle, 0),
+                    mProgram(program), mProgramLen(len),
+                    mReqType(SET_APF_PROGRAM)
+        {
+        }
+
+    int createRequest(WifiRequest& request) {
+        if (mReqType == SET_APF_PROGRAM) {
+            ALOGI("\n%s: APF set program request\n", __FUNCTION__);
+            return createSetPktFilterRequest(request);
+        } else if (mReqType == GET_APF_CAPABILITIES) {
+            ALOGI("\n%s: APF get capabilities request\n", __FUNCTION__);
+            return createGetPktFilterCapabilitesRequest(request);
+        } else {
+            ALOGE("\n%s Unknown APF request\n", __FUNCTION__);
+            return WIFI_ERROR_NOT_SUPPORTED;
+        }
+        return WIFI_SUCCESS;
+    }
+
+    int createSetPktFilterRequest(WifiRequest& request) {
+        u8 *program = new u8[mProgramLen];
+        NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        int result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(APF_ATTRIBUTE_PROGRAM_LEN, mProgramLen);
+        if (result < 0) {
+            return result;
+        }
+        memcpy(program, mProgram, mProgramLen);
+        result = request.put(APF_ATTRIBUTE_PROGRAM, program, mProgramLen);
+        if (result < 0) {
+            return result;
+        }
+        request.attr_end(data);
+        delete[] program;
+        return result;
+    }
+
+    int createGetPktFilterCapabilitesRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, APF_SUBCMD_GET_CAPABILITIES);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request);
+        if (result < 0) {
+            return result;
+        }
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGI("Request Response failed for APF, result = %d", result);
+            return result;
+        }
+        ALOGI("Done!");
+        return result;
+    }
+
+    int cancel() {
+        return WIFI_SUCCESS;
+    }
+
+    int handleResponse(WifiEvent& reply) {
+        ALOGD("In SetAPFCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = reply.get_vendor_data_len();
+
+        ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("no vendor data in SetAPFCommand response; ignoring it");
+            return NL_SKIP;
+        }
+        if( mReqType == SET_APF_PROGRAM) {
+            ALOGD("Response recieved for set packet filter command\n");
+        } else if (mReqType == GET_APF_CAPABILITIES) {
+            *mVersion = 0;
+            *mMaxLen = 0;
+            ALOGD("Response recieved for get packet filter capabilities command\n");
+            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                if (it.get_type() == APF_ATTRIBUTE_VERSION) {
+                    *mVersion = it.get_u32();
+                    ALOGI("APF version is %d\n", *mVersion);
+                } else if (it.get_type() == APF_ATTRIBUTE_MAX_LEN) {
+                    *mMaxLen = it.get_u32();
+                    ALOGI("APF max len is %d\n", *mMaxLen);
+                } else {
+                    ALOGE("Ignoring invalid attribute type = %d, size = %d",
+                            it.get_type(), it.get_len());
+                }
+            }
+        }
+        return NL_OK;
+    }
+
+    int handleEvent(WifiEvent& event) {
+        /* No Event to recieve for APF commands */
+        return NL_SKIP;
+    }
+};
+
+class SetNdoffloadCommand : public WifiCommand {
+
+private:
+    u8 mEnable;
+public:
+    SetNdoffloadCommand(wifi_interface_handle handle, u8 enable)
+        : WifiCommand("SetNdoffloadCommand", handle, 0) {
+        mEnable = enable;
+    }
+    virtual int create() {
+        int ret;
+
+        ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_ND_OFFLOAD);
+        if (ret < 0) {
+            ALOGE("Can't create message to send to driver - %d", ret);
+            return ret;
+        }
+
+        nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
+        ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE, mEnable);
+        if (ret < 0) {
+             return ret;
+        }
+
+        mMsg.attr_end(data);
+        return WIFI_SUCCESS;
+    }
+};
+
+class GetFeatureSetCommand : public WifiCommand {
+
+private:
+    int feature_type;
+    feature_set *fset;
+    feature_set *feature_matrix;
+    int *fm_size;
+    int set_size_max;
+public:
+    GetFeatureSetCommand(wifi_interface_handle handle, int feature, feature_set *set,
+         feature_set set_matrix[], int *size, int max_size)
+        : WifiCommand("GetFeatureSetCommand", handle, 0)
+    {
+        feature_type = feature;
+        fset = set;
+        feature_matrix = set_matrix;
+        fm_size = size;
+        set_size_max = max_size;
+    }
+
+    virtual int create() {
+        int ret;
+
+        if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
+            ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET);
+        } else if (feature_type == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) {
+            ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET_MATRIX);
+        } else {
+            ALOGE("Unknown feature type %d", feature_type);
+            return -1;
+        }
+
+        if (ret < 0) {
+            ALOGE("Can't create message to send to driver - %d", ret);
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        ALOGV("In GetFeatureSetCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = reply.get_vendor_data_len();
+
+        ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("no vendor data in GetFeatureSetCommand response; ignoring it");
+            return NL_SKIP;
+        }
+        if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
+            void *data = reply.get_vendor_data();
+            if(!fset) {
+                ALOGE("Buffers pointers not set");
+                return NL_SKIP;
+            }
+            memcpy(fset, data, min(len, (int) sizeof(*fset)));
+        } else {
+            int num_features_set = 0;
+            int i = 0;
+
+            if(!feature_matrix || !fm_size) {
+                ALOGE("Buffers pointers not set");
+                return NL_SKIP;
+            }
+
+            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                if (it.get_type() == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
+                    num_features_set = it.get_u32();
+                    ALOGV("Got feature list with %d concurrent sets", num_features_set);
+                    if(set_size_max && (num_features_set > set_size_max))
+                        num_features_set = set_size_max;
+                    *fm_size = num_features_set;
+                } else if ((it.get_type() == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) &&
+                             i < num_features_set) {
+                    feature_matrix[i] = it.get_u32();
+                    i++;
+                } else {
+                    ALOGW("Ignoring invalid attribute type = %d, size = %d",
+                            it.get_type(), it.get_len());
+                }
+            }
+
+        }
+        return NL_OK;
+    }
+
+};
+
+static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group)
+{
+    GetMulticastIdCommand cmd(handle, name, group);
+    int res = cmd.requestResponse();
+    if (res < 0)
+        return res;
+    else
+        return cmd.getId();
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static bool is_wifi_interface(const char *name)
+{
+    if (strncmp(name, "wlan", 4) != 0 && strncmp(name, "p2p", 3) != 0) {
+        /* not a wifi interface; ignore it */
+        return false;
+    } else {
+        return true;
+    }
+}
+
+static int get_interface(const char *name, interface_info *info)
+{
+    strcpy(info->name, name);
+    info->id = if_nametoindex(name);
+    // ALOGI("found an interface : %s, id = %d", name, info->id);
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_init_interfaces(wifi_handle handle)
+{
+    hal_info *info = (hal_info *)handle;
+
+    struct dirent *de;
+
+    DIR *d = opendir("/sys/class/net");
+    if (d == 0)
+        return WIFI_ERROR_UNKNOWN;
+
+    int n = 0;
+    while ((de = readdir(d))) {
+        if (de->d_name[0] == '.')
+            continue;
+        if (is_wifi_interface(de->d_name) ) {
+            n++;
+        }
+    }
+
+    closedir(d);
+
+    if (n == 0)
+        return WIFI_ERROR_NOT_AVAILABLE;
+
+    d = opendir("/sys/class/net");
+    if (d == 0)
+        return WIFI_ERROR_UNKNOWN;
+
+    info->interfaces = (interface_info **)malloc(sizeof(interface_info *) * n);
+
+    int i = 0;
+    while ((de = readdir(d))) {
+        if (de->d_name[0] == '.')
+            continue;
+        if (is_wifi_interface(de->d_name)) {
+            interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info));
+            if (get_interface(de->d_name, ifinfo) != WIFI_SUCCESS) {
+                free(ifinfo);
+                continue;
+            }
+            ifinfo->handle = handle;
+            info->interfaces[i] = ifinfo;
+            i++;
+        }
+    }
+
+    closedir(d);
+
+    info->num_interfaces = n;
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_get_ifaces(wifi_handle handle, int *num, wifi_interface_handle **interfaces)
+{
+    hal_info *info = (hal_info *)handle;
+
+    *interfaces = (wifi_interface_handle *)info->interfaces;
+    *num = info->num_interfaces;
+
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t size)
+{
+    interface_info *info = (interface_info *)handle;
+    strcpy(name, info->name);
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
+{
+    GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, set, NULL, NULL, 1);
+    return (wifi_error) command.requestResponse();
+}
+
+wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
+       feature_set set[], int *set_size)
+{
+    GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, NULL,
+            set, set_size, set_size_max);
+    return (wifi_error) command.requestResponse();
+}
+
+wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui)
+{
+    SetPnoMacAddrOuiCommand command(handle, scan_oui);
+    return (wifi_error)command.start();
+}
+
+wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs)
+{
+    SetNodfsCommand command(handle, nodfs);
+    return (wifi_error) command.requestResponse();
+}
+
+wifi_error wifi_set_country_code(wifi_interface_handle handle, const char *country_code)
+{
+    SetCountryCodeCommand command(handle, country_code);
+    return (wifi_error) command.requestResponse();
+}
+
+static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
+                        iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
+{
+    ALOGD("Start RSSI monitor %d", id);
+    wifi_handle handle = getWifiHandle(iface);
+    SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, max_rssi, min_rssi, eh);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return WIFI_ERROR_UNKNOWN;
+}
+
+static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface)
+{
+    ALOGD("Stopping RSSI monitor");
+
+    if(id == -1) {
+        wifi_rssi_event_handler handler;
+        s8 max_rssi = 0, min_rssi = 0;
+        wifi_handle handle = getWifiHandle(iface);
+        memset(&handler, 0, sizeof(handler));
+        SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface,
+                                                    max_rssi, min_rssi, handler);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+       wifi_cancel_cmd(id, iface);
+    return WIFI_ERROR_UNKNOWN;
+}
+
+static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
+        u32 *version, u32 *max_len)
+{
+#if 0
+    ALOGD("Getting APF capabilities, halHandle = %p\n", handle);
+    AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, version, max_len);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    if (result == WIFI_SUCCESS) {
+        ALOGD("Getting APF capability, version = %d, max_len = %d\n", *version, *max_len);
+    }
+    cmd->releaseRef();
+    return result;
+#endif
+       return WIFI_SUCCESS;
+}
+
+static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
+        const u8 *program, u32 len)
+{
+    ALOGD("Setting APF program, halHandle = %p\n", handle);
+    AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, program, len);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
+
+static wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable)
+{
+    SetNdoffloadCommand command(handle, enable);
+    return (wifi_error) command.requestResponse();
+}
+
+static wifi_error wifi_get_wake_reason_stats (wifi_interface_handle handle,
+                                WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt) {
+                                
+       return WIFI_SUCCESS;
+}
+/////////////////////////////////////////////////////////////////////////////
diff --git a/wlan/wifi_hal/rtw_wifi_llstats.cpp b/wlan/wifi_hal/rtw_wifi_llstats.cpp
new file mode 100644 (file)
index 0000000..93efb54
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink/handlers.h>
+
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL"
+
+#include <log/log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+/* Internal radio statistics structure in the driver */
+typedef struct {
+       wifi_radio radio;
+       uint32_t on_time;
+       uint32_t tx_time;
+       uint32_t rx_time;
+       uint32_t on_time_scan;
+       uint32_t on_time_nbd;
+       uint32_t on_time_gscan;
+       uint32_t on_time_roam_scan;
+       uint32_t on_time_pno_scan;
+       uint32_t on_time_hs20;
+       uint32_t num_channels;
+       wifi_channel_stat channels[];
+} wifi_radio_stat_internal;
+
+enum {
+    LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START,
+};
+
+class GetLinkStatsCommand : public WifiCommand
+{
+    wifi_stats_result_handler mHandler;
+public:
+    GetLinkStatsCommand(wifi_interface_handle iface, wifi_stats_result_handler handler)
+        : WifiCommand("GetLinkStatsCommand", iface, 0), mHandler(handler)
+    { }
+
+    virtual int create() {
+        // ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
+
+        int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_GET_INFO);
+        if (ret < 0) {
+            ALOGE("Failed to create %x - %d", LSTATS_SUBCMD_GET_INFO, ret);
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        // ALOGI("In GetLinkStatsCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        // ALOGI("Id = %0x, subcmd = %d", id, subcmd);
+
+        void *data = reply.get_vendor_data();
+        int len = reply.get_vendor_data_len();
+               wifi_radio_stat *radio_stat =
+            convertToExternalRadioStatStructure((wifi_radio_stat_internal *)data);
+        if (!radio_stat) {
+            ALOGE("Invalid stats pointer received");
+            return NL_SKIP;
+        }
+
+#ifdef CONFIG_WIFI_HAL_DEBUG 
+               ALOGE("radio: = %d", radio_stat->radio);
+        ALOGE("on_time: = %u ms", radio_stat->on_time);
+        ALOGE("tx_time: = %u ms", radio_stat->tx_time);
+               ALOGE("num_tx_levels: = %u", radio_stat->num_tx_levels);
+        ALOGE("rx_time: = %u ms", radio_stat->rx_time);
+        ALOGE("on_time_scan: = %u ms", radio_stat->on_time_scan);
+        ALOGE("on_time_nbd: = %u ms", radio_stat->on_time_nbd);
+        ALOGE("on_time_gscan: = %u ms", radio_stat->on_time_gscan);
+        ALOGE("on_time_pno_scan: = %u ms", radio_stat->on_time_pno_scan);
+        ALOGE("on_time_hs20: = %u ms", radio_stat->on_time_hs20);
+#endif
+        if (!radio_stat) {
+            ALOGE("Invalid stats pointer received");
+            return NL_SKIP;
+        }
+        if (radio_stat->num_channels > 11) {
+            ALOGE("Incorrect number of channels = %d", radio_stat->num_channels);
+            // dump data before num_channels
+            ALOGE("radio: = %d", radio_stat->radio);
+            ALOGE("on_time: = %u ms", radio_stat->on_time);
+            ALOGE("tx_time: = %u ms", radio_stat->tx_time);
+            ALOGE("rx_time: = %u ms", radio_stat->rx_time);
+            ALOGE("on_time_scan: = %u ms", radio_stat->on_time_scan);
+            ALOGE("on_time_nbd: = %u ms", radio_stat->on_time_nbd);
+            ALOGE("on_time_gscan: = %u ms", radio_stat->on_time_gscan);
+            ALOGE("on_time_pno_scan: = %u ms", radio_stat->on_time_pno_scan);
+            ALOGE("on_time_hs20: = %u ms", radio_stat->on_time_hs20);
+            free(radio_stat);
+            return NL_SKIP;
+        }
+               wifi_iface_stat *iface_stat = NULL;
+               iface_stat = (wifi_iface_stat *)((char* )data + sizeof(wifi_radio_stat));
+
+               if(*mHandler.on_link_stats_results == NULL) {
+                       ALOGE("*mHandler.on_link_stats_results is NULL");
+               } else {
+               (*mHandler.on_link_stats_results)(id, iface_stat, 1, radio_stat);
+               }
+        free(radio_stat);
+        return NL_OK;
+    }
+private:
+    wifi_radio_stat *convertToExternalRadioStatStructure(wifi_radio_stat_internal *internal_stat_ptr) {
+        wifi_radio_stat *external_stat_ptr = NULL;
+        if (internal_stat_ptr) {
+            uint32_t channel_size = internal_stat_ptr->num_channels * sizeof(wifi_channel_stat);
+            uint32_t total_size = sizeof(wifi_radio_stat) + channel_size;
+            external_stat_ptr = (wifi_radio_stat *)malloc(total_size);
+            if (external_stat_ptr) {
+                external_stat_ptr->radio = internal_stat_ptr->radio;
+                external_stat_ptr->on_time = internal_stat_ptr->on_time;
+                external_stat_ptr->tx_time = internal_stat_ptr->tx_time;
+                external_stat_ptr->rx_time = internal_stat_ptr->rx_time;
+                external_stat_ptr->tx_time_per_levels = NULL;
+                external_stat_ptr->num_tx_levels = 0;
+                external_stat_ptr->on_time_scan = internal_stat_ptr->on_time_scan;
+                external_stat_ptr->on_time_nbd = internal_stat_ptr->on_time_nbd;
+                external_stat_ptr->on_time_gscan = internal_stat_ptr->on_time_gscan;
+                external_stat_ptr->on_time_roam_scan = internal_stat_ptr->on_time_roam_scan;
+                external_stat_ptr->on_time_pno_scan = internal_stat_ptr->on_time_pno_scan;
+                external_stat_ptr->on_time_hs20 = internal_stat_ptr->on_time_hs20;
+                external_stat_ptr->num_channels = internal_stat_ptr->num_channels;
+                if (internal_stat_ptr->num_channels) {
+                    memcpy(&(external_stat_ptr->channels), &(internal_stat_ptr->channels),
+                        channel_size);
+                }
+            }
+        }
+        return external_stat_ptr;
+    }
+
+};
+
+wifi_error wifi_get_link_stats(wifi_request_id id,
+        wifi_interface_handle iface, wifi_stats_result_handler handler)
+{
+    GetLinkStatsCommand command(iface, handler);
+    return (wifi_error) command.requestResponse();
+}
+
+wifi_error wifi_set_link_stats(
+        wifi_interface_handle /* iface */, wifi_link_layer_params /* params */)
+{
+    /* Return success here since bcom HAL does not need set link stats. */
+    return WIFI_SUCCESS;
+}
+
+wifi_error wifi_clear_link_stats(
+        wifi_interface_handle /* iface */, u32 /* stats_clear_req_mask */,
+        u32 * /* stats_clear_rsp_mask */, u8 /* stop_req */, u8 * /* stop_rsp */)
+{
+    /* Return success here since bcom HAL does not support clear link stats. */
+    return WIFI_SUCCESS;
+}
diff --git a/wlan/wifi_hal/rtw_wifi_logger.cpp b/wlan/wifi_hal/rtw_wifi_logger.cpp
new file mode 100644 (file)
index 0000000..2e214dd
--- /dev/null
@@ -0,0 +1,1107 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <string>
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink-private/object-api.h>
+#include <netlink-private/types.h>
+
+#include "nl80211_copy.h"
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL"
+
+#include <log/log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+typedef enum {
+    LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START,
+    LOGGER_TRIGGER_MEM_DUMP,
+    LOGGER_GET_MEM_DUMP,
+    LOGGER_GET_VER,
+    LOGGER_GET_RING_STATUS,
+    LOGGER_GET_RING_DATA,
+    LOGGER_GET_FEATURE,
+    LOGGER_RESET_LOGGING,
+    LOGGER_TRIGGER_DRIVER_MEM_DUMP,
+    LOGGER_GET_DRIVER_MEM_DUMP,
+    LOGGER_START_PKT_FATE_MONITORING,
+    LOGGER_GET_TX_PKT_FATES,
+    LOGGER_GET_RX_PKT_FATES,
+} DEBUG_SUB_COMMAND;
+
+typedef enum {
+    LOGGER_ATTRIBUTE_DRIVER_VER,
+    LOGGER_ATTRIBUTE_FW_VER,
+    LOGGER_ATTRIBUTE_RING_ID,
+    LOGGER_ATTRIBUTE_RING_NAME,
+    LOGGER_ATTRIBUTE_RING_FLAGS,
+    LOGGER_ATTRIBUTE_LOG_LEVEL,
+    LOGGER_ATTRIBUTE_LOG_TIME_INTVAL,
+    LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE,
+    LOGGER_ATTRIBUTE_FW_DUMP_LEN,
+    LOGGER_ATTRIBUTE_FW_DUMP_DATA,
+    // LOGGER_ATTRIBUTE_FW_ERR_CODE,
+    LOGGER_ATTRIBUTE_RING_DATA,
+    LOGGER_ATTRIBUTE_RING_STATUS,
+    LOGGER_ATTRIBUTE_RING_NUM,
+    LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN,
+    LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA,
+    LOGGER_ATTRIBUTE_PKT_FATE_NUM,
+    LOGGER_ATTRIBUTE_PKT_FATE_DATA,
+} LOGGER_ATTRIBUTE;
+
+typedef enum {
+    DEBUG_OFF = 0,
+    DEBUG_NORMAL,
+    DEBUG_VERBOSE,
+    DEBUG_VERY,
+    DEBUG_VERY_VERY,
+} LOGGER_LEVEL;
+
+typedef enum {
+    GET_FW_VER,
+    GET_DRV_VER,
+    GET_RING_DATA,
+    GET_RING_STATUS,
+    GET_FEATURE,
+    START_RING_LOG,
+} GetCmdType;
+
+typedef enum {
+    PACKET_MONITOR_START,
+    TX_PACKET_FATE,
+    RX_PACKET_FATE,
+} PktFateReqType;
+
+
+///////////////////////////////////////////////////////////////////////////////
+class DebugCommand : public WifiCommand
+{
+    char *mBuff;
+    int *mBuffSize;
+    u32 *mNumRings;
+    wifi_ring_buffer_status *mStatus;
+    unsigned int *mSupport;
+    u32 mVerboseLevel;
+    u32 mFlags;
+    u32 mMaxIntervalSec;
+    u32 mMinDataSize;
+    char *mRingName;
+    GetCmdType mType;
+
+public:
+
+    // constructor for get version
+    DebugCommand(wifi_interface_handle iface, char *buffer, int *buffer_size,
+            GetCmdType cmdType)
+        : WifiCommand("DebugCommand", iface, 0), mBuff(buffer), mBuffSize(buffer_size), mType
+        (cmdType)
+    {
+        memset(mBuff, 0, *mBuffSize);
+    }
+
+    // constructor for ring data
+    DebugCommand(wifi_interface_handle iface, char *ring_name, GetCmdType cmdType)
+        : WifiCommand("DebugCommand", iface, 0), mRingName(ring_name), mType(cmdType)
+    { }
+
+    // constructor for ring status
+    DebugCommand(wifi_interface_handle iface, u32 *num_rings,
+            wifi_ring_buffer_status *status, GetCmdType cmdType)
+        : WifiCommand("DebugCommand", iface, 0), mNumRings(num_rings), mStatus(status), mType(cmdType)
+    {
+        memset(mStatus, 0, sizeof(wifi_ring_buffer_status) * (*mNumRings));
+    }
+
+    // constructor for feature set
+    DebugCommand(wifi_interface_handle iface, unsigned int *support, GetCmdType cmdType)
+        : WifiCommand("DebugCommand", iface, 0), mSupport(support), mType(cmdType)
+    { }
+
+    // constructor for ring params
+    DebugCommand(wifi_interface_handle iface, u32 verbose_level, u32 flags,
+            u32 max_interval_sec, u32 min_data_size, char *ring_name, GetCmdType cmdType)
+        : WifiCommand("DebugCommand", iface, 0), mVerboseLevel(verbose_level), mFlags(flags),
+        mMaxIntervalSec(max_interval_sec), mMinDataSize(min_data_size),
+        mRingName(ring_name), mType(cmdType)
+    { }
+
+    int createRingRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, LOGGER_START_LOGGING);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to create start ring logger request; result = %d", result);
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        result = request.put_u32(LOGGER_ATTRIBUTE_LOG_LEVEL, mVerboseLevel);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to put log level; result = %d", result);
+            return result;
+        }
+        result = request.put_u32(LOGGER_ATTRIBUTE_RING_FLAGS, mFlags);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to put ring flags; result = %d", result);
+            return result;
+        }
+        result = request.put_u32(LOGGER_ATTRIBUTE_LOG_TIME_INTVAL, mMaxIntervalSec);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to put log time interval; result = %d", result);
+            return result;
+        }
+        result = request.put_u32(LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE, mMinDataSize);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to put min data size; result = %d", result);
+            return result;
+        }
+        result = request.put_string(LOGGER_ATTRIBUTE_RING_NAME, mRingName);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to put ringbuffer name; result = %d", result);
+            return result;
+        }
+        request.attr_end(data);
+
+        return WIFI_SUCCESS;
+    }
+
+    int createRequest(WifiRequest &request) {
+        int result;
+
+        switch (mType) {
+            case GET_FW_VER:
+            {
+                result = request.create(GOOGLE_OUI, LOGGER_GET_VER);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to create get fw version request; result = %d", result);
+                    return result;
+                }
+
+                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+                // Driver expecting only attribute type, passing mbuff as data with
+                // length 0 to avoid undefined state
+                result = request.put(LOGGER_ATTRIBUTE_FW_VER, mBuff, 0);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to put get fw version request; result = %d", result);
+                    return result;
+                }
+                request.attr_end(data);
+                break;
+            }
+
+            case GET_DRV_VER:
+            {
+                result = request.create(GOOGLE_OUI, LOGGER_GET_VER);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to create get drv version request; result = %d", result);
+                    return result;
+                }
+
+                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+                // Driver expecting only attribute type, passing mbuff as data with
+                // length 0 to avoid undefined state
+                result = request.put(LOGGER_ATTRIBUTE_DRIVER_VER, mBuff, 0);
+
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to put get drv version request; result = %d", result);
+                    return result;
+                }
+                request.attr_end(data);
+                break;
+            }
+
+            case GET_RING_DATA:
+            {
+                result = request.create(GOOGLE_OUI, LOGGER_GET_RING_DATA);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to create get ring data request; result = %d", result);
+                    return result;
+                }
+
+                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+                result = request.put_string(LOGGER_ATTRIBUTE_RING_NAME, mRingName);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to put ring data request; result = %d", result);
+                    return result;
+                }
+                request.attr_end(data);
+                break;
+            }
+
+            case GET_RING_STATUS:
+            {
+                result = request.create(GOOGLE_OUI, LOGGER_GET_RING_STATUS);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to create get ring status request; result = %d", result);
+                    return result;
+                }
+                break;
+            }
+
+            case GET_FEATURE:
+            {
+                result = request.create(GOOGLE_OUI, LOGGER_GET_FEATURE);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to create get feature request; result = %d", result);
+                    return result;
+                }
+                break;
+            }
+
+            case START_RING_LOG:
+                result = createRingRequest(request);
+                break;
+
+            default:
+                ALOGE("Unknown Debug command");
+                result = WIFI_ERROR_UNKNOWN;
+        }
+        return result;
+    }
+
+    int start() {
+        // ALOGD("Start debug command");
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to create debug request; result = %d", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to register debug response; result = %d", result);
+        }
+        return result;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        ALOGD("In DebugCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        switch (mType) {
+            case GET_DRV_VER:
+            case GET_FW_VER:
+            {
+                void *data = reply.get_vendor_data();
+                int len = reply.get_vendor_data_len();
+
+                ALOGD("len = %d, expected len = %d", len, *mBuffSize);
+                memcpy(mBuff, data, min(len, *mBuffSize));
+                if (*mBuffSize < len)
+                    return NL_SKIP;
+                *mBuffSize = len;
+                break;
+            }
+
+            case START_RING_LOG:
+            case GET_RING_DATA:
+                break;
+
+            case GET_RING_STATUS:
+            {
+                nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+                int len = reply.get_vendor_data_len();
+                wifi_ring_buffer_status *status(mStatus);
+
+                if (vendor_data == NULL || len == 0) {
+                    ALOGE("No Debug data found");
+                    return NL_SKIP;
+                }
+
+                nl_iterator it(vendor_data);
+                if (it.get_type() == LOGGER_ATTRIBUTE_RING_NUM) {
+                    unsigned int num_rings = it.get_u32();
+                    if (*mNumRings < num_rings) {
+                        ALOGE("Not enough status buffers provided, available: %d required: %d",
+                                *mNumRings, num_rings);
+                    } else {
+                        *mNumRings = num_rings;
+                    }
+                } else {
+                    ALOGE("Unknown attribute: %d expecting %d",
+                            it.get_type(), LOGGER_ATTRIBUTE_RING_NUM);
+                    return NL_SKIP;
+                }
+
+                it.next();
+                for (unsigned int i = 0; it.has_next() && i < *mNumRings; it.next()) {
+                    if (it.get_type() == LOGGER_ATTRIBUTE_RING_STATUS) {
+                        memcpy(status, it.get_data(), sizeof(wifi_ring_buffer_status));
+                        i++;
+                        status++;
+                    } else {
+                        ALOGW("Ignoring invalid attribute type = %d, size = %d",
+                                it.get_type(), it.get_len());
+                    }
+                }
+                break;
+            }
+
+            case GET_FEATURE:
+            {
+                void *data = reply.get_vendor_data();
+                int len = reply.get_vendor_data_len();
+
+                ALOGD("len = %d, expected len = %d", len, sizeof(unsigned int));
+                memcpy(mSupport, data, sizeof(unsigned int));
+                break;
+            }
+
+            default:
+                ALOGW("Unknown Debug command");
+        }
+        return NL_OK;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        /* NO events! */
+        return NL_SKIP;
+    }
+};
+
+/* API to collect a firmware version string */
+wifi_error wifi_get_firmware_version(wifi_interface_handle iface, char *buffer,
+        int buffer_size)
+{
+    if (buffer && (buffer_size > 0)) {
+        DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_FW_VER);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        wifi_error result = (wifi_error)cmd->start();
+        cmd->releaseRef();
+        return result;
+    } else {
+        ALOGE("FW version buffer NULL");
+        return  WIFI_ERROR_INVALID_ARGS;
+    }
+}
+
+/* API to collect a driver version string */
+wifi_error wifi_get_driver_version(wifi_interface_handle iface, char *buffer, int buffer_size)
+{
+    if (buffer && (buffer_size > 0)) {
+        DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_DRV_VER);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        wifi_error result = (wifi_error)cmd->start();
+        cmd->releaseRef();
+        return result;
+    } else {
+        ALOGE("Driver version buffer NULL");
+        return  WIFI_ERROR_INVALID_ARGS;
+    }
+}
+
+/* API to collect driver records */
+wifi_error wifi_get_ring_data(wifi_interface_handle iface, char *ring_name)
+{
+    DebugCommand *cmd = new DebugCommand(iface, ring_name, GET_RING_DATA);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
+
+/* API to get the status of all ring buffers supported by driver */
+wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface,
+        u32 *num_rings, wifi_ring_buffer_status *status)
+{
+    if (status && num_rings) {
+        DebugCommand *cmd = new DebugCommand(iface, num_rings, status, GET_RING_STATUS);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        wifi_error result = (wifi_error)cmd->start();
+        cmd->releaseRef();
+        return result;
+    } else {
+        ALOGE("Ring status buffer NULL");
+        return  WIFI_ERROR_INVALID_ARGS;
+    }
+}
+
+/* API to get supportable feature */
+wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,
+        unsigned int *support)
+{
+    if (support) {
+        DebugCommand *cmd = new DebugCommand(iface, support, GET_FEATURE);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        wifi_error result = (wifi_error)cmd->start();
+        cmd->releaseRef();
+        return result;
+    } else {
+        ALOGE("Get support buffer NULL");
+        return  WIFI_ERROR_INVALID_ARGS;
+    }
+}
+
+wifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level,
+        u32 flags, u32 max_interval_sec, u32 min_data_size, char *ring_name)
+{
+    if (ring_name) {
+        DebugCommand *cmd = new DebugCommand(iface, verbose_level, flags, max_interval_sec,
+                    min_data_size, ring_name, START_RING_LOG);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        wifi_error result = (wifi_error)cmd->start();
+        cmd->releaseRef();
+        return result;
+    } else {
+        ALOGE("Ring name NULL");
+        return  WIFI_ERROR_INVALID_ARGS;
+    }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+class SetLogHandler : public WifiCommand
+{
+    wifi_ring_buffer_data_handler mHandler;
+
+public:
+    SetLogHandler(wifi_interface_handle iface, int id, wifi_ring_buffer_data_handler handler)
+        : WifiCommand("SetLogHandler", iface, id), mHandler(handler)
+    { }
+
+    int start() {
+        ALOGV("Register loghandler");
+        registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int cancel() {
+        /* Send a command to driver to stop generating logging events */
+        ALOGV("Clear loghandler");
+
+        /* unregister event handler */
+        unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
+
+        WifiRequest request(familyId(), ifaceId());
+        int result = request.create(GOOGLE_OUI, LOGGER_RESET_LOGGING);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create reset request; result = %d", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to request reset; result = %d", result);
+            return result;
+        }
+
+        ALOGD("Success to clear loghandler");
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        char *buffer = NULL;
+        int buffer_size = 0;
+
+        // ALOGD("In SetLogHandler::handleEvent");
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = event.get_vendor_data_len();
+        int event_id = event.get_vendor_subcmd();
+        // ALOGI("Got Logger event: %d", event_id);
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("No Debug data found");
+            return NL_SKIP;
+        }
+
+        if(event_id == GOOGLE_DEBUG_RING_EVENT) {
+            wifi_ring_buffer_status status;
+            memset(&status, 0, sizeof(status));
+
+            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                if (it.get_type() == LOGGER_ATTRIBUTE_RING_STATUS) {
+                    memcpy(&status, it.get_data(), sizeof(status));
+                } else if (it.get_type() == LOGGER_ATTRIBUTE_RING_DATA) {
+                    buffer_size = it.get_len();
+                    buffer = (char *)it.get_data();
+                } else {
+                    ALOGW("Ignoring invalid attribute type = %d, size = %d",
+                            it.get_type(), it.get_len());
+                }
+            }
+
+            // ALOGI("Retrieved Debug data");
+            if (mHandler.on_ring_buffer_data) {
+                (*mHandler.on_ring_buffer_data)((char *)status.name, buffer, buffer_size,
+                        &status);
+            }
+        } else {
+            ALOGE("Unknown Event");
+            return NL_SKIP;
+        }
+        return NL_OK;
+    }
+};
+
+wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface,
+        wifi_ring_buffer_data_handler handler)
+{
+    wifi_handle handle = getWifiHandle(iface);
+    ALOGV("Loghandler start, handle = %p", handle);
+
+    SetLogHandler *cmd = new SetLogHandler(iface, id, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return result;
+}
+
+wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface)
+{
+    wifi_handle handle = getWifiHandle(iface);
+    ALOGV("Loghandler reset, wifi_request_id = %d, handle = %p", id, handle);
+
+    if (id == -1) {
+        wifi_ring_buffer_data_handler handler;
+        memset(&handler, 0, sizeof(handler));
+
+        SetLogHandler *cmd = new SetLogHandler(iface, id, handler);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+
+    return wifi_cancel_cmd(id, iface);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+class SetAlertHandler : public WifiCommand
+{
+    wifi_alert_handler mHandler;
+    int mBuffSize;
+    char *mBuff;
+    int mErrCode;
+
+public:
+    SetAlertHandler(wifi_interface_handle iface, int id, wifi_alert_handler handler)
+        : WifiCommand("SetAlertHandler", iface, id), mHandler(handler), mBuffSize(0), mBuff(NULL),
+            mErrCode(0)
+    { }
+
+    int start() {
+        ALOGV("Start Alerting");
+        registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_MEM_DUMP_EVENT);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int cancel() {
+        ALOGV("Clear alerthandler");
+
+        /* unregister alert handler */
+        unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_MEM_DUMP_EVENT);
+        wifi_unregister_cmd(wifiHandle(), id());
+        ALOGD("Success to clear alerthandler");
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        ALOGD("In SetAlertHandler::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = reply.get_vendor_data_len();
+
+        ALOGD("len = %d", len);
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("no vendor data in memory dump response; ignoring it");
+            return NL_SKIP;
+        }
+
+        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+            if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_DATA) {
+                ALOGI("Initiating alert callback");
+                if (mHandler.on_alert) {
+                    (*mHandler.on_alert)(id(), mBuff, mBuffSize, mErrCode);
+                }
+                if (mBuff) {
+                    free(mBuff);
+                    mBuff = NULL;
+                }
+            }
+        }
+        return NL_OK;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        wifi_ring_buffer_id ring_id;
+        char *buffer = NULL;
+        int buffer_size = 0;
+
+
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = event.get_vendor_data_len();
+        int event_id = event.get_vendor_subcmd();
+        ALOGI("Got event: %d", event_id);
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("No Debug data found");
+            return NL_SKIP;
+        }
+
+        if (event_id == GOOGLE_DEBUG_MEM_DUMP_EVENT) {
+            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_LEN) {
+                    mBuffSize = it.get_u32();
+                } else if (it.get_type() == LOGGER_ATTRIBUTE_RING_DATA) {
+                    buffer_size = it.get_len();
+                    buffer = (char *)it.get_data();
+            /*
+                } else if (it.get_type() == LOGGER_ATTRIBUTE_FW_ERR_CODE) {
+                    mErrCode = it.get_u32();
+            */
+                } else {
+                    ALOGW("Ignoring invalid attribute type = %d, size = %d",
+                            it.get_type(), it.get_len());
+                }
+            }
+            if (mBuffSize) {
+                ALOGD("dump size: %d meta data size: %d", mBuffSize, buffer_size);
+                if (mBuff) free(mBuff);
+                mBuff = (char *)malloc(mBuffSize + buffer_size);
+                if (!mBuff) {
+                    ALOGE("Buffer allocation failed");
+                    return NL_SKIP;
+                }
+                memcpy(mBuff, buffer, buffer_size);
+
+                WifiRequest request(familyId(), ifaceId());
+                int result = request.create(GOOGLE_OUI, LOGGER_GET_MEM_DUMP);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to create get memory dump request; result = %d", result);
+                    free(mBuff);
+                    return NL_SKIP;
+                }
+                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+                result = request.put_u32(LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to put get memory dump request; result = %d", result);
+                    return result;
+                }
+
+                result = request.put_u64(LOGGER_ATTRIBUTE_FW_DUMP_DATA,
+                         (uint64_t)(mBuff+buffer_size));
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to put get memory dump request; result = %d", result);
+                    return result;
+                }
+
+                request.attr_end(data);
+                mBuffSize += buffer_size;
+
+                result = requestResponse(request);
+
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to register get momory dump response; result = %d", result);
+                }
+            } else {
+                ALOGE("dump event missing dump length attribute");
+                return NL_SKIP;
+            }
+        }
+        return NL_OK;
+    }
+};
+
+wifi_error wifi_set_alert_handler(wifi_request_id id, wifi_interface_handle iface,
+        wifi_alert_handler handler)
+{
+    wifi_handle handle = getWifiHandle(iface);
+    ALOGV("Alerthandler start, handle = %p", handle);
+
+    SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return result;
+}
+
+wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle iface)
+{
+    wifi_handle handle = getWifiHandle(iface);
+    ALOGV("Alerthandler reset, wifi_request_id = %d, handle = %p", id, handle);
+
+    if (id == -1) {
+        wifi_alert_handler handler;
+        memset(&handler, 0, sizeof(handler));
+
+        SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+
+    return wifi_cancel_cmd(id, iface);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+class MemoryDumpCommand: public WifiCommand
+{
+    wifi_firmware_memory_dump_handler mHandler;
+    int mBuffSize;
+    char *mBuff;
+
+public:
+    MemoryDumpCommand(wifi_interface_handle iface, wifi_firmware_memory_dump_handler handler)
+        : WifiCommand("MemoryDumpCommand", iface, 0), mHandler(handler), mBuffSize(0), mBuff(NULL)
+    { }
+
+    int start() {
+        ALOGD("Start memory dump command");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = request.create(GOOGLE_OUI, LOGGER_TRIGGER_MEM_DUMP);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to create trigger fw memory dump request; result = %d", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to register trigger memory dump response; result = %d", result);
+        }
+        return result;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        ALOGD("In MemoryDumpCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = reply.get_vendor_data_len();
+
+        ALOGD("len = %d", len);
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("no vendor data in memory dump response; ignoring it");
+            return NL_SKIP;
+        }
+
+        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+            if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_LEN) {
+                mBuffSize = it.get_u32();
+
+                if (mBuff)
+                    free(mBuff);
+                mBuff = (char *)malloc(mBuffSize);
+                if (!mBuff) {
+                    ALOGE("Buffer allocation failed");
+                    return NL_SKIP;
+                }
+                WifiRequest request(familyId(), ifaceId());
+                int result = request.create(GOOGLE_OUI, LOGGER_GET_MEM_DUMP);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to create get memory dump request; result = %d", result);
+                    free(mBuff);
+                    return NL_SKIP;
+                }
+
+                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+                result = request.put_u32(LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to put get memory dump request; result = %d", result);
+                    return result;
+                }
+
+                result = request.put_u64(LOGGER_ATTRIBUTE_FW_DUMP_DATA, (uint64_t)mBuff);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to put get memory dump request; result = %d", result);
+                    return result;
+                }
+                request.attr_end(data);
+
+                result = requestResponse(request);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to register get momory dump response; result = %d", result);
+                }
+            } else if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_DATA) {
+                ALOGI("Initiating memory dump callback");
+                if (mHandler.on_firmware_memory_dump) {
+                    (*mHandler.on_firmware_memory_dump)(mBuff, mBuffSize);
+                }
+                if (mBuff) {
+                    free(mBuff);
+                    mBuff = NULL;
+                }
+            } else {
+                ALOGW("Ignoring invalid attribute type = %d, size = %d",
+                        it.get_type(), it.get_len());
+            }
+        }
+        return NL_OK;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        /* NO events! */
+        return NL_SKIP;
+    }
+};
+
+/* API to collect a firmware memory dump for a given iface */
+wifi_error wifi_get_firmware_memory_dump( wifi_interface_handle iface,
+        wifi_firmware_memory_dump_handler handler)
+{
+    MemoryDumpCommand *cmd = new MemoryDumpCommand(iface, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
+
+class PacketFateCommand: public WifiCommand
+{
+    void *mReportBufs;
+    size_t mNoReqFates;
+    size_t *mNoProvidedFates;
+    PktFateReqType mReqType;
+
+public:
+    PacketFateCommand(wifi_interface_handle handle)
+        : WifiCommand("PacketFateCommand", handle, 0), mReqType(PACKET_MONITOR_START)
+    { }
+
+    PacketFateCommand(wifi_interface_handle handle, wifi_tx_report *tx_report_bufs,
+            size_t n_requested_fates, size_t *n_provided_fates)
+        : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(tx_report_bufs),
+                  mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates),
+                  mReqType(TX_PACKET_FATE)
+    { }
+
+    PacketFateCommand(wifi_interface_handle handle, wifi_rx_report *rx_report_bufs,
+            size_t n_requested_fates, size_t *n_provided_fates)
+        : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(rx_report_bufs),
+                  mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates),
+                  mReqType(RX_PACKET_FATE)
+    { }
+
+    int createRequest(WifiRequest& request) {
+        if (mReqType == TX_PACKET_FATE) {
+            ALOGD("%s Get Tx packet fate request\n", __FUNCTION__);
+            return createTxPktFateRequest(request);
+        } else if (mReqType == RX_PACKET_FATE) {
+            ALOGD("%s Get Rx packet fate request\n", __FUNCTION__);
+            return createRxPktFateRequest(request);
+        } else if (mReqType == PACKET_MONITOR_START) {
+            ALOGD("%s Monitor packet fate request\n", __FUNCTION__);
+            return createMonitorPktFateRequest(request);
+        } else {
+            ALOGE("%s Unknown packet fate request\n", __FUNCTION__);
+            return WIFI_ERROR_NOT_SUPPORTED;
+        }
+        return WIFI_SUCCESS;
+    }
+
+    int createMonitorPktFateRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, LOGGER_START_PKT_FATE_MONITORING);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        request.attr_end(data);
+        return result;
+    }
+
+    int createTxPktFateRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, LOGGER_GET_TX_PKT_FATES);
+        if (result < 0) {
+            return result;
+        }
+
+        memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_tx_report)));
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs);
+        if (result < 0) {
+            return result;
+        }
+        request.attr_end(data);
+        return result;
+    }
+
+    int createRxPktFateRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, LOGGER_GET_RX_PKT_FATES);
+        if (result < 0) {
+            return result;
+        }
+
+        memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_rx_report)));
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs);
+        if (result < 0) {
+            return result;
+        }
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        ALOGD("Start get packet fate command\n");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = createRequest(request);
+        if (result < 0) {
+            ALOGE("Failed to create get pkt fate request; result = %d\n", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to register get pkt fate response; result = %d\n", result);
+        }
+        return result;
+    }
+
+    int handleResponse(WifiEvent& reply) {
+        ALOGD("In GetPktFateCommand::handleResponse\n");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGI("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = reply.get_vendor_data_len();
+
+        ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
+
+        if (mReqType == TX_PACKET_FATE) {
+            ALOGI("Response recieved for get TX pkt fate command\n");
+        } else if (mReqType == RX_PACKET_FATE) {
+            ALOGI("Response recieved for get RX pkt fate command\n");
+        } else if (mReqType == PACKET_MONITOR_START) {
+            ALOGI("Response recieved for monitor pkt fate command\n");
+            return NL_OK;
+        } else {
+            ALOGE("Response recieved for unknown pkt fate command\n");
+            return NL_SKIP;
+        }
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("no vendor data in GetPktFateCommand response; ignoring it\n");
+            return NL_SKIP;
+        }
+
+        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+            if (it.get_type() == LOGGER_ATTRIBUTE_PKT_FATE_NUM) {
+                *mNoProvidedFates = it.get_u32();
+                ALOGI("No: of pkt fates provided is %d\n", *mNoProvidedFates);
+            } else {
+                ALOGE("Ignoring invalid attribute type = %d, size = %d\n",
+                        it.get_type(), it.get_len());
+            }
+        }
+
+        return NL_OK;
+    }
+
+    int handleEvent(WifiEvent& event) {
+        /* NO events to handle here! */
+        return NL_SKIP;
+    }
+};
+
+wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle)
+{
+    PacketFateCommand *cmd = new PacketFateCommand(handle);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
+
+wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle,
+        wifi_tx_report *tx_report_bufs, size_t n_requested_fates,
+        size_t *n_provided_fates)
+{
+    PacketFateCommand *cmd = new PacketFateCommand(handle, tx_report_bufs,
+                n_requested_fates, n_provided_fates);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
+
+wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle,
+        wifi_rx_report *rx_report_bufs, size_t n_requested_fates,
+        size_t *n_provided_fates)
+{
+    PacketFateCommand *cmd = new PacketFateCommand(handle, rx_report_bufs,
+                n_requested_fates, n_provided_fates);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
diff --git a/wlan/wifi_hal/rtw_wifi_offload.cpp b/wlan/wifi_hal/rtw_wifi_offload.cpp
new file mode 100644 (file)
index 0000000..51720c6
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink-private/object-api.h>
+#include <netlink-private/types.h>
+
+
+#include "nl80211_copy.h"
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL"
+
+#include <log/log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+typedef enum {
+    WIFI_OFFLOAD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
+    WIFI_OFFLOAD_STOP_MKEEP_ALIVE,
+} WIFI_OFFLOAD_SUB_COMMAND;
+
+typedef enum {
+    MKEEP_ALIVE_ATTRIBUTE_ID,
+    MKEEP_ALIVE_ATTRIBUTE_IP_PKT,
+    MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN,
+    MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR,
+    MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR,
+    MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
+} WIFI_MKEEP_ALIVE_ATTRIBUTE;
+
+typedef enum {
+    START_MKEEP_ALIVE,
+    STOP_MKEEP_ALIVE,
+} GetCmdType;
+
+///////////////////////////////////////////////////////////////////////////////
+class MKeepAliveCommand : public WifiCommand
+{
+    u8 mIndex;
+    u8 *mIpPkt;
+    u16 mIpPktLen;
+    u8 *mSrcMacAddr;
+    u8 *mDstMacAddr;
+    u32 mPeriodMsec;
+    GetCmdType mType;
+
+public:
+
+    // constructor for start sending
+    MKeepAliveCommand(wifi_interface_handle iface, u8 index, u8 *ip_packet, u16 ip_packet_len,
+            u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec, GetCmdType cmdType)
+        : WifiCommand("MKeepAliveCommand", iface, 0), mIndex(index), mIpPkt(ip_packet),
+        mIpPktLen(ip_packet_len), mSrcMacAddr(src_mac_addr), mDstMacAddr(dst_mac_addr),
+        mPeriodMsec(period_msec), mType(cmdType)
+    { }
+
+    // constructor for stop sending
+    MKeepAliveCommand(wifi_interface_handle iface, u8 index, GetCmdType cmdType)
+        : WifiCommand("MKeepAliveCommand", iface, 0), mIndex(index), mType(cmdType)
+    { }
+
+    int createRequest(WifiRequest &request) {
+        int result;
+
+        switch (mType) {
+            case START_MKEEP_ALIVE:
+            {
+                result = request.create(GOOGLE_OUI, WIFI_OFFLOAD_START_MKEEP_ALIVE);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to create start keep alive request; result = %d", result);
+                    return result;
+                }
+
+                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+                result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
+                if (result < 0) {
+                    ALOGE("Failed to put id request; result = %d", result);
+                    return result;
+                }
+
+                result = request.put_u16(MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, mIpPktLen);
+                if (result < 0) {
+                    ALOGE("Failed to put ip pkt len request; result = %d", result);
+                    return result;
+                }
+
+                result = request.put(MKEEP_ALIVE_ATTRIBUTE_IP_PKT, (u8*)mIpPkt, mIpPktLen);
+                if (result < 0) {
+                    ALOGE("Failed to put ip pkt request; result = %d", result);
+                    return result;
+                }
+
+                result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, mSrcMacAddr);
+                if (result < 0) {
+                    ALOGE("Failed to put src mac address request; result = %d", result);
+                    return result;
+                }
+
+                result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, mDstMacAddr);
+                if (result < 0) {
+                    ALOGE("Failed to put dst mac address request; result = %d", result);
+                    return result;
+                }
+
+                result = request.put_u32(MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, mPeriodMsec);
+                if (result < 0) {
+                    ALOGE("Failed to put period request; result = %d", result);
+                    return result;
+                }
+
+                request.attr_end(data);
+                break;
+            }
+
+            case STOP_MKEEP_ALIVE:
+            {
+                result = request.create(GOOGLE_OUI, WIFI_OFFLOAD_STOP_MKEEP_ALIVE);
+                if (result != WIFI_SUCCESS) {
+                    ALOGE("Failed to create stop keep alive request; result = %d", result);
+                    return result;
+                }
+
+                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+                result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
+                if (result < 0) {
+                    ALOGE("Failed to put id request; result = %d", result);
+                    return result;
+                }
+
+                request.attr_end(data);
+                break;
+            }
+
+            default:
+                ALOGE("Unknown wifi keep alive command");
+                result = WIFI_ERROR_UNKNOWN;
+        }
+        return result;
+    }
+
+    int start() {
+        ALOGD("Start mkeep_alive command");
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to create keep alive request; result = %d", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to register keep alive response; result = %d", result);
+        }
+        return result;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        ALOGD("In MKeepAliveCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        switch (mType) {
+            case START_MKEEP_ALIVE:
+            case STOP_MKEEP_ALIVE:
+                break;
+
+            default:
+                ALOGW("Unknown mkeep_alive command");
+        }
+        return NL_OK;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        /* NO events! */
+        return NL_SKIP;
+    }
+};
+
+/* API to send specified mkeep_alive packet periodically. */
+wifi_error wifi_start_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface,
+        u16 /* ether_type */, u8 *ip_packet, u16 ip_packet_len, u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec)
+{
+    if ((index > 0 && index <= N_AVAIL_ID) && (ip_packet != NULL) && (src_mac_addr != NULL)
+            && (dst_mac_addr != NULL) && (period_msec > 0)
+            && (ip_packet_len <= MKEEP_ALIVE_IP_PKT_MAX)) {
+        MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, ip_packet, ip_packet_len,
+                src_mac_addr, dst_mac_addr, period_msec, START_MKEEP_ALIVE);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        wifi_error result = (wifi_error)cmd->start();
+        cmd->releaseRef();
+        return result;
+    } else {
+        ALOGE("Invalid mkeep_alive parameters");
+        return  WIFI_ERROR_INVALID_ARGS;
+    }
+}
+
+/* API to stop sending mkeep_alive packet. */
+wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface)
+{
+    if (index > 0 && index <= N_AVAIL_ID) {
+        MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, STOP_MKEEP_ALIVE);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        wifi_error result = (wifi_error)cmd->start();
+        cmd->releaseRef();
+        return result;
+    } else {
+        ALOGE("Invalid mkeep_alive parameters");
+        return  WIFI_ERROR_INVALID_ARGS;
+    }
+}
diff --git a/wlan/wifi_hal/rtw_wifi_rtt.cpp b/wlan/wifi_hal/rtw_wifi_rtt.cpp
new file mode 100644 (file)
index 0000000..813be0e
--- /dev/null
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink-private/object-api.h>
+#include <netlink-private/types.h>
+
+#include "nl80211_copy.h"
+
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL"
+
+#include <log/log.h>
+#include <utils/String8.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+using namespace android;
+#define RTT_RESULT_SIZE (sizeof(wifi_rtt_result));
+typedef enum {
+
+    RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
+    RTT_SUBCMD_CANCEL_CONFIG,
+    RTT_SUBCMD_GETCAPABILITY,
+    RTT_SUBCMD_GETAVAILCHANNEL,
+    RTT_SUBCMD_SET_RESPONDER,
+    RTT_SUBCMD_CANCEL_RESPONDER,
+} RTT_SUB_COMMAND;
+
+typedef enum {
+    RTT_ATTRIBUTE_TARGET_CNT = 0,
+    RTT_ATTRIBUTE_TARGET_INFO,
+    RTT_ATTRIBUTE_TARGET_MAC,
+    RTT_ATTRIBUTE_TARGET_TYPE,
+    RTT_ATTRIBUTE_TARGET_PEER,
+    RTT_ATTRIBUTE_TARGET_CHAN,
+    RTT_ATTRIBUTE_TARGET_PERIOD,
+    RTT_ATTRIBUTE_TARGET_NUM_BURST,
+    RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
+    RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
+    RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
+    RTT_ATTRIBUTE_TARGET_LCI,
+    RTT_ATTRIBUTE_TARGET_LCR,
+    RTT_ATTRIBUTE_TARGET_BURST_DURATION,
+    RTT_ATTRIBUTE_TARGET_PREAMBLE,
+    RTT_ATTRIBUTE_TARGET_BW,
+    RTT_ATTRIBUTE_RESULTS_COMPLETE = 30,
+    RTT_ATTRIBUTE_RESULTS_PER_TARGET,
+    RTT_ATTRIBUTE_RESULT_CNT,
+    RTT_ATTRIBUTE_RESULT
+} RTT_ATTRIBUTE;
+typedef struct strmap_entry {
+    int                        id;
+    String8            text;
+} strmap_entry_t;
+struct dot11_rm_ie {
+    u8 id;
+    u8 len;
+    u8 token;
+    u8 mode;
+    u8 type;
+} __attribute__ ((packed));
+typedef struct dot11_rm_ie dot11_rm_ie_t;
+#define DOT11_HDR_LEN 2
+#define DOT11_RM_IE_LEN       5
+#define DOT11_MNG_MEASURE_REQUEST_ID           38      /* 11H MeasurementRequest */
+#define DOT11_MEASURE_TYPE_LCI         8   /* d11 measurement LCI type */
+#define DOT11_MEASURE_TYPE_CIVICLOC    11  /* d11 measurement location civic */
+
+static const strmap_entry_t err_info[] = {
+    {RTT_STATUS_SUCCESS, String8("Success")},
+    {RTT_STATUS_FAILURE, String8("Failure")},
+    {RTT_STATUS_FAIL_NO_RSP, String8("No reponse")},
+    {RTT_STATUS_FAIL_INVALID_TS, String8("Invalid Timestamp")},
+    {RTT_STATUS_FAIL_PROTOCOL, String8("Protocol error")},
+    {RTT_STATUS_FAIL_REJECTED, String8("Rejected")},
+    {RTT_STATUS_FAIL_NOT_SCHEDULED_YET, String8("not scheduled")},
+    {RTT_STATUS_FAIL_SCHEDULE,  String8("schedule failed")},
+    {RTT_STATUS_FAIL_TM_TIMEOUT, String8("timeout")},
+    {RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, String8("AP is on difference channel")},
+    {RTT_STATUS_FAIL_NO_CAPABILITY, String8("no capability")},
+    {RTT_STATUS_FAIL_BUSY_TRY_LATER, String8("busy and try later")},
+    {RTT_STATUS_ABORTED, String8("aborted")}
+};
+
+    static const char*
+get_err_info(int status)
+{
+    int i;
+    const strmap_entry_t *p_entry;
+    int num_entries = sizeof(err_info)/ sizeof(err_info[0]);
+    /* scan thru the table till end */
+    p_entry = err_info;
+    for (i = 0; i < (int) num_entries; i++)
+    {
+        if (p_entry->id == status)
+            return p_entry->text;
+        p_entry++;             /* next entry */
+    }
+    return "unknown error";                    /* not found */
+}
+
+class GetRttCapabilitiesCommand : public WifiCommand
+{
+    wifi_rtt_capabilities *mCapabilities;
+public:
+    GetRttCapabilitiesCommand(wifi_interface_handle iface, wifi_rtt_capabilities *capabitlites)
+        : WifiCommand("GetRttCapabilitiesCommand", iface, 0), mCapabilities(capabitlites)
+    {
+        memset(mCapabilities, 0, sizeof(*mCapabilities));
+    }
+
+    virtual int create() {
+        ALOGD("Creating message to get scan capablities; iface = %d", mIfaceInfo->id);
+
+        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETCAPABILITY);
+        if (ret < 0) {
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        ALOGD("In GetRttCapabilitiesCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        void *data = reply.get_vendor_data();
+        int len = reply.get_vendor_data_len();
+
+        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
+                sizeof(*mCapabilities));
+
+        memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities)));
+
+        return NL_OK;
+    }
+};
+
+
+class GetRttResponderInfoCommand : public WifiCommand
+{
+    wifi_rtt_responder* mResponderInfo;
+public:
+    GetRttResponderInfoCommand(wifi_interface_handle iface, wifi_rtt_responder *responderInfo)
+        : WifiCommand("GetRttResponderInfoCommand", iface, 0), mResponderInfo(responderInfo)
+    {
+        memset(mResponderInfo, 0 , sizeof(*mResponderInfo));
+
+    }
+
+    virtual int create() {
+        ALOGD("Creating message to get responder info ; iface = %d", mIfaceInfo->id);
+
+        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETAVAILCHANNEL);
+        if (ret < 0) {
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        ALOGD("In GetRttResponderInfoCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        void *data = reply.get_vendor_data();
+        int len = reply.get_vendor_data_len();
+
+        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
+                sizeof(*mResponderInfo));
+
+        memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
+
+        return NL_OK;
+    }
+};
+
+
+class EnableResponderCommand : public WifiCommand
+{
+    wifi_channel_info  mChannelInfo;
+    wifi_rtt_responder* mResponderInfo;
+    unsigned m_max_duration_sec;
+public:
+    EnableResponderCommand(wifi_interface_handle iface, int id, wifi_channel_info channel_hint,
+            unsigned max_duration_seconds, wifi_rtt_responder *responderInfo)
+            : WifiCommand("EnableResponderCommand", iface, 0), mChannelInfo(channel_hint),
+            m_max_duration_sec(max_duration_seconds), mResponderInfo(responderInfo)
+    {
+        memset(mResponderInfo, 0, sizeof(*mResponderInfo));
+    }
+
+    virtual int create() {
+        ALOGD("Creating message to set responder ; iface = %d", mIfaceInfo->id);
+
+        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_SET_RESPONDER);
+        if (ret < 0) {
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        ALOGD("In EnableResponderCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        void *data = reply.get_vendor_data();
+        int len = reply.get_vendor_data_len();
+
+        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
+                sizeof(*mResponderInfo));
+
+        memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
+
+        return NL_OK;
+    }
+};
+
+
+class CancelResponderCommand : public WifiCommand
+{
+
+public:
+    CancelResponderCommand(wifi_interface_handle iface, int id)
+        : WifiCommand("CancelResponderCommand", iface, 0)/*, mChannelInfo(channel)*/
+    {
+
+    }
+
+    virtual int create() {
+        ALOGD("Creating message to cancel responder ; iface = %d", mIfaceInfo->id);
+
+        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_RESPONDER);
+        if (ret < 0) {
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+};
+
+
+class RttCommand : public WifiCommand
+{
+    unsigned numRttParams;
+    int mCompleted;
+    int currentIdx;
+    int totalCnt;
+    static const int MAX_RESULTS = 1024;
+    wifi_rtt_result *rttResults[MAX_RESULTS];
+    wifi_rtt_config *rttParams;
+    wifi_rtt_event_handler rttHandler;
+public:
+    RttCommand(wifi_interface_handle iface, int id, unsigned num_rtt_config,
+            wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
+        : WifiCommand("RttCommand", iface, id), numRttParams(num_rtt_config), rttParams(rtt_config),
+        rttHandler(handler)
+    {
+        memset(rttResults, 0, sizeof(rttResults));
+        currentIdx = 0;
+        mCompleted = 0;
+        totalCnt = 0;
+    }
+
+    RttCommand(wifi_interface_handle iface, int id)
+        : WifiCommand("RttCommand", iface, id)
+    {
+        currentIdx = 0;
+        mCompleted = 0;
+        totalCnt = 0;
+        numRttParams = 0;
+    }
+
+    int createSetupRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, RTT_SUBCMD_SET_CONFIG);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, numRttParams);
+        if (result < 0) {
+            return result;
+        }
+        nlattr *rtt_config = request.attr_start(RTT_ATTRIBUTE_TARGET_INFO);
+        for (unsigned i = 0; i < numRttParams; i++) {
+            nlattr *attr2 = request.attr_start(i);
+            if (attr2 == NULL) {
+                return WIFI_ERROR_OUT_OF_MEMORY;
+            }
+
+            result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, rttParams[i].addr);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(RTT_ATTRIBUTE_TARGET_TYPE, rttParams[i].type);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(RTT_ATTRIBUTE_TARGET_PEER, rttParams[i].peer);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put(RTT_ATTRIBUTE_TARGET_CHAN, &rttParams[i].channel,
+                    sizeof(wifi_channel_info));
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_BURST, rttParams[i].num_burst);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
+                    rttParams[i].num_frames_per_burst);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
+                    rttParams[i].num_retries_per_rtt_frame);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
+                    rttParams[i].num_retries_per_ftmr);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u32(RTT_ATTRIBUTE_TARGET_PERIOD,
+                    rttParams[i].burst_period);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u32(RTT_ATTRIBUTE_TARGET_BURST_DURATION,
+                    rttParams[i].burst_duration);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCI,
+                    rttParams[i].LCI_request);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCR,
+                    rttParams[i].LCR_request);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(RTT_ATTRIBUTE_TARGET_BW,
+                    rttParams[i].bw);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(RTT_ATTRIBUTE_TARGET_PREAMBLE,
+                    rttParams[i].preamble);
+            if (result < 0) {
+                return result;
+            }
+            request.attr_end(attr2);
+        }
+
+        request.attr_end(rtt_config);
+        request.attr_end(data);
+        return WIFI_SUCCESS;
+    }
+
+    int createTeardownRequest(WifiRequest& request, unsigned num_devices, mac_addr addr[]) {
+        int result = request.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_CONFIG);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, num_devices);
+        for(unsigned i = 0; i < num_devices; i++) {
+            result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, addr[i]);
+            if (result < 0) {
+                return result;
+            }
+        }
+        request.attr_end(data);
+        return result;
+    }
+    int start() {
+        ALOGD("Setting RTT configuration");
+        WifiRequest request(familyId(), ifaceId());
+        int result = createSetupRequest(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create setup request; result = %d", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to configure RTT setup; result = %d", result);
+            return result;
+        }
+
+        registerVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
+        ALOGI("Successfully started RTT operation");
+        return result;
+    }
+
+    virtual int cancel() {
+        ALOGD("Stopping RTT");
+
+        WifiRequest request(familyId(), ifaceId());
+        int result = createTeardownRequest(request, 0, NULL);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create stop request; result = %d", result);
+        } else {
+            result = requestResponse(request);
+            if (result != WIFI_SUCCESS) {
+                ALOGE("failed to stop scan; result = %d", result);
+            }
+        }
+
+        unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
+        return WIFI_SUCCESS;
+    }
+
+    int cancel_specific(unsigned num_devices, mac_addr addr[]) {
+        ALOGE("Stopping RTT");
+
+        WifiRequest request(familyId(), ifaceId());
+        int result = createTeardownRequest(request, num_devices, addr);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create stop request; result = %d", result);
+        } else {
+            result = requestResponse(request);
+            if (result != WIFI_SUCCESS) {
+                ALOGE("failed to stop RTT; result = %d", result);
+            }
+        }
+
+        unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        ALOGI("Got an RTT event");
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = event.get_vendor_data_len();
+        if (vendor_data == NULL || len == 0) {
+            ALOGI("No rtt results found");
+        }
+        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+            if (it.get_type() == RTT_ATTRIBUTE_RESULTS_COMPLETE) {
+                mCompleted = it.get_u32();
+                ALOGI("retrieved completed flag : %d\n", mCompleted);
+            } else if (it.get_type() == RTT_ATTRIBUTE_RESULTS_PER_TARGET) {
+                int result_cnt = 0;
+                mac_addr bssid;
+                for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
+                    if (it2.get_type() == RTT_ATTRIBUTE_TARGET_MAC) {
+                        memcpy(bssid, it2.get_data(), sizeof(mac_addr));
+                        ALOGI("retrived target mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
+                                bssid[0],
+                                bssid[1],
+                                bssid[2],
+                                bssid[3],
+                                bssid[4],
+                                bssid[5]);
+                    } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_CNT) {
+                        result_cnt = it2.get_u32();
+                        ALOGI("retrieved result_cnt : %d\n", result_cnt);
+                    } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT) {
+                        int result_len = it2.get_len();
+                        rttResults[currentIdx] =  (wifi_rtt_result *)malloc(it2.get_len());
+                        wifi_rtt_result *rtt_result = rttResults[currentIdx];
+                        if (rtt_result == NULL) {
+                            mCompleted = 1;
+                            ALOGE("failed to allocate the wifi_rtt_result\n");
+                            break;
+                        }
+                        memcpy(rtt_result, it2.get_data(), it2.get_len());
+                        result_len -= sizeof(wifi_rtt_result);
+                        if (result_len > 0) {
+                            result_len -= sizeof(wifi_rtt_result);
+                            dot11_rm_ie_t *ele_1;
+                            dot11_rm_ie_t *ele_2;
+                            /* The result has LCI or LCR element */
+                            ele_1 = (dot11_rm_ie_t *)(rtt_result + 1);
+                            if (ele_1->id == DOT11_MNG_MEASURE_REQUEST_ID) {
+                                if (ele_1->type == DOT11_MEASURE_TYPE_LCI) {
+                                    rtt_result->LCI = (wifi_information_element *)ele_1;
+                                    result_len -= (ele_1->len + DOT11_HDR_LEN);
+                                    /* get a next rm ie */
+                                    if (result_len > 0) {
+                                        ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN));
+                                        if ((ele_2->id == DOT11_MNG_MEASURE_REQUEST_ID) &&
+                                                (ele_2->type == DOT11_MEASURE_TYPE_CIVICLOC)) {
+                                            rtt_result->LCR = (wifi_information_element *)ele_2;
+                                        }
+                                    }
+                                } else if (ele_1->type == DOT11_MEASURE_TYPE_CIVICLOC){
+                                    rtt_result->LCR = (wifi_information_element *)ele_1;
+                                    result_len -= (ele_1->len + DOT11_HDR_LEN);
+                                    /* get a next rm ie */
+                                    if (result_len > 0) {
+                                        ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN));
+                                        if ((ele_2->id == DOT11_MNG_MEASURE_REQUEST_ID) &&
+                                                (ele_2->type == DOT11_MEASURE_TYPE_LCI)) {
+                                            rtt_result->LCI = (wifi_information_element *)ele_2;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        totalCnt++;
+                        ALOGI("retrived rtt_result : \n\tburst_num :%d, measurement_number : %d, success_number : %d\n"
+                                "\tnumber_per_burst_peer : %d, status : %s, retry_after_duration : %d s\n"
+                                "\trssi : %d dbm, rx_rate : %d Kbps, rtt : %llu ns, rtt_sd : %llu\n"
+                                "\tdistance : %d, burst_duration : %d ms, negotiated_burst_num : %d\n",
+                                rtt_result->burst_num, rtt_result->measurement_number,
+                                rtt_result->success_number, rtt_result->number_per_burst_peer,
+                                get_err_info(rtt_result->status), rtt_result->retry_after_duration,
+                                rtt_result->rssi, rtt_result->rx_rate.bitrate * 100,
+                                rtt_result->rtt/10, rtt_result->rtt_sd, rtt_result->distance_mm / 10,
+                                rtt_result->burst_duration, rtt_result->negotiated_burst_num);
+                        currentIdx++;
+                    }
+                }
+            }
+
+        }
+        if (mCompleted) {
+            unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
+            (*rttHandler.on_rtt_results)(id(), totalCnt, rttResults);
+            for (int i = 0; i < currentIdx; i++) {
+                free(rttResults[i]);
+                rttResults[i] = NULL;
+            }
+            totalCnt = currentIdx = 0;
+            WifiCommand *cmd = wifi_unregister_cmd(wifiHandle(), id());
+            if (cmd)
+                cmd->releaseRef();
+        }
+        return NL_SKIP;
+    }
+};
+
+
+/* API to request RTT measurement */
+wifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle iface,
+        unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
+{
+    wifi_handle handle = getWifiHandle(iface);
+    RttCommand *cmd = new RttCommand(iface, id, num_rtt_config, rtt_config, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return result;
+}
+
+/* API to cancel RTT measurements */
+wifi_error wifi_rtt_range_cancel(wifi_request_id id,  wifi_interface_handle iface,
+        unsigned num_devices, mac_addr addr[])
+{
+    wifi_handle handle = getWifiHandle(iface);
+    RttCommand *cmd = new RttCommand(iface, id);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    cmd->cancel_specific(num_devices, addr);
+    cmd->releaseRef();
+    return WIFI_SUCCESS;
+}
+
+/* API to get RTT capability */
+wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
+        wifi_rtt_capabilities *capabilities)
+{
+    GetRttCapabilitiesCommand command(iface, capabilities);
+    return (wifi_error) command.requestResponse();
+}
+
+/* API to get the responder information */
+wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
+        wifi_rtt_responder* responderInfo)
+{
+    GetRttResponderInfoCommand command(iface, responderInfo);
+    return (wifi_error) command.requestResponse();
+
+}
+
+/**
+ * Enable RTT responder mode.
+ * channel_hint - hint of the channel information where RTT responder should be enabled on.
+ * max_duration_seconds - timeout of responder mode.
+ * wifi_rtt_responder - information for RTT responder e.g. channel used and preamble supported.
+ */
+wifi_error wifi_enable_responder(wifi_request_id id, wifi_interface_handle iface,
+                                wifi_channel_info channel_hint, unsigned max_duration_seconds,
+                                wifi_rtt_responder* responderInfo)
+{
+    EnableResponderCommand command(iface, id, channel_hint, max_duration_seconds, responderInfo);
+    return (wifi_error) command.requestResponse();
+}
+
+/**
+ * Disable RTT responder mode.
+ */
+wifi_error wifi_disable_responder(wifi_request_id id, wifi_interface_handle iface)
+{
+    CancelResponderCommand command(iface, id);
+    return (wifi_error) command.requestResponse();
+}
+
diff --git a/wlan/wifi_hal/version.h b/wlan/wifi_hal/version.h
new file mode 100644 (file)
index 0000000..ad2e795
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef VERSION_H
+#define VERSION_H
+
+#define RTW_WIFI_HAL_VERSION "v1.0.3"
+
+#endif /* VERSION_H */
diff --git a/wlan/wifi_hal/wifi_hal.cpp b/wlan/wifi_hal/wifi_hal.cpp
deleted file mode 100644 (file)
index cfc5e23..0000000
+++ /dev/null
@@ -1,1349 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/rtnetlink.h>
-#include <netpacket/packet.h>
-#include <linux/filter.h>
-#include <linux/errqueue.h>
-#include <errno.h>
-
-#include <linux/pkt_sched.h>
-#include <netlink/object-api.h>
-#include <netlink/netlink.h>
-#include <netlink/socket.h>
-#include <netlink/attr.h>
-#include <netlink/handlers.h>
-#include <netlink/msg.h>
-
-#include <dirent.h>
-#include <net/if.h>
-
-#include "sync.h"
-
-#define LOG_TAG  "WifiHAL"
-
-#include <utils/Log.h>
-
-#include "wifi_hal.h"
-#include "common.h"
-#include "cpp_bindings.h"
-#include "rtt.h"
-/*
- BUGBUG: normally, libnl allocates ports for all connections it makes; but
- being a static library, it doesn't really know how many other netlink connections
- are made by the same process, if connections come from different shared libraries.
- These port assignments exist to solve that problem - temporarily. We need to fix
- libnl to try and allocate ports across the entire process.
- */
-
-#define WIFI_HAL_CMD_SOCK_PORT       644
-#define WIFI_HAL_EVENT_SOCK_PORT     645
-
-static void internal_event_handler(wifi_handle handle, int events);
-static int internal_no_seq_check(nl_msg *msg, void *arg);
-static int internal_valid_message_handler(nl_msg *msg, void *arg);
-static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group);
-static int wifi_add_membership(wifi_handle handle, const char *group);
-static wifi_error wifi_init_interfaces(wifi_handle handle);
-static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
-                        iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh);
-static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface);
-static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
-                            const u8 *program, u32 len);
-static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
-                u32 *version, u32 *max_len);
-static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, u8 enable);
-static wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface,
-                                WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt);
-
-typedef enum wifi_attr {
-    ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
-    ANDR_WIFI_ATTRIBUTE_FEATURE_SET,
-    ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI,
-    ANDR_WIFI_ATTRIBUTE_NODFS_SET,
-    ANDR_WIFI_ATTRIBUTE_COUNTRY,
-    ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE
-    // Add more attribute here
-} wifi_attr_t;
-
-enum wifi_rssi_monitor_attr {
-    RSSI_MONITOR_ATTRIBUTE_MAX_RSSI,
-    RSSI_MONITOR_ATTRIBUTE_MIN_RSSI,
-    RSSI_MONITOR_ATTRIBUTE_START,
-};
-
-enum wifi_apf_attr {
-    APF_ATTRIBUTE_VERSION,
-    APF_ATTRIBUTE_MAX_LEN,
-    APF_ATTRIBUTE_PROGRAM,
-    APF_ATTRIBUTE_PROGRAM_LEN
-};
-
-enum apf_request_type {
-    GET_APF_CAPABILITIES,
-    SET_APF_PROGRAM
-};
-
-/* Initialize/Cleanup */
-
-void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
-{
-    uint32_t pid = getpid() & 0x3FFFFF;
-    nl_socket_set_local_port(sock, pid + (port << 22));
-}
-
-static nl_sock * wifi_create_nl_socket(int port)
-{
-    // ALOGI("Creating socket");
-    struct nl_sock *sock = nl_socket_alloc();
-    if (sock == NULL) {
-        ALOGE("Could not create handle");
-        return NULL;
-    }
-
-    wifi_socket_set_local_port(sock, port);
-
-    struct sockaddr *addr = NULL;
-    // ALOGI("sizeof(sockaddr) = %d, sizeof(sockaddr_nl) = %d", sizeof(*addr), sizeof(*addr_nl));
-
-    // ALOGI("Connecting socket");
-    if (nl_connect(sock, NETLINK_GENERIC)) {
-        ALOGE("Could not connect handle");
-        nl_socket_free(sock);
-        return NULL;
-    }
-
-    // ALOGI("Making socket nonblocking");
-    /*
-    if (nl_socket_set_nonblocking(sock)) {
-        ALOGE("Could make socket non-blocking");
-        nl_socket_free(sock);
-        return NULL;
-    }
-    */
-
-    return sock;
-}
-
-/*initialize function pointer table with Realtek HAL API*/
-wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
-{
-    if (fn == NULL) {
-        return WIFI_ERROR_UNKNOWN;
-    }
-    fn->wifi_initialize = wifi_initialize;
-    fn->wifi_cleanup = wifi_cleanup;
-    fn->wifi_event_loop = wifi_event_loop;
-    fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set;
-    fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix;
-    fn->wifi_set_scanning_mac_oui =  wifi_set_scanning_mac_oui;
-    fn->wifi_get_ifaces = wifi_get_ifaces;
-    fn->wifi_get_iface_name = wifi_get_iface_name;
-    fn->wifi_start_gscan = wifi_start_gscan;
-    fn->wifi_stop_gscan = wifi_stop_gscan;
-    fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results;
-    fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist;
-    fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist;
-    fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler;
-    fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler;
-    fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities;
-    fn->wifi_get_link_stats = wifi_get_link_stats;
-    fn->wifi_set_link_stats = wifi_set_link_stats;
-    fn->wifi_clear_link_stats = wifi_clear_link_stats;
-    fn->wifi_get_valid_channels = wifi_get_valid_channels;
-    fn->wifi_rtt_range_request = wifi_rtt_range_request;
-    fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel;
-    fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities;
-    fn->wifi_rtt_get_responder_info = wifi_rtt_get_responder_info;
-    fn->wifi_enable_responder = wifi_enable_responder;
-    fn->wifi_disable_responder = wifi_disable_responder;
-    fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag;
-    fn->wifi_start_logging = wifi_start_logging;
-    fn->wifi_set_epno_list = wifi_set_epno_list;
-    fn->wifi_reset_epno_list = wifi_reset_epno_list;
-    fn->wifi_set_country_code = wifi_set_country_code;
-    fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump;
-    fn->wifi_set_log_handler = wifi_set_log_handler;
-    fn->wifi_reset_log_handler = wifi_reset_log_handler;
-    fn->wifi_set_alert_handler = wifi_set_alert_handler;
-    fn->wifi_reset_alert_handler = wifi_reset_alert_handler;
-    fn->wifi_get_firmware_version = wifi_get_firmware_version;
-    fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status;
-    fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set;
-    fn->wifi_get_ring_data = wifi_get_ring_data;
-    fn->wifi_get_driver_version = wifi_get_driver_version;
-    fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring;
-    fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring;
-    fn->wifi_configure_nd_offload = wifi_configure_nd_offload;
-    fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet;
-    fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet;
-    fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring;
-    fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates;
-    fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates;
-    fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities;
-    fn->wifi_set_packet_filter = wifi_set_packet_filter;
-       fn->wifi_get_wake_reason_stats = wifi_get_wake_reason_stats;
-    return WIFI_SUCCESS;
-}
-
-wifi_error wifi_initialize(wifi_handle *handle)
-{
-    srand(getpid());
-
-    ALOGI("Initializing wifi");
-    hal_info *info = (hal_info *)malloc(sizeof(hal_info));
-    if (info == NULL) {
-        ALOGE("Could not allocate hal_info");
-        return WIFI_ERROR_UNKNOWN;
-    }
-
-    memset(info, 0, sizeof(*info));
-
-    ALOGI("Creating socket");
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, info->cleanup_socks) == -1) {
-        ALOGE("Could not create cleanup sockets");
-        free(info);
-        return WIFI_ERROR_UNKNOWN;
-    }
-
-    struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT);
-    if (cmd_sock == NULL) {
-        ALOGE("Could not create handle");
-        free(info);
-        return WIFI_ERROR_UNKNOWN;
-    }
-
-    struct nl_sock *event_sock = wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT);
-    if (event_sock == NULL) {
-        ALOGE("Could not create handle");
-        nl_socket_free(cmd_sock);
-        free(info);
-        return WIFI_ERROR_UNKNOWN;
-    }
-
-    struct nl_cb *cb = nl_socket_get_cb(event_sock);
-    if (cb == NULL) {
-        ALOGE("Could not create handle");
-        nl_socket_free(cmd_sock);
-        nl_socket_free(event_sock);
-        free(info);
-        return WIFI_ERROR_UNKNOWN;
-    }
-
-    // ALOGI("cb->refcnt = %d", cb->cb_refcnt);
-    nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, internal_no_seq_check, info);
-    nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler, info);
-    nl_cb_put(cb);
-
-    info->cmd_sock = cmd_sock;
-    info->event_sock = event_sock;
-    info->clean_up = false;
-    info->in_event_loop = false;
-
-    info->event_cb = (cb_info *)malloc(sizeof(cb_info) * DEFAULT_EVENT_CB_SIZE);
-    info->alloc_event_cb = DEFAULT_EVENT_CB_SIZE;
-    info->num_event_cb = 0;
-
-    info->cmd = (cmd_info *)malloc(sizeof(cmd_info) * DEFAULT_CMD_SIZE);
-    info->alloc_cmd = DEFAULT_CMD_SIZE;
-    info->num_cmd = 0;
-
-    info->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211");
-    if (info->nl80211_family_id < 0) {
-        ALOGE("Could not resolve nl80211 familty id");
-        nl_socket_free(cmd_sock);
-        nl_socket_free(event_sock);
-        free(info);
-        return WIFI_ERROR_UNKNOWN;
-    }
-
-    pthread_mutex_init(&info->cb_lock, NULL);
-
-    *handle = (wifi_handle) info;
-
-    if (wifi_init_interfaces(*handle) != WIFI_SUCCESS) {
-        ALOGE("No wifi interface found");
-        nl_socket_free(cmd_sock);
-        nl_socket_free(event_sock);
-        pthread_mutex_destroy(&info->cb_lock);
-        free(info);
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-
-    if ((wifi_add_membership(*handle, "scan") < 0) ||
-        (wifi_add_membership(*handle, "mlme")  < 0) ||
-        (wifi_add_membership(*handle, "regulatory") < 0) ||
-        (wifi_add_membership(*handle, "vendor") < 0)) {
-        ALOGE("Add membership failed");
-        nl_socket_free(cmd_sock);
-        nl_socket_free(event_sock);
-        pthread_mutex_destroy(&info->cb_lock);
-        free(info);
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-
-    // ALOGI("Found %d interfaces", info->num_interfaces);
-
-    ALOGI("Initialized Wifi HAL Successfully; vendor cmd = %d", NL80211_CMD_VENDOR);
-    return WIFI_SUCCESS;
-}
-
-static int wifi_add_membership(wifi_handle handle, const char *group)
-{
-    hal_info *info = getHalInfo(handle);
-
-    int id = wifi_get_multicast_id(handle, "nl80211", group);
-    if (id < 0) {
-        ALOGE("Could not find group %s", group);
-        return id;
-    }
-
-    int ret = nl_socket_add_membership(info->event_sock, id);
-    if (ret < 0) {
-        ALOGE("Could not add membership to group %s", group);
-    }
-
-    // ALOGI("Successfully added membership for group %s", group);
-    return ret;
-}
-
-static void internal_cleaned_up_handler(wifi_handle handle)
-{
-    hal_info *info = getHalInfo(handle);
-    wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler;
-
-    if (info->cmd_sock != 0) {
-        close(info->cleanup_socks[0]);
-        close(info->cleanup_socks[1]);
-        nl_socket_free(info->cmd_sock);
-        nl_socket_free(info->event_sock);
-        info->cmd_sock = NULL;
-        info->event_sock = NULL;
-    }
-
-    (*cleaned_up_handler)(handle);
-    pthread_mutex_destroy(&info->cb_lock);
-    free(info);
-
-    ALOGI("Internal cleanup completed");
-}
-
-void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)
-{
-    hal_info *info = getHalInfo(handle);
-    char buf[64];
-
-    info->cleaned_up_handler = handler;
-    if (TEMP_FAILURE_RETRY(write(info->cleanup_socks[0], "Exit", 4)) < 1) {
-        // As a fallback set the cleanup flag to TRUE
-        ALOGE("could not write to the cleanup socket");
-    } else {
-        // Listen to the response
-        // Hopefully we dont get errors or get hung up
-        // Not much can be done in that case, but assume that
-        // it has rx'ed the Exit message to exit the thread.
-        // As a fallback set the cleanup flag to TRUE
-        memset(buf, 0, sizeof(buf));
-        ssize_t result = TEMP_FAILURE_RETRY(read(info->cleanup_socks[0], buf, sizeof(buf)));
-        ALOGE("%s: Read after POLL returned %zd, error no = %d (%s)", __FUNCTION__,
-               result, errno, strerror(errno));
-        if (strncmp(buf, "Done", 4) == 0) {
-            ALOGE("Event processing terminated");
-        } else {
-            ALOGD("Rx'ed %s", buf);
-        }
-    }
-    info->clean_up = true;
-    pthread_mutex_lock(&info->cb_lock);
-
-    int bad_commands = 0;
-
-    for (int i = 0; i < info->num_event_cb; i++) {
-        cb_info *cbi = &(info->event_cb[i]);
-        WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
-        ALOGI("Command left in event_cb %p:%s", cmd, (cmd ? cmd->getType(): ""));
-    }
-
-    while (info->num_cmd > bad_commands) {
-        int num_cmd = info->num_cmd;
-        cmd_info *cmdi = &(info->cmd[bad_commands]);
-        WifiCommand *cmd = cmdi->cmd;
-        if (cmd != NULL) {
-            ALOGI("Cancelling command %p:%s", cmd, cmd->getType());
-            pthread_mutex_unlock(&info->cb_lock);
-            cmd->cancel();
-            pthread_mutex_lock(&info->cb_lock);
-            if (num_cmd == info->num_cmd) {
-                ALOGI("Cancelling command %p:%s did not work", cmd, (cmd ? cmd->getType(): ""));
-                bad_commands++;
-            }
-            /* release reference added when command is saved */
-            cmd->releaseRef();
-        }
-    }
-
-    for (int i = 0; i < info->num_event_cb; i++) {
-        cb_info *cbi = &(info->event_cb[i]);
-        WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
-        ALOGE("Leaked command %p", cmd);
-    }
-    pthread_mutex_unlock(&info->cb_lock);
-    internal_cleaned_up_handler(handle);
-}
-
-static int internal_pollin_handler(wifi_handle handle)
-{
-    hal_info *info = getHalInfo(handle);
-    struct nl_cb *cb = nl_socket_get_cb(info->event_sock);
-    int res = nl_recvmsgs(info->event_sock, cb);
-    // ALOGD("nl_recvmsgs returned %d", res);
-    nl_cb_put(cb);
-    return res;
-}
-
-/* Run event handler */
-void wifi_event_loop(wifi_handle handle)
-{
-    hal_info *info = getHalInfo(handle);
-    if (info->in_event_loop) {
-        return;
-    } else {
-        info->in_event_loop = true;
-    }
-
-    pollfd pfd[2];
-    memset(&pfd[0], 0, sizeof(pollfd) * 2);
-
-    pfd[0].fd = nl_socket_get_fd(info->event_sock);
-    pfd[0].events = POLLIN;
-    pfd[1].fd = info->cleanup_socks[1];
-    pfd[1].events = POLLIN;
-
-    char buf[2048];
-    /* TODO: Add support for timeouts */
-
-    do {
-        int timeout = -1;                   /* Infinite timeout */
-        pfd[0].revents = 0;
-        pfd[1].revents = 0;
-        // ALOGI("Polling socket");
-        int result = TEMP_FAILURE_RETRY(poll(pfd, 2, timeout));
-        if (result < 0) {
-            // ALOGE("Error polling socket");
-        } else if (pfd[0].revents & POLLERR) {
-            ALOGE("POLL Error; error no = %d (%s)", errno, strerror(errno));
-            ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[0].fd, buf, sizeof(buf)));
-            ALOGE("Read after POLL returned %zd, error no = %d (%s)", result2,
-                  errno, strerror(errno));
-        } else if (pfd[0].revents & POLLHUP) {
-            ALOGE("Remote side hung up");
-            break;
-        } else if (pfd[0].revents & POLLIN) {
-            // ALOGI("Found some events!!!");
-            internal_pollin_handler(handle);
-        } else if (pfd[1].revents & POLLIN) {
-            memset(buf, 0, sizeof(buf));
-            ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[1].fd, buf, sizeof(buf)));
-            ALOGE("%s: Read after POLL returned %zd, error no = %d (%s)", __FUNCTION__,
-                   result2, errno, strerror(errno));
-            if (strncmp(buf, "Exit", 4) == 0) {
-                ALOGD("Got a signal to exit!!!");
-                if (TEMP_FAILURE_RETRY(write(pfd[1].fd, "Done", 4)) < 1) {
-                    ALOGE("could not write to the cleanup socket");
-                }
-                break;
-            } else {
-                ALOGD("Rx'ed %s on the cleanup socket\n", buf);
-            }
-        } else {
-            ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents);
-        }
-    } while (!info->clean_up);
-    ALOGI("Exit %s", __FUNCTION__);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static int internal_no_seq_check(struct nl_msg *msg, void *arg)
-{
-    return NL_OK;
-}
-
-static int internal_valid_message_handler(nl_msg *msg, void *arg)
-{
-    // ALOGI("got an event");
-
-    wifi_handle handle = (wifi_handle)arg;
-    hal_info *info = getHalInfo(handle);
-
-    WifiEvent event(msg);
-    int res = event.parse();
-    if (res < 0) {
-        ALOGE("Failed to parse event: %d", res);
-        return NL_SKIP;
-    }
-
-    int cmd = event.get_cmd();
-    uint32_t vendor_id = 0;
-    int subcmd = 0;
-
-    if (cmd == NL80211_CMD_VENDOR) {
-        vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID);
-        subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD);
-        ALOGV("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x",
-                event.get_cmdString(), vendor_id, subcmd);
-    } else {
-        // ALOGV("event received %s", event.get_cmdString());
-    }
-
-    // ALOGV("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id);
-    // event.log();
-
-    bool dispatched = false;
-
-    pthread_mutex_lock(&info->cb_lock);
-
-    for (int i = 0; i < info->num_event_cb; i++) {
-        if (cmd == info->event_cb[i].nl_cmd) {
-            if (cmd == NL80211_CMD_VENDOR
-                && ((vendor_id != info->event_cb[i].vendor_id)
-                || (subcmd != info->event_cb[i].vendor_subcmd)))
-            {
-                /* event for a different vendor, ignore it */
-                continue;
-            }
-
-            cb_info *cbi = &(info->event_cb[i]);
-            nl_recvmsg_msg_cb_t cb_func = cbi->cb_func;
-            void *cb_arg = cbi->cb_arg;
-            WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
-            if (cmd != NULL) {
-                cmd->addRef();
-            }
-            pthread_mutex_unlock(&info->cb_lock);
-            if (cb_func)
-                (*cb_func)(msg, cb_arg);
-            if (cmd != NULL) {
-                cmd->releaseRef();
-            }
-
-            return NL_OK;
-        }
-    }
-
-    pthread_mutex_unlock(&info->cb_lock);
-    return NL_OK;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-class GetMulticastIdCommand : public WifiCommand
-{
-private:
-    const char *mName;
-    const char *mGroup;
-    int   mId;
-public:
-    GetMulticastIdCommand(wifi_handle handle, const char *name, const char *group)
-        : WifiCommand("GetMulticastIdCommand", handle, 0)
-    {
-        mName = name;
-        mGroup = group;
-        mId = -1;
-    }
-
-    int getId() {
-        return mId;
-    }
-
-    virtual int create() {
-        int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl");
-        // ALOGI("ctrl family = %d", nlctrlFamily);
-        int ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0);
-        if (ret < 0) {
-            return ret;
-        }
-        ret = mMsg.put_string(CTRL_ATTR_FAMILY_NAME, mName);
-        return ret;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-
-        // ALOGI("handling reponse in %s", __func__);
-
-        struct nlattr **tb = reply.attributes();
-        struct genlmsghdr *gnlh = reply.header();
-        struct nlattr *mcgrp = NULL;
-        int i;
-
-        if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
-            ALOGI("No multicast groups found");
-            return NL_SKIP;
-        } else {
-            // ALOGI("Multicast groups attr size = %d", nla_len(tb[CTRL_ATTR_MCAST_GROUPS]));
-        }
-
-        for_each_attr(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
-
-            // ALOGI("Processing group");
-            struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
-            nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, (nlattr *)nla_data(mcgrp),
-                nla_len(mcgrp), NULL);
-            if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || !tb2[CTRL_ATTR_MCAST_GRP_ID]) {
-                continue;
-            }
-
-            char *grpName = (char *)nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
-            int grpNameLen = nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
-
-            // ALOGI("Found group name %s", grpName);
-
-            if (strncmp(grpName, mGroup, grpNameLen) != 0)
-                continue;
-
-            mId = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
-            break;
-        }
-
-        return NL_SKIP;
-    }
-
-};
-
-class SetPnoMacAddrOuiCommand : public WifiCommand {
-
-private:
-    byte *mOui;
-    feature_set *fset;
-    feature_set *feature_matrix;
-    int *fm_size;
-    int set_size_max;
-public:
-    SetPnoMacAddrOuiCommand(wifi_interface_handle handle, oui scan_oui)
-        : WifiCommand("SetPnoMacAddrOuiCommand", handle, 0)
-    {
-        mOui = scan_oui;
-    }
-
-    int createRequest(WifiRequest& request, int subcmd, byte *scan_oui) {
-        int result = request.create(GOOGLE_OUI, subcmd);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put(ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, scan_oui, DOT11_OUI_LEN);
-        if (result < 0) {
-            return result;
-        }
-
-        request.attr_end(data);
-        return WIFI_SUCCESS;
-
-    }
-
-    int start() {
-        ALOGD("Sending mac address OUI");
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request, WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, mOui);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create request; result = %d", result);
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to set scanning mac OUI; result = %d", result);
-        }
-
-        return result;
-    }
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-         ALOGD("Request complete!");
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-};
-
-class SetNodfsCommand : public WifiCommand {
-
-private:
-    u32 mNoDfs;
-public:
-    SetNodfsCommand(wifi_interface_handle handle, u32 nodfs)
-        : WifiCommand("SetNodfsCommand", handle, 0) {
-        mNoDfs = nodfs;
-    }
-    virtual int create() {
-        int ret;
-
-        ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_NODFS_SET);
-        if (ret < 0) {
-            ALOGE("Can't create message to send to driver - %d", ret);
-            return ret;
-        }
-
-        nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
-        ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_NODFS_SET, mNoDfs);
-        if (ret < 0) {
-             return ret;
-        }
-
-        mMsg.attr_end(data);
-        return WIFI_SUCCESS;
-    }
-};
-
-class SetCountryCodeCommand : public WifiCommand {
-private:
-    const char *mCountryCode;
-public:
-    SetCountryCodeCommand(wifi_interface_handle handle, const char *country_code)
-        : WifiCommand("SetCountryCodeCommand", handle, 0) {
-        mCountryCode = country_code;
-        }
-    virtual int create() {
-        int ret;
-
-        ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_COUNTRY_CODE);
-        if (ret < 0) {
-             ALOGE("Can't create message to send to driver - %d", ret);
-             return ret;
-        }
-
-        nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
-        ret = mMsg.put_string(ANDR_WIFI_ATTRIBUTE_COUNTRY, mCountryCode);
-        if (ret < 0) {
-            return ret;
-        }
-
-        mMsg.attr_end(data);
-        return WIFI_SUCCESS;
-
-    }
-};
-
-class SetRSSIMonitorCommand : public WifiCommand {
-private:
-    s8 mMax_rssi;
-    s8 mMin_rssi;
-    wifi_rssi_event_handler mHandler;
-public:
-    SetRSSIMonitorCommand(wifi_request_id id, wifi_interface_handle handle,
-                s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
-        : WifiCommand("SetRSSIMonitorCommand", handle, id), mMax_rssi(max_rssi), mMin_rssi
-        (min_rssi), mHandler(eh)
-        {
-        }
-   int createRequest(WifiRequest& request, int enable) {
-        int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0));
-        if (result < 0) {
-            return result;
-        }
-        ALOGD("create request");
-        result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0));
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_START, enable);
-        if (result < 0) {
-            return result;
-        }
-        request.attr_end(data);
-        return result;
-    }
-
-    int start() {
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request, 1);
-        if (result < 0) {
-            return result;
-        }
-        result = requestResponse(request);
-        if (result < 0) {
-            ALOGI("Failed to set RSSI Monitor, result = %d", result);
-            return result;
-        }
-        ALOGI("Successfully set RSSI monitoring");
-        registerVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
-
-
-        if (result < 0) {
-            unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
-            return result;
-        }
-        ALOGI("Done!");
-        return result;
-    }
-
-    virtual int cancel() {
-
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request, 0);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create request; result = %d", result);
-        } else {
-            result = requestResponse(request);
-            if (result != WIFI_SUCCESS) {
-                ALOGE("failed to stop RSSI monitoring = %d", result);
-            }
-        }
-        unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
-        return WIFI_SUCCESS;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-   virtual int handleEvent(WifiEvent& event) {
-        ALOGI("Got a RSSI monitor event");
-
-        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = event.get_vendor_data_len();
-
-        if (vendor_data == NULL || len == 0) {
-            ALOGI("RSSI monitor: No data");
-            return NL_SKIP;
-        }
-        /* driver<->HAL event structure */
-        #define RSSI_MONITOR_EVT_VERSION   1
-        typedef struct {
-            u8 version;
-            s8 cur_rssi;
-            mac_addr BSSID;
-        } rssi_monitor_evt;
-
-        rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data();
-
-        if (data->version != RSSI_MONITOR_EVT_VERSION) {
-            ALOGI("Event version mismatch %d, expected %d", data->version, RSSI_MONITOR_EVT_VERSION);
-            return NL_SKIP;
-        }
-
-        if (*mHandler.on_rssi_threshold_breached) {
-            (*mHandler.on_rssi_threshold_breached)(id(), data->BSSID, data->cur_rssi);
-        } else {
-            ALOGW("No RSSI monitor handler registered");
-        }
-
-        return NL_SKIP;
-    }
-
-};
-
-class AndroidPktFilterCommand : public WifiCommand {
-    private:
-        const u8* mProgram;
-        u32 mProgramLen;
-        u32* mVersion;
-        u32* mMaxLen;
-        int mReqType;
-    public:
-        AndroidPktFilterCommand(wifi_interface_handle handle,
-                u32* version, u32* max_len)
-            : WifiCommand("AndroidPktFilterCommand", handle, 0),
-                    mVersion(version), mMaxLen(max_len),
-                    mReqType(GET_APF_CAPABILITIES)
-        {
-        }
-
-        AndroidPktFilterCommand(wifi_interface_handle handle,
-                const u8* program, u32 len)
-            : WifiCommand("AndroidPktFilterCommand", handle, 0),
-                    mProgram(program), mProgramLen(len),
-                    mReqType(SET_APF_PROGRAM)
-        {
-        }
-
-    int createRequest(WifiRequest& request) {
-        if (mReqType == SET_APF_PROGRAM) {
-            ALOGI("\n%s: APF set program request\n", __FUNCTION__);
-            return createSetPktFilterRequest(request);
-        } else if (mReqType == GET_APF_CAPABILITIES) {
-            ALOGI("\n%s: APF get capabilities request\n", __FUNCTION__);
-            return createGetPktFilterCapabilitesRequest(request);
-        } else {
-            ALOGE("\n%s Unknown APF request\n", __FUNCTION__);
-            return WIFI_ERROR_NOT_SUPPORTED;
-        }
-        return WIFI_SUCCESS;
-    }
-
-    int createSetPktFilterRequest(WifiRequest& request) {
-        u8 *program = new u8[mProgramLen];
-        NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        int result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u32(APF_ATTRIBUTE_PROGRAM_LEN, mProgramLen);
-        if (result < 0) {
-            return result;
-        }
-        memcpy(program, mProgram, mProgramLen);
-        result = request.put(APF_ATTRIBUTE_PROGRAM, program, mProgramLen);
-        if (result < 0) {
-            return result;
-        }
-        request.attr_end(data);
-        delete[] program;
-        return result;
-    }
-
-    int createGetPktFilterCapabilitesRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, APF_SUBCMD_GET_CAPABILITIES);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        request.attr_end(data);
-        return result;
-    }
-
-    int start() {
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request);
-        if (result < 0) {
-            return result;
-        }
-        result = requestResponse(request);
-        if (result < 0) {
-            ALOGI("Request Response failed for APF, result = %d", result);
-            return result;
-        }
-        ALOGI("Done!");
-        return result;
-    }
-
-    int cancel() {
-        return WIFI_SUCCESS;
-    }
-
-    int handleResponse(WifiEvent& reply) {
-        ALOGD("In SetAPFCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-
-        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = reply.get_vendor_data_len();
-
-        ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
-        if (vendor_data == NULL || len == 0) {
-            ALOGE("no vendor data in SetAPFCommand response; ignoring it");
-            return NL_SKIP;
-        }
-        if( mReqType == SET_APF_PROGRAM) {
-            ALOGD("Response recieved for set packet filter command\n");
-        } else if (mReqType == GET_APF_CAPABILITIES) {
-            *mVersion = 0;
-            *mMaxLen = 0;
-            ALOGD("Response recieved for get packet filter capabilities command\n");
-            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
-                if (it.get_type() == APF_ATTRIBUTE_VERSION) {
-                    *mVersion = it.get_u32();
-                    ALOGI("APF version is %d\n", *mVersion);
-                } else if (it.get_type() == APF_ATTRIBUTE_MAX_LEN) {
-                    *mMaxLen = it.get_u32();
-                    ALOGI("APF max len is %d\n", *mMaxLen);
-                } else {
-                    ALOGE("Ignoring invalid attribute type = %d, size = %d",
-                            it.get_type(), it.get_len());
-                }
-            }
-        }
-        return NL_OK;
-    }
-
-    int handleEvent(WifiEvent& event) {
-        /* No Event to recieve for APF commands */
-        return NL_SKIP;
-    }
-};
-
-class SetNdoffloadCommand : public WifiCommand {
-
-private:
-    u8 mEnable;
-public:
-    SetNdoffloadCommand(wifi_interface_handle handle, u8 enable)
-        : WifiCommand("SetNdoffloadCommand", handle, 0) {
-        mEnable = enable;
-    }
-    virtual int create() {
-        int ret;
-
-        ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_ND_OFFLOAD);
-        if (ret < 0) {
-            ALOGE("Can't create message to send to driver - %d", ret);
-            return ret;
-        }
-
-        nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
-        ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE, mEnable);
-        if (ret < 0) {
-             return ret;
-        }
-
-        mMsg.attr_end(data);
-        return WIFI_SUCCESS;
-    }
-};
-
-class GetFeatureSetCommand : public WifiCommand {
-
-private:
-    int feature_type;
-    feature_set *fset;
-    feature_set *feature_matrix;
-    int *fm_size;
-    int set_size_max;
-public:
-    GetFeatureSetCommand(wifi_interface_handle handle, int feature, feature_set *set,
-         feature_set set_matrix[], int *size, int max_size)
-        : WifiCommand("GetFeatureSetCommand", handle, 0)
-    {
-        feature_type = feature;
-        fset = set;
-        feature_matrix = set_matrix;
-        fm_size = size;
-        set_size_max = max_size;
-    }
-
-    virtual int create() {
-        int ret;
-
-        if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
-            ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET);
-        } else if (feature_type == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) {
-            ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET_MATRIX);
-        } else {
-            ALOGE("Unknown feature type %d", feature_type);
-            return -1;
-        }
-
-        if (ret < 0) {
-            ALOGE("Can't create message to send to driver - %d", ret);
-        }
-
-        return ret;
-    }
-
-protected:
-    virtual int handleResponse(WifiEvent& reply) {
-
-        ALOGV("In GetFeatureSetCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-
-        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = reply.get_vendor_data_len();
-
-        ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
-        if (vendor_data == NULL || len == 0) {
-            ALOGE("no vendor data in GetFeatureSetCommand response; ignoring it");
-            return NL_SKIP;
-        }
-        if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
-            void *data = reply.get_vendor_data();
-            if(!fset) {
-                ALOGE("Buffers pointers not set");
-                return NL_SKIP;
-            }
-            memcpy(fset, data, min(len, (int) sizeof(*fset)));
-        } else {
-            int num_features_set = 0;
-            int i = 0;
-
-            if(!feature_matrix || !fm_size) {
-                ALOGE("Buffers pointers not set");
-                return NL_SKIP;
-            }
-
-            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
-                if (it.get_type() == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
-                    num_features_set = it.get_u32();
-                    ALOGV("Got feature list with %d concurrent sets", num_features_set);
-                    if(set_size_max && (num_features_set > set_size_max))
-                        num_features_set = set_size_max;
-                    *fm_size = num_features_set;
-                } else if ((it.get_type() == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) &&
-                             i < num_features_set) {
-                    feature_matrix[i] = it.get_u32();
-                    i++;
-                } else {
-                    ALOGW("Ignoring invalid attribute type = %d, size = %d",
-                            it.get_type(), it.get_len());
-                }
-            }
-
-        }
-        return NL_OK;
-    }
-
-};
-
-static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group)
-{
-    GetMulticastIdCommand cmd(handle, name, group);
-    int res = cmd.requestResponse();
-    if (res < 0)
-        return res;
-    else
-        return cmd.getId();
-}
-
-/////////////////////////////////////////////////////////////////////////
-
-static bool is_wifi_interface(const char *name)
-{
-    if (strncmp(name, "wlan", 4) != 0 && strncmp(name, "p2p", 3) != 0) {
-        /* not a wifi interface; ignore it */
-        return false;
-    } else {
-        return true;
-    }
-}
-
-static int get_interface(const char *name, interface_info *info)
-{
-    strcpy(info->name, name);
-    info->id = if_nametoindex(name);
-    // ALOGI("found an interface : %s, id = %d", name, info->id);
-    return WIFI_SUCCESS;
-}
-
-wifi_error wifi_init_interfaces(wifi_handle handle)
-{
-    hal_info *info = (hal_info *)handle;
-
-    struct dirent *de;
-
-    DIR *d = opendir("/sys/class/net");
-    if (d == 0)
-        return WIFI_ERROR_UNKNOWN;
-
-    int n = 0;
-    while ((de = readdir(d))) {
-        if (de->d_name[0] == '.')
-            continue;
-        if (is_wifi_interface(de->d_name) ) {
-            n++;
-        }
-    }
-
-    closedir(d);
-
-    if (n == 0)
-        return WIFI_ERROR_NOT_AVAILABLE;
-
-    d = opendir("/sys/class/net");
-    if (d == 0)
-        return WIFI_ERROR_UNKNOWN;
-
-    info->interfaces = (interface_info **)malloc(sizeof(interface_info *) * n);
-
-    int i = 0;
-    while ((de = readdir(d))) {
-        if (de->d_name[0] == '.')
-            continue;
-        if (is_wifi_interface(de->d_name)) {
-            interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info));
-            if (get_interface(de->d_name, ifinfo) != WIFI_SUCCESS) {
-                free(ifinfo);
-                continue;
-            }
-            ifinfo->handle = handle;
-            info->interfaces[i] = ifinfo;
-            i++;
-        }
-    }
-
-    closedir(d);
-
-    info->num_interfaces = n;
-    return WIFI_SUCCESS;
-}
-
-wifi_error wifi_get_ifaces(wifi_handle handle, int *num, wifi_interface_handle **interfaces)
-{
-    hal_info *info = (hal_info *)handle;
-
-    *interfaces = (wifi_interface_handle *)info->interfaces;
-    *num = info->num_interfaces;
-
-    return WIFI_SUCCESS;
-}
-
-wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t size)
-{
-    interface_info *info = (interface_info *)handle;
-    strcpy(name, info->name);
-    return WIFI_SUCCESS;
-}
-
-wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
-{
-    GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, set, NULL, NULL, 1);
-    return (wifi_error) command.requestResponse();
-}
-
-wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
-       feature_set set[], int *set_size)
-{
-    GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, NULL,
-            set, set_size, set_size_max);
-    return (wifi_error) command.requestResponse();
-}
-
-wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui)
-{
-#if 0
-    SetPnoMacAddrOuiCommand command(handle, scan_oui);
-    return (wifi_error)command.start();
-#endif
-       return WIFI_SUCCESS;
-
-}
-
-wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs)
-{
-    SetNodfsCommand command(handle, nodfs);
-    return (wifi_error) command.requestResponse();
-}
-
-wifi_error wifi_set_country_code(wifi_interface_handle handle, const char *country_code)
-{
-#if 0
-    SetCountryCodeCommand command(handle, country_code);
-    return (wifi_error) command.requestResponse();
-#endif
-       return WIFI_SUCCESS ;
-}
-
-static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
-                        iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
-{
-    ALOGD("Start RSSI monitor %d", id);
-    wifi_handle handle = getWifiHandle(iface);
-    SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, max_rssi, min_rssi, eh);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = wifi_register_cmd(handle, id, cmd);
-    if (result != WIFI_SUCCESS) {
-        cmd->releaseRef();
-        return result;
-    }
-    result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-        cmd->releaseRef();
-        return result;
-    }
-    return result;
-}
-
-static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface)
-{
-    ALOGD("Stopping RSSI monitor");
-
-    if(id == -1) {
-        wifi_rssi_event_handler handler;
-        s8 max_rssi = 0, min_rssi = 0;
-        wifi_handle handle = getWifiHandle(iface);
-        memset(&handler, 0, sizeof(handler));
-        SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface,
-                                                    max_rssi, min_rssi, handler);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        cmd->cancel();
-        cmd->releaseRef();
-        return WIFI_SUCCESS;
-    }
-    return wifi_cancel_cmd(id, iface);
-}
-
-static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
-        u32 *version, u32 *max_len)
-{
-#if 0
-    ALOGD("Getting APF capabilities, halHandle = %p\n", handle);
-    AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, version, max_len);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = (wifi_error)cmd->start();
-    if (result == WIFI_SUCCESS) {
-        ALOGD("Getting APF capability, version = %d, max_len = %d\n", *version, *max_len);
-    }
-    cmd->releaseRef();
-    return result;
-#endif
-       return WIFI_SUCCESS;
-}
-
-static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
-        const u8 *program, u32 len)
-{
-    ALOGD("Setting APF program, halHandle = %p\n", handle);
-    AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, program, len);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = (wifi_error)cmd->start();
-    cmd->releaseRef();
-    return result;
-}
-
-static wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable)
-{
-#if 0
-    SetNdoffloadCommand command(handle, enable);
-    return (wifi_error) command.requestResponse();
-#endif
-       return WIFI_SUCCESS;
-}
-
-static wifi_error wifi_get_wake_reason_stats (wifi_interface_handle handle,
-                                WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt) {
-                                
-       return WIFI_SUCCESS;
-}
-
-/////////////////////////////////////////////////////////////////////////////
diff --git a/wlan/wifi_hal/wifi_logger.cpp b/wlan/wifi_hal/wifi_logger.cpp
deleted file mode 100644 (file)
index d53a010..0000000
+++ /dev/null
@@ -1,1148 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <string>
-#include <stdint.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/rtnetlink.h>
-#include <netpacket/packet.h>
-#include <linux/filter.h>
-#include <linux/errqueue.h>
-
-#include <linux/pkt_sched.h>
-#include <netlink/object-api.h>
-#include <netlink/netlink.h>
-#include <netlink/socket.h>
-#include <netlink-private/object-api.h>
-#include <netlink-private/types.h>
-
-#include "nl80211_copy.h"
-#include "sync.h"
-
-#define LOG_TAG  "WifiHAL"
-
-#include <log/log.h>
-
-#include "wifi_hal.h"
-#include "common.h"
-#include "cpp_bindings.h"
-
-typedef enum {
-    LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START,
-    LOGGER_TRIGGER_MEM_DUMP,
-    LOGGER_GET_MEM_DUMP,
-    LOGGER_GET_VER,
-    LOGGER_GET_RING_STATUS,
-    LOGGER_GET_RING_DATA,
-    LOGGER_GET_FEATURE,
-    LOGGER_RESET_LOGGING,
-    LOGGER_TRIGGER_DRIVER_MEM_DUMP,
-    LOGGER_GET_DRIVER_MEM_DUMP,
-    LOGGER_START_PKT_FATE_MONITORING,
-    LOGGER_GET_TX_PKT_FATES,
-    LOGGER_GET_RX_PKT_FATES,
-} DEBUG_SUB_COMMAND;
-
-typedef enum {
-    LOGGER_ATTRIBUTE_DRIVER_VER,
-    LOGGER_ATTRIBUTE_FW_VER,
-    LOGGER_ATTRIBUTE_RING_ID,
-    LOGGER_ATTRIBUTE_RING_NAME,
-    LOGGER_ATTRIBUTE_RING_FLAGS,
-    LOGGER_ATTRIBUTE_LOG_LEVEL,
-    LOGGER_ATTRIBUTE_LOG_TIME_INTVAL,
-    LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE,
-    LOGGER_ATTRIBUTE_FW_DUMP_LEN,
-    LOGGER_ATTRIBUTE_FW_DUMP_DATA,
-    // LOGGER_ATTRIBUTE_FW_ERR_CODE,
-    LOGGER_ATTRIBUTE_RING_DATA,
-    LOGGER_ATTRIBUTE_RING_STATUS,
-    LOGGER_ATTRIBUTE_RING_NUM,
-    LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN,
-    LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA,
-    LOGGER_ATTRIBUTE_PKT_FATE_NUM,
-    LOGGER_ATTRIBUTE_PKT_FATE_DATA,
-} LOGGER_ATTRIBUTE;
-
-typedef enum {
-    DEBUG_OFF = 0,
-    DEBUG_NORMAL,
-    DEBUG_VERBOSE,
-    DEBUG_VERY,
-    DEBUG_VERY_VERY,
-} LOGGER_LEVEL;
-
-typedef enum {
-    GET_FW_VER,
-    GET_DRV_VER,
-    GET_RING_DATA,
-    GET_RING_STATUS,
-    GET_FEATURE,
-    START_RING_LOG,
-} GetCmdType;
-
-typedef enum {
-    PACKET_MONITOR_START,
-    TX_PACKET_FATE,
-    RX_PACKET_FATE,
-} PktFateReqType;
-
-
-///////////////////////////////////////////////////////////////////////////////
-class DebugCommand : public WifiCommand
-{
-    char *mBuff;
-    int *mBuffSize;
-    u32 *mNumRings;
-    wifi_ring_buffer_status *mStatus;
-    unsigned int *mSupport;
-    u32 mVerboseLevel;
-    u32 mFlags;
-    u32 mMaxIntervalSec;
-    u32 mMinDataSize;
-    char *mRingName;
-    GetCmdType mType;
-
-public:
-
-    // constructor for get version
-    DebugCommand(wifi_interface_handle iface, char *buffer, int *buffer_size,
-            GetCmdType cmdType)
-        : WifiCommand("DebugCommand", iface, 0), mBuff(buffer), mBuffSize(buffer_size), mType
-        (cmdType)
-    {
-        memset(mBuff, 0, *mBuffSize);
-    }
-
-    // constructor for ring data
-    DebugCommand(wifi_interface_handle iface, char *ring_name, GetCmdType cmdType)
-        : WifiCommand("DebugCommand", iface, 0), mRingName(ring_name), mType(cmdType)
-    { }
-
-    // constructor for ring status
-    DebugCommand(wifi_interface_handle iface, u32 *num_rings,
-            wifi_ring_buffer_status *status, GetCmdType cmdType)
-        : WifiCommand("DebugCommand", iface, 0), mNumRings(num_rings), mStatus(status), mType(cmdType)
-    {
-        memset(mStatus, 0, sizeof(wifi_ring_buffer_status) * (*mNumRings));
-    }
-
-    // constructor for feature set
-    DebugCommand(wifi_interface_handle iface, unsigned int *support, GetCmdType cmdType)
-        : WifiCommand("DebugCommand", iface, 0), mSupport(support), mType(cmdType)
-    { }
-
-    // constructor for ring params
-    DebugCommand(wifi_interface_handle iface, u32 verbose_level, u32 flags,
-            u32 max_interval_sec, u32 min_data_size, char *ring_name, GetCmdType cmdType)
-        : WifiCommand("DebugCommand", iface, 0), mVerboseLevel(verbose_level), mFlags(flags),
-        mMaxIntervalSec(max_interval_sec), mMinDataSize(min_data_size),
-        mRingName(ring_name), mType(cmdType)
-    { }
-
-    int createRingRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, LOGGER_START_LOGGING);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to create start ring logger request; result = %d", result);
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-
-        result = request.put_u32(LOGGER_ATTRIBUTE_LOG_LEVEL, mVerboseLevel);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to put log level; result = %d", result);
-            return result;
-        }
-        result = request.put_u32(LOGGER_ATTRIBUTE_RING_FLAGS, mFlags);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to put ring flags; result = %d", result);
-            return result;
-        }
-        result = request.put_u32(LOGGER_ATTRIBUTE_LOG_TIME_INTVAL, mMaxIntervalSec);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to put log time interval; result = %d", result);
-            return result;
-        }
-        result = request.put_u32(LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE, mMinDataSize);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to put min data size; result = %d", result);
-            return result;
-        }
-        result = request.put_string(LOGGER_ATTRIBUTE_RING_NAME, mRingName);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to put ringbuffer name; result = %d", result);
-            return result;
-        }
-        request.attr_end(data);
-
-        return WIFI_SUCCESS;
-    }
-
-    int createRequest(WifiRequest &request) {
-        int result;
-
-        switch (mType) {
-            case GET_FW_VER:
-            {
-                result = request.create(GOOGLE_OUI, LOGGER_GET_VER);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to create get fw version request; result = %d", result);
-                    return result;
-                }
-
-                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-
-                // Driver expecting only attribute type, passing mbuff as data with
-                // length 0 to avoid undefined state
-                result = request.put(LOGGER_ATTRIBUTE_FW_VER, mBuff, 0);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to put get fw version request; result = %d", result);
-                    return result;
-                }
-                request.attr_end(data);
-                break;
-            }
-
-            case GET_DRV_VER:
-            {
-                result = request.create(GOOGLE_OUI, LOGGER_GET_VER);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to create get drv version request; result = %d", result);
-                    return result;
-                }
-
-                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-
-                // Driver expecting only attribute type, passing mbuff as data with
-                // length 0 to avoid undefined state
-                result = request.put(LOGGER_ATTRIBUTE_DRIVER_VER, mBuff, 0);
-
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to put get drv version request; result = %d", result);
-                    return result;
-                }
-                request.attr_end(data);
-                break;
-            }
-
-            case GET_RING_DATA:
-            {
-                result = request.create(GOOGLE_OUI, LOGGER_GET_RING_DATA);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to create get ring data request; result = %d", result);
-                    return result;
-                }
-
-                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-                result = request.put_string(LOGGER_ATTRIBUTE_RING_NAME, mRingName);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to put ring data request; result = %d", result);
-                    return result;
-                }
-                request.attr_end(data);
-                break;
-            }
-
-            case GET_RING_STATUS:
-            {
-                result = request.create(GOOGLE_OUI, LOGGER_GET_RING_STATUS);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to create get ring status request; result = %d", result);
-                    return result;
-                }
-                break;
-            }
-
-            case GET_FEATURE:
-            {
-                result = request.create(GOOGLE_OUI, LOGGER_GET_FEATURE);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to create get feature request; result = %d", result);
-                    return result;
-                }
-                break;
-            }
-
-            case START_RING_LOG:
-                result = createRingRequest(request);
-                break;
-
-            default:
-                ALOGE("Unknown Debug command");
-                result = WIFI_ERROR_UNKNOWN;
-        }
-        return result;
-    }
-
-    int start() {
-        // ALOGD("Start debug command");
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to create debug request; result = %d", result);
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to register debug response; result = %d", result);
-        }
-        return result;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        ALOGD("In DebugCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        switch (mType) {
-            case GET_DRV_VER:
-            case GET_FW_VER:
-            {
-                void *data = reply.get_vendor_data();
-                int len = reply.get_vendor_data_len();
-
-                ALOGD("len = %d, expected len = %d", len, *mBuffSize);
-                memcpy(mBuff, data, min(len, *mBuffSize));
-                if (*mBuffSize < len)
-                    return NL_SKIP;
-                *mBuffSize = len;
-                break;
-            }
-
-            case START_RING_LOG:
-            case GET_RING_DATA:
-                break;
-
-            case GET_RING_STATUS:
-            {
-                nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
-                int len = reply.get_vendor_data_len();
-                wifi_ring_buffer_status *status(mStatus);
-
-                if (vendor_data == NULL || len == 0) {
-                    ALOGE("No Debug data found");
-                    return NL_SKIP;
-                }
-
-                nl_iterator it(vendor_data);
-                if (it.get_type() == LOGGER_ATTRIBUTE_RING_NUM) {
-                    unsigned int num_rings = it.get_u32();
-                    if (*mNumRings < num_rings) {
-                        ALOGE("Not enough status buffers provided, available: %d required: %d",
-                                *mNumRings, num_rings);
-                    } else {
-                        *mNumRings = num_rings;
-                    }
-                } else {
-                    ALOGE("Unknown attribute: %d expecting %d",
-                            it.get_type(), LOGGER_ATTRIBUTE_RING_NUM);
-                    return NL_SKIP;
-                }
-
-                it.next();
-                for (unsigned int i = 0; it.has_next() && i < *mNumRings; it.next()) {
-                    if (it.get_type() == LOGGER_ATTRIBUTE_RING_STATUS) {
-                        memcpy(status, it.get_data(), sizeof(wifi_ring_buffer_status));
-                        i++;
-                        status++;
-                    } else {
-                        ALOGW("Ignoring invalid attribute type = %d, size = %d",
-                                it.get_type(), it.get_len());
-                    }
-                }
-                break;
-            }
-
-            case GET_FEATURE:
-            {
-                void *data = reply.get_vendor_data();
-                int len = reply.get_vendor_data_len();
-
-                ALOGD("len = %d, expected len = %d", len, sizeof(unsigned int));
-                memcpy(mSupport, data, sizeof(unsigned int));
-                break;
-            }
-
-            default:
-                ALOGW("Unknown Debug command");
-        }
-        return NL_OK;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        /* NO events! */
-        return NL_SKIP;
-    }
-};
-
-/* API to collect a firmware version string */
-wifi_error wifi_get_firmware_version(wifi_interface_handle iface, char *buffer,
-        int buffer_size)
-{
-#if 0
-    if (buffer && (buffer_size > 0)) {
-        DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_FW_VER);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        wifi_error result = (wifi_error)cmd->start();
-        cmd->releaseRef();
-        return result;
-    } else {
-        ALOGE("FW version buffer NULL");
-        return  WIFI_ERROR_INVALID_ARGS;
-    }
-#endif
-       std::string pFirmwareVer = "RTK_FIRMWARE";
-       memcpy(buffer, pFirmwareVer.c_str(), pFirmwareVer.length()+1);
-       return WIFI_SUCCESS;
-}
-
-/* API to collect a driver version string */
-wifi_error wifi_get_driver_version(wifi_interface_handle iface, char *buffer, int buffer_size)
-{
-#if 0
-    if (buffer && (buffer_size > 0)) {
-        DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_DRV_VER);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        wifi_error result = (wifi_error)cmd->start();
-        cmd->releaseRef();
-        return result;
-    } else {
-        ALOGE("Driver version buffer NULL");
-        return  WIFI_ERROR_INVALID_ARGS;
-    }
-#endif
-       std::string pDriverVer = "RTK_DRIVER";
-       memcpy(buffer, pDriverVer.c_str(), pDriverVer.length()+1);
-       return WIFI_SUCCESS;
-}
-
-/* API to collect driver records */
-wifi_error wifi_get_ring_data(wifi_interface_handle iface, char *ring_name)
-{
-#if 0
-    DebugCommand *cmd = new DebugCommand(iface, ring_name, GET_RING_DATA);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = (wifi_error)cmd->start();
-    cmd->releaseRef();
-    return result;
-#endif
-       return WIFI_SUCCESS;
-}
-
-/* API to get the status of all ring buffers supported by driver */
-wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface,
-        u32 *num_rings, wifi_ring_buffer_status *status)
-{
-#if 0
-    if (status && num_rings) {
-        DebugCommand *cmd = new DebugCommand(iface, num_rings, status, GET_RING_STATUS);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        wifi_error result = (wifi_error)cmd->start();
-        cmd->releaseRef();
-        return result;
-    } else {
-        ALOGE("Ring status buffer NULL");
-        return  WIFI_ERROR_INVALID_ARGS;
-    }
-#endif
-       wifi_ring_buffer_status* pLocalstatus = NULL;
-       std::string from = "RTK_RING";
-       memcpy(status->name, from.c_str(), strlen(from.c_str())+1);
-       *num_rings = 1;
-       
-       return  WIFI_SUCCESS;
-}
-
-/* API to get supportable feature */
-wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,
-        unsigned int *support)
-{
-    if (support) {
-               wifi_error result = WIFI_SUCCESS;
-               #if 0
-        DebugCommand *cmd = new DebugCommand(iface, support, GET_FEATURE);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        wifi_error result = (wifi_error)cmd->start();
-        cmd->releaseRef();
-               #endif
-               *support = WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
-               
-        return result;
-    } else {
-        ALOGE("Get support buffer NULL");
-        return  WIFI_ERROR_INVALID_ARGS;
-    }
-}
-
-wifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level,
-        u32 flags, u32 max_interval_sec, u32 min_data_size, char *ring_name)
-{
-#if 0
-    if (ring_name) {
-        DebugCommand *cmd = new DebugCommand(iface, verbose_level, flags, max_interval_sec,
-                    min_data_size, ring_name, START_RING_LOG);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        wifi_error result = (wifi_error)cmd->start();
-        cmd->releaseRef();
-        return result;
-    } else {
-        ALOGE("Ring name NULL");
-        return  WIFI_ERROR_INVALID_ARGS;
-    }
-#endif
-       return WIFI_SUCCESS;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-class SetLogHandler : public WifiCommand
-{
-    wifi_ring_buffer_data_handler mHandler;
-
-public:
-    SetLogHandler(wifi_interface_handle iface, int id, wifi_ring_buffer_data_handler handler)
-        : WifiCommand("SetLogHandler", iface, id), mHandler(handler)
-    { }
-
-    int start() {
-        ALOGV("Register loghandler");
-        registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
-        return WIFI_SUCCESS;
-    }
-
-    virtual int cancel() {
-        /* Send a command to driver to stop generating logging events */
-        ALOGV("Clear loghandler");
-
-        /* unregister event handler */
-        unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
-
-        WifiRequest request(familyId(), ifaceId());
-        int result = request.create(GOOGLE_OUI, LOGGER_RESET_LOGGING);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to create reset request; result = %d", result);
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("failed to request reset; result = %d", result);
-            return result;
-        }
-
-        ALOGD("Success to clear loghandler");
-        return WIFI_SUCCESS;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        char *buffer = NULL;
-        int buffer_size = 0;
-
-        // ALOGD("In SetLogHandler::handleEvent");
-        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = event.get_vendor_data_len();
-        int event_id = event.get_vendor_subcmd();
-        // ALOGI("Got Logger event: %d", event_id);
-
-        if (vendor_data == NULL || len == 0) {
-            ALOGE("No Debug data found");
-            return NL_SKIP;
-        }
-
-        if(event_id == GOOGLE_DEBUG_RING_EVENT) {
-            wifi_ring_buffer_status status;
-            memset(&status, 0, sizeof(status));
-
-            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
-                if (it.get_type() == LOGGER_ATTRIBUTE_RING_STATUS) {
-                    memcpy(&status, it.get_data(), sizeof(status));
-                } else if (it.get_type() == LOGGER_ATTRIBUTE_RING_DATA) {
-                    buffer_size = it.get_len();
-                    buffer = (char *)it.get_data();
-                } else {
-                    ALOGW("Ignoring invalid attribute type = %d, size = %d",
-                            it.get_type(), it.get_len());
-                }
-            }
-
-            // ALOGI("Retrieved Debug data");
-            if (mHandler.on_ring_buffer_data) {
-                (*mHandler.on_ring_buffer_data)((char *)status.name, buffer, buffer_size,
-                        &status);
-            }
-        } else {
-            ALOGE("Unknown Event");
-            return NL_SKIP;
-        }
-        return NL_OK;
-    }
-};
-
-wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface,
-        wifi_ring_buffer_data_handler handler)
-{
-    wifi_handle handle = getWifiHandle(iface);
-    ALOGV("Loghandler start, handle = %p", handle);
-
-    SetLogHandler *cmd = new SetLogHandler(iface, id, handler);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = wifi_register_cmd(handle, id, cmd);
-    if (result != WIFI_SUCCESS) {
-        cmd->releaseRef();
-        return result;
-    }
-    result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-        cmd->releaseRef();
-        return result;
-    }
-    return result;
-}
-
-wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface)
-{
-    wifi_handle handle = getWifiHandle(iface);
-    ALOGV("Loghandler reset, wifi_request_id = %d, handle = %p", id, handle);
-
-    if (id == -1) {
-        wifi_ring_buffer_data_handler handler;
-        memset(&handler, 0, sizeof(handler));
-
-        SetLogHandler *cmd = new SetLogHandler(iface, id, handler);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        cmd->cancel();
-        cmd->releaseRef();
-        return WIFI_SUCCESS;
-    }
-
-    return wifi_cancel_cmd(id, iface);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-class SetAlertHandler : public WifiCommand
-{
-    wifi_alert_handler mHandler;
-    int mBuffSize;
-    char *mBuff;
-    int mErrCode;
-
-public:
-    SetAlertHandler(wifi_interface_handle iface, int id, wifi_alert_handler handler)
-        : WifiCommand("SetAlertHandler", iface, id), mHandler(handler), mBuffSize(0), mBuff(NULL),
-            mErrCode(0)
-    { }
-
-    int start() {
-        ALOGV("Start Alerting");
-        registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_MEM_DUMP_EVENT);
-        return WIFI_SUCCESS;
-    }
-
-    virtual int cancel() {
-        ALOGV("Clear alerthandler");
-
-        /* unregister alert handler */
-        unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_MEM_DUMP_EVENT);
-        wifi_unregister_cmd(wifiHandle(), id());
-        ALOGD("Success to clear alerthandler");
-        return WIFI_SUCCESS;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        ALOGD("In SetAlertHandler::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = reply.get_vendor_data_len();
-
-        ALOGD("len = %d", len);
-        if (vendor_data == NULL || len == 0) {
-            ALOGE("no vendor data in memory dump response; ignoring it");
-            return NL_SKIP;
-        }
-
-        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
-            if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_DATA) {
-                ALOGI("Initiating alert callback");
-                if (mHandler.on_alert) {
-                    (*mHandler.on_alert)(id(), mBuff, mBuffSize, mErrCode);
-                }
-                if (mBuff) {
-                    free(mBuff);
-                    mBuff = NULL;
-                }
-            }
-        }
-        return NL_OK;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        wifi_ring_buffer_id ring_id;
-        char *buffer = NULL;
-        int buffer_size = 0;
-
-
-        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = event.get_vendor_data_len();
-        int event_id = event.get_vendor_subcmd();
-        ALOGI("Got event: %d", event_id);
-
-        if (vendor_data == NULL || len == 0) {
-            ALOGE("No Debug data found");
-            return NL_SKIP;
-        }
-
-        if (event_id == GOOGLE_DEBUG_MEM_DUMP_EVENT) {
-            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
-                if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_LEN) {
-                    mBuffSize = it.get_u32();
-                } else if (it.get_type() == LOGGER_ATTRIBUTE_RING_DATA) {
-                    buffer_size = it.get_len();
-                    buffer = (char *)it.get_data();
-            /*
-                } else if (it.get_type() == LOGGER_ATTRIBUTE_FW_ERR_CODE) {
-                    mErrCode = it.get_u32();
-            */
-                } else {
-                    ALOGW("Ignoring invalid attribute type = %d, size = %d",
-                            it.get_type(), it.get_len());
-                }
-            }
-            if (mBuffSize) {
-                ALOGD("dump size: %d meta data size: %d", mBuffSize, buffer_size);
-                if (mBuff) free(mBuff);
-                mBuff = (char *)malloc(mBuffSize + buffer_size);
-                if (!mBuff) {
-                    ALOGE("Buffer allocation failed");
-                    return NL_SKIP;
-                }
-                memcpy(mBuff, buffer, buffer_size);
-
-                WifiRequest request(familyId(), ifaceId());
-                int result = request.create(GOOGLE_OUI, LOGGER_GET_MEM_DUMP);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to create get memory dump request; result = %d", result);
-                    free(mBuff);
-                    return NL_SKIP;
-                }
-                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-                result = request.put_u32(LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to put get memory dump request; result = %d", result);
-                    return result;
-                }
-
-                result = request.put_u64(LOGGER_ATTRIBUTE_FW_DUMP_DATA,
-                         (uint64_t)(mBuff+buffer_size));
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to put get memory dump request; result = %d", result);
-                    return result;
-                }
-
-                request.attr_end(data);
-                mBuffSize += buffer_size;
-
-                result = requestResponse(request);
-
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to register get momory dump response; result = %d", result);
-                }
-            } else {
-                ALOGE("dump event missing dump length attribute");
-                return NL_SKIP;
-            }
-        }
-        return NL_OK;
-    }
-};
-
-wifi_error wifi_set_alert_handler(wifi_request_id id, wifi_interface_handle iface,
-        wifi_alert_handler handler)
-{
-    wifi_handle handle = getWifiHandle(iface);
-    ALOGV("Alerthandler start, handle = %p", handle);
-
-    SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = wifi_register_cmd(handle, id, cmd);
-    if (result != WIFI_SUCCESS) {
-        cmd->releaseRef();
-        return result;
-    }
-    result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-        cmd->releaseRef();
-        return result;
-    }
-    return result;
-}
-
-wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle iface)
-{
-    wifi_handle handle = getWifiHandle(iface);
-    ALOGV("Alerthandler reset, wifi_request_id = %d, handle = %p", id, handle);
-
-    if (id == -1) {
-        wifi_alert_handler handler;
-        memset(&handler, 0, sizeof(handler));
-
-        SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        cmd->cancel();
-        cmd->releaseRef();
-        return WIFI_SUCCESS;
-    }
-
-    return wifi_cancel_cmd(id, iface);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-class MemoryDumpCommand: public WifiCommand
-{
-    wifi_firmware_memory_dump_handler mHandler;
-    int mBuffSize;
-    char *mBuff;
-
-public:
-    MemoryDumpCommand(wifi_interface_handle iface, wifi_firmware_memory_dump_handler handler)
-        : WifiCommand("MemoryDumpCommand", iface, 0), mHandler(handler), mBuffSize(0), mBuff(NULL)
-    { }
-
-    int start() {
-        ALOGD("Start memory dump command");
-        WifiRequest request(familyId(), ifaceId());
-
-        int result = request.create(GOOGLE_OUI, LOGGER_TRIGGER_MEM_DUMP);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to create trigger fw memory dump request; result = %d", result);
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to register trigger memory dump response; result = %d", result);
-        }
-        return result;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        ALOGD("In MemoryDumpCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = reply.get_vendor_data_len();
-
-        ALOGD("len = %d", len);
-        if (vendor_data == NULL || len == 0) {
-            ALOGE("no vendor data in memory dump response; ignoring it");
-            return NL_SKIP;
-        }
-
-        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
-            if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_LEN) {
-                mBuffSize = it.get_u32();
-
-                if (mBuff)
-                    free(mBuff);
-                mBuff = (char *)malloc(mBuffSize);
-                if (!mBuff) {
-                    ALOGE("Buffer allocation failed");
-                    return NL_SKIP;
-                }
-                WifiRequest request(familyId(), ifaceId());
-                int result = request.create(GOOGLE_OUI, LOGGER_GET_MEM_DUMP);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to create get memory dump request; result = %d", result);
-                    free(mBuff);
-                    return NL_SKIP;
-                }
-
-                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-                result = request.put_u32(LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to put get memory dump request; result = %d", result);
-                    return result;
-                }
-
-                result = request.put_u64(LOGGER_ATTRIBUTE_FW_DUMP_DATA, (uint64_t)mBuff);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to put get memory dump request; result = %d", result);
-                    return result;
-                }
-                request.attr_end(data);
-
-                result = requestResponse(request);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to register get momory dump response; result = %d", result);
-                }
-            } else if (it.get_type() == LOGGER_ATTRIBUTE_FW_DUMP_DATA) {
-                ALOGI("Initiating memory dump callback");
-                if (mHandler.on_firmware_memory_dump) {
-                    (*mHandler.on_firmware_memory_dump)(mBuff, mBuffSize);
-                }
-                if (mBuff) {
-                    free(mBuff);
-                    mBuff = NULL;
-                }
-            } else {
-                ALOGW("Ignoring invalid attribute type = %d, size = %d",
-                        it.get_type(), it.get_len());
-            }
-        }
-        return NL_OK;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        /* NO events! */
-        return NL_SKIP;
-    }
-};
-
-/* API to collect a firmware memory dump for a given iface */
-wifi_error wifi_get_firmware_memory_dump( wifi_interface_handle iface,
-        wifi_firmware_memory_dump_handler handler)
-{
-#if 0
-    MemoryDumpCommand *cmd = new MemoryDumpCommand(iface, handler);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = (wifi_error)cmd->start();
-    cmd->releaseRef();
-    return result;
-#endif
-       return WIFI_SUCCESS;
-}
-
-class PacketFateCommand: public WifiCommand
-{
-    void *mReportBufs;
-    size_t mNoReqFates;
-    size_t *mNoProvidedFates;
-    PktFateReqType mReqType;
-
-public:
-    PacketFateCommand(wifi_interface_handle handle)
-        : WifiCommand("PacketFateCommand", handle, 0), mReqType(PACKET_MONITOR_START)
-    { }
-
-    PacketFateCommand(wifi_interface_handle handle, wifi_tx_report *tx_report_bufs,
-            size_t n_requested_fates, size_t *n_provided_fates)
-        : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(tx_report_bufs),
-                  mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates),
-                  mReqType(TX_PACKET_FATE)
-    { }
-
-    PacketFateCommand(wifi_interface_handle handle, wifi_rx_report *rx_report_bufs,
-            size_t n_requested_fates, size_t *n_provided_fates)
-        : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(rx_report_bufs),
-                  mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates),
-                  mReqType(RX_PACKET_FATE)
-    { }
-
-    int createRequest(WifiRequest& request) {
-        if (mReqType == TX_PACKET_FATE) {
-            ALOGD("%s Get Tx packet fate request\n", __FUNCTION__);
-            return createTxPktFateRequest(request);
-        } else if (mReqType == RX_PACKET_FATE) {
-            ALOGD("%s Get Rx packet fate request\n", __FUNCTION__);
-            return createRxPktFateRequest(request);
-        } else if (mReqType == PACKET_MONITOR_START) {
-            ALOGD("%s Monitor packet fate request\n", __FUNCTION__);
-            return createMonitorPktFateRequest(request);
-        } else {
-            ALOGE("%s Unknown packet fate request\n", __FUNCTION__);
-            return WIFI_ERROR_NOT_SUPPORTED;
-        }
-        return WIFI_SUCCESS;
-    }
-
-    int createMonitorPktFateRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, LOGGER_START_PKT_FATE_MONITORING);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        request.attr_end(data);
-        return result;
-    }
-
-    int createTxPktFateRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, LOGGER_GET_TX_PKT_FATES);
-        if (result < 0) {
-            return result;
-        }
-
-        memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_tx_report)));
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs);
-        if (result < 0) {
-            return result;
-        }
-        request.attr_end(data);
-        return result;
-    }
-
-    int createRxPktFateRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, LOGGER_GET_RX_PKT_FATES);
-        if (result < 0) {
-            return result;
-        }
-
-        memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_rx_report)));
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);
-        if (result < 0) {
-            return result;
-        }
-        result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs);
-        if (result < 0) {
-            return result;
-        }
-        request.attr_end(data);
-        return result;
-    }
-
-    int start() {
-        ALOGD("Start get packet fate command\n");
-        WifiRequest request(familyId(), ifaceId());
-
-        int result = createRequest(request);
-        if (result < 0) {
-            ALOGE("Failed to create get pkt fate request; result = %d\n", result);
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to register get pkt fate response; result = %d\n", result);
-        }
-        return result;
-    }
-
-    int handleResponse(WifiEvent& reply) {
-        ALOGD("In GetPktFateCommand::handleResponse\n");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGI("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        int id = reply.get_vendor_id();
-        int subcmd = reply.get_vendor_subcmd();
-        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        int len = reply.get_vendor_data_len();
-
-        ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
-
-        if (mReqType == TX_PACKET_FATE) {
-            ALOGI("Response recieved for get TX pkt fate command\n");
-        } else if (mReqType == RX_PACKET_FATE) {
-            ALOGI("Response recieved for get RX pkt fate command\n");
-        } else if (mReqType == PACKET_MONITOR_START) {
-            ALOGI("Response recieved for monitor pkt fate command\n");
-            return NL_OK;
-        } else {
-            ALOGE("Response recieved for unknown pkt fate command\n");
-            return NL_SKIP;
-        }
-
-        if (vendor_data == NULL || len == 0) {
-            ALOGE("no vendor data in GetPktFateCommand response; ignoring it\n");
-            return NL_SKIP;
-        }
-
-        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
-            if (it.get_type() == LOGGER_ATTRIBUTE_PKT_FATE_NUM) {
-                *mNoProvidedFates = it.get_u32();
-                ALOGI("No: of pkt fates provided is %d\n", *mNoProvidedFates);
-            } else {
-                ALOGE("Ignoring invalid attribute type = %d, size = %d\n",
-                        it.get_type(), it.get_len());
-            }
-        }
-
-        return NL_OK;
-    }
-
-    int handleEvent(WifiEvent& event) {
-        /* NO events to handle here! */
-        return NL_SKIP;
-    }
-};
-
-wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle)
-{
-#if 0
-    PacketFateCommand *cmd = new PacketFateCommand(handle);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = (wifi_error)cmd->start();
-    cmd->releaseRef();
-    return result;
-#endif
-       return WIFI_SUCCESS;
-}
-
-wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle,
-        wifi_tx_report *tx_report_bufs, size_t n_requested_fates,
-        size_t *n_provided_fates)
-{
-#if 0
-    PacketFateCommand *cmd = new PacketFateCommand(handle, tx_report_bufs,
-                n_requested_fates, n_provided_fates);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = (wifi_error)cmd->start();
-    cmd->releaseRef();
-    return result;
-#endif
-       return WIFI_SUCCESS;
-}
-
-wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle,
-        wifi_rx_report *rx_report_bufs, size_t n_requested_fates,
-        size_t *n_provided_fates)
-{
-#if 0
-    PacketFateCommand *cmd = new PacketFateCommand(handle, rx_report_bufs,
-                n_requested_fates, n_provided_fates);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    wifi_error result = (wifi_error)cmd->start();
-    cmd->releaseRef();
-    return result;
-#endif
-       return WIFI_SUCCESS;
-}
diff --git a/wlan/wifi_hal/wifi_offload.cpp b/wlan/wifi_hal/wifi_offload.cpp
deleted file mode 100644 (file)
index 397b792..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/rtnetlink.h>
-#include <netpacket/packet.h>
-#include <linux/filter.h>
-#include <linux/errqueue.h>
-
-#include <linux/pkt_sched.h>
-#include <netlink/object-api.h>
-#include <netlink/netlink.h>
-#include <netlink/socket.h>
-#include <netlink-private/object-api.h>
-#include <netlink-private/types.h>
-
-
-#include "nl80211_copy.h"
-#include "sync.h"
-
-#define LOG_TAG  "WifiHAL"
-
-#include <log/log.h>
-
-#include "wifi_hal.h"
-#include "common.h"
-#include "cpp_bindings.h"
-
-typedef enum {
-    WIFI_OFFLOAD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
-    WIFI_OFFLOAD_STOP_MKEEP_ALIVE,
-} WIFI_OFFLOAD_SUB_COMMAND;
-
-typedef enum {
-    MKEEP_ALIVE_ATTRIBUTE_ID,
-    MKEEP_ALIVE_ATTRIBUTE_IP_PKT,
-    MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN,
-    MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR,
-    MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR,
-    MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
-} WIFI_MKEEP_ALIVE_ATTRIBUTE;
-
-typedef enum {
-    START_MKEEP_ALIVE,
-    STOP_MKEEP_ALIVE,
-} GetCmdType;
-
-///////////////////////////////////////////////////////////////////////////////
-class MKeepAliveCommand : public WifiCommand
-{
-    u8 mIndex;
-    u8 *mIpPkt;
-    u16 mIpPktLen;
-    u8 *mSrcMacAddr;
-    u8 *mDstMacAddr;
-    u32 mPeriodMsec;
-    GetCmdType mType;
-
-public:
-
-    // constructor for start sending
-    MKeepAliveCommand(wifi_interface_handle iface, u8 index, u8 *ip_packet, u16 ip_packet_len,
-            u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec, GetCmdType cmdType)
-        : WifiCommand("MKeepAliveCommand", iface, 0), mIndex(index), mIpPkt(ip_packet),
-        mIpPktLen(ip_packet_len), mSrcMacAddr(src_mac_addr), mDstMacAddr(dst_mac_addr),
-        mPeriodMsec(period_msec), mType(cmdType)
-    { }
-
-    // constructor for stop sending
-    MKeepAliveCommand(wifi_interface_handle iface, u8 index, GetCmdType cmdType)
-        : WifiCommand("MKeepAliveCommand", iface, 0), mIndex(index), mType(cmdType)
-    { }
-
-    int createRequest(WifiRequest &request) {
-        int result;
-
-        switch (mType) {
-            case START_MKEEP_ALIVE:
-            {
-                result = request.create(GOOGLE_OUI, WIFI_OFFLOAD_START_MKEEP_ALIVE);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to create start keep alive request; result = %d", result);
-                    return result;
-                }
-
-                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-
-                result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
-                if (result < 0) {
-                    ALOGE("Failed to put id request; result = %d", result);
-                    return result;
-                }
-
-                result = request.put_u16(MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, mIpPktLen);
-                if (result < 0) {
-                    ALOGE("Failed to put ip pkt len request; result = %d", result);
-                    return result;
-                }
-
-                result = request.put(MKEEP_ALIVE_ATTRIBUTE_IP_PKT, (u8*)mIpPkt, mIpPktLen);
-                if (result < 0) {
-                    ALOGE("Failed to put ip pkt request; result = %d", result);
-                    return result;
-                }
-
-                result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, mSrcMacAddr);
-                if (result < 0) {
-                    ALOGE("Failed to put src mac address request; result = %d", result);
-                    return result;
-                }
-
-                result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, mDstMacAddr);
-                if (result < 0) {
-                    ALOGE("Failed to put dst mac address request; result = %d", result);
-                    return result;
-                }
-
-                result = request.put_u32(MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, mPeriodMsec);
-                if (result < 0) {
-                    ALOGE("Failed to put period request; result = %d", result);
-                    return result;
-                }
-
-                request.attr_end(data);
-                break;
-            }
-
-            case STOP_MKEEP_ALIVE:
-            {
-                result = request.create(GOOGLE_OUI, WIFI_OFFLOAD_STOP_MKEEP_ALIVE);
-                if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to create stop keep alive request; result = %d", result);
-                    return result;
-                }
-
-                nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-
-                result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
-                if (result < 0) {
-                    ALOGE("Failed to put id request; result = %d", result);
-                    return result;
-                }
-
-                request.attr_end(data);
-                break;
-            }
-
-            default:
-                ALOGE("Unknown wifi keep alive command");
-                result = WIFI_ERROR_UNKNOWN;
-        }
-        return result;
-    }
-
-    int start() {
-        ALOGD("Start mkeep_alive command");
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to create keep alive request; result = %d", result);
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to register keep alive response; result = %d", result);
-        }
-        return result;
-    }
-
-    virtual int handleResponse(WifiEvent& reply) {
-        ALOGD("In MKeepAliveCommand::handleResponse");
-
-        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
-            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
-            return NL_SKIP;
-        }
-
-        switch (mType) {
-            case START_MKEEP_ALIVE:
-            case STOP_MKEEP_ALIVE:
-                break;
-
-            default:
-                ALOGW("Unknown mkeep_alive command");
-        }
-        return NL_OK;
-    }
-
-    virtual int handleEvent(WifiEvent& event) {
-        /* NO events! */
-        return NL_SKIP;
-    }
-};
-
-
-/* API to send specified mkeep_alive packet periodically. */
-wifi_error wifi_start_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface,
-        u8 *ip_packet, u16 ip_packet_len, u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec)
-{
-    if ((index > 0 && index <= N_AVAIL_ID) && (ip_packet != NULL) && (src_mac_addr != NULL)
-            && (dst_mac_addr != NULL) && (period_msec > 0)
-            && (ip_packet_len <= MKEEP_ALIVE_IP_PKT_MAX)) {
-        MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, ip_packet, ip_packet_len,
-                src_mac_addr, dst_mac_addr, period_msec, START_MKEEP_ALIVE);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        wifi_error result = (wifi_error)cmd->start();
-        cmd->releaseRef();
-        return result;
-    } else {
-        ALOGE("Invalid mkeep_alive parameters");
-        return  WIFI_ERROR_INVALID_ARGS;
-    }
-}
-
-/* API to stop sending mkeep_alive packet. */
-wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface)
-{
-    if (index > 0 && index <= N_AVAIL_ID) {
-        MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, STOP_MKEEP_ALIVE);
-        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        wifi_error result = (wifi_error)cmd->start();
-        cmd->releaseRef();
-        return result;
-    } else {
-        ALOGE("Invalid mkeep_alive parameters");
-        return  WIFI_ERROR_INVALID_ARGS;
-    }
-}
diff --git a/wlan/wpa_supplicant_8_lib/Android.mk b/wlan/wpa_supplicant_8_lib/Android.mk
new file mode 100644 (file)
index 0000000..09d862c
--- /dev/null
@@ -0,0 +1,71 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+ifeq ($(WPA_SUPPLICANT_VERSION),VER_0_8_X)
+
+ifneq ($(BOARD_WPA_SUPPLICANT_DRIVER),)
+  CONFIG_DRIVER_$(BOARD_WPA_SUPPLICANT_DRIVER) := y
+endif
+
+WPA_SUPPL_DIR = external/wpa_supplicant_8
+WPA_SRC_FILE :=
+
+include $(WPA_SUPPL_DIR)/wpa_supplicant/android.config
+
+WPA_SUPPL_DIR_INCLUDE = $(WPA_SUPPL_DIR)/src \
+       $(WPA_SUPPL_DIR)/src/common \
+       $(WPA_SUPPL_DIR)/src/drivers \
+       $(WPA_SUPPL_DIR)/src/l2_packet \
+       $(WPA_SUPPL_DIR)/src/utils \
+       $(WPA_SUPPL_DIR)/src/wps \
+       $(WPA_SUPPL_DIR)/wpa_supplicant
+
+ifdef CONFIG_DRIVER_NL80211
+WPA_SUPPL_DIR_INCLUDE += external/libnl/include
+WPA_SRC_FILE += driver_cmd_nl80211.c
+endif
+
+ifdef CONFIG_DRIVER_WEXT
+WPA_SRC_FILE += driver_cmd_wext.c
+endif
+
+ifeq ($(TARGET_ARCH),arm)
+# To force sizeof(enum) = 4
+L_CFLAGS += -mabi=aapcs-linux
+endif
+
+ifdef CONFIG_ANDROID_LOG
+L_CFLAGS += -DCONFIG_ANDROID_LOG
+endif
+
+ifdef CONFIG_P2P
+L_CFLAGS += -DCONFIG_P2P
+endif
+########################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := lib_driver_cmd_rtl
+LOCAL_SHARED_LIBRARIES := libc libcutils
+LOCAL_CFLAGS := $(L_CFLAGS)
+LOCAL_SRC_FILES := $(WPA_SRC_FILE)
+LOCAL_C_INCLUDES := $(WPA_SUPPL_DIR_INCLUDE)
+LOCAL_VENDOR_MODULE := true
+include $(BUILD_STATIC_LIBRARY)
+
+########################
+
+endif
diff --git a/wlan/wpa_supplicant_8_lib/MODULE_LICENSE_BSD b/wlan/wpa_supplicant_8_lib/MODULE_LICENSE_BSD
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/wlan/wpa_supplicant_8_lib/NOTICE b/wlan/wpa_supplicant_8_lib/NOTICE
new file mode 100644 (file)
index 0000000..f9d25ea
--- /dev/null
@@ -0,0 +1,43 @@
+
+Copyright (c) 2005-2010, The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the 
+   distribution.
+ * Neither the name of The Android Open Source Project nor the names
+   of its contributors may be used to endorse or promote products
+   derived from this software without specific prior written
+   permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+ * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2004, Instant802 Networks, Inc.
+ * Copyright (c) 2005-2006, Devicescape Software, Inc.
+ * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright (c) 2009-2010, Atheros Communications
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
diff --git a/wlan/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/wlan/wpa_supplicant_8_lib/driver_cmd_nl80211.c
new file mode 100644 (file)
index 0000000..c0fa3bc
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Driver interaction with extended Linux CFG8021
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ */
+
+#include "includes.h"
+#include <sys/types.h>
+#include <fcntl.h>
+#include <net/if.h>
+
+#include "common.h"
+#include "linux_ioctl.h"
+#include "driver_nl80211.h"
+#include "rtw_version.h"
+#ifdef PURE_LINUX
+#ifndef SIOCDEVPRIVATE
+#define SIOCDEVPRIVATE  0x89F0  /* to 89FF */
+#endif
+#ifndef __unused
+#if __GNUC_PREREQ(2, 95) || defined(__INTEL_COMPILER)
+#define __unused __attribute__((__unused__))
+#else
+#define __unused
+#endif
+#endif
+#endif /* PURE_LINUX */
+#include "wpa_supplicant_i.h"
+#include "config.h"
+#ifdef ANDROID
+#include "android_drv.h"
+#endif
+
+typedef struct android_wifi_priv_cmd {
+       char *bufaddr;
+       int used_len;
+       int total_len;
+} android_wifi_priv_cmd;
+
+static int drv_errors = 0;
+
+static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
+{
+       drv_errors++;
+       if (drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
+               drv_errors = 0;
+               wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
+       }
+}
+
+static void wpa_driver_notify_country_change(void *ctx, char *cmd)
+{
+       if ((os_strncasecmp(cmd, "COUNTRY", 7) == 0) ||
+           (os_strncasecmp(cmd, "SETBAND", 7) == 0)) {
+               union wpa_event_data event;
+
+               os_memset(&event, 0, sizeof(event));
+               event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
+               if (os_strncasecmp(cmd, "COUNTRY", 7) == 0) {
+                       event.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
+                       if (os_strlen(cmd) > 9) {
+                               event.channel_list_changed.alpha2[0] = cmd[8];
+                               event.channel_list_changed.alpha2[1] = cmd[9];
+                       }
+               } else {
+                       event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
+               }
+               wpa_supplicant_event(ctx, EVENT_CHANNEL_LIST_CHANGED, &event);
+       }
+}
+
+int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
+                                 size_t buf_len )
+{
+       struct i802_bss *bss = priv;
+       struct wpa_driver_nl80211_data *drv = bss->drv;
+       struct ifreq ifr;
+       android_wifi_priv_cmd priv_cmd;
+       int ret = 0;
+
+       if (bss->ifindex <= 0 && bss->wdev_id > 0) {
+               /* DRIVER CMD received on the DEDICATED P2P Interface which doesn't
+                * have an NETDEVICE associated with it. So we have to re-route the
+                * command to the parent NETDEVICE
+                */
+               struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
+
+               wpa_printf(MSG_DEBUG, "Re-routing DRIVER cmd to parent iface");
+               if (wpa_s && wpa_s->parent) {
+                       /* Update the nl80211 pointers corresponding to parent iface */
+                       bss = wpa_s->parent->drv_priv;
+                       drv = bss->drv;
+                       wpa_printf(MSG_DEBUG, "Re-routing command to iface: %s"
+                                             " cmd (%s)", bss->ifname, cmd);
+               }
+       }
+
+       if (os_strcasecmp(cmd, "STOP") == 0) {
+               linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
+               wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
+       } else if (os_strcasecmp(cmd, "START") == 0) {
+               linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
+               wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
+       } else if (os_strcasecmp(cmd, "lib_version") == 0) {
+               wpa_msg(drv->ctx, MSG_INFO, RTW_VERSION);
+       } else if (os_strcasecmp(cmd, "P2P_DISABLE") == 0) {
+               os_memcpy(buf, "P2P_DISABLE", 12);
+               wpa_printf(MSG_DEBUG, "P2P_DISABLE");
+       } else if (os_strcasecmp(cmd, "MACADDR") == 0) {
+               u8 macaddr[ETH_ALEN] = {};
+
+               ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
+               if (!ret)
+                       ret = os_snprintf(buf, buf_len,
+                                         "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
+       } else { /* Use private command */
+               os_memcpy(buf, cmd, strlen(cmd) + 1);
+               memset(&ifr, 0, sizeof(ifr));
+               memset(&priv_cmd, 0, sizeof(priv_cmd));
+               os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
+               priv_cmd.bufaddr = buf;
+               priv_cmd.used_len = buf_len;
+               priv_cmd.total_len = buf_len;
+               ifr.ifr_data = (void *)&priv_cmd;
+
+               if ((ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
+                       wpa_printf(MSG_ERROR, "%s: failed to issue private command: %s", __func__, cmd);
+                       wpa_driver_send_hang_msg(drv);
+               } else {
+                       drv_errors = 0;
+                       ret = 0;
+                       if ((os_strcasecmp(cmd, "LINKSPEED") == 0) ||
+                           (os_strcasecmp(cmd, "RSSI") == 0) ||
+                           (os_strcasecmp(cmd, "GETBAND") == 0) ||
+                           (os_strncasecmp(cmd, "WLS_BATCHING", 12) == 0))
+                               ret = strlen(buf);
+                       wpa_driver_notify_country_change(drv->ctx, cmd);
+                       wpa_printf(MSG_DEBUG, "%s %s len = %d, %zu", __func__, buf, ret, strlen(buf));
+               }
+       }
+       return ret;
+}
+
+int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration)
+{
+       char buf[MAX_DRV_CMD_SIZE];
+
+       memset(buf, 0, sizeof(buf));
+       wpa_printf(MSG_DEBUG, "%s: Entry", __func__);
+       snprintf(buf, sizeof(buf), "P2P_SET_NOA %d %d %d", count, start, duration);
+       return wpa_driver_nl80211_driver_cmd(priv, buf, buf, strlen(buf)+1);
+}
+
+int wpa_driver_get_p2p_noa(void *priv __unused, u8 *buf __unused, size_t len __unused)
+{
+       /* Return 0 till we handle p2p_presence request completely in the driver */
+       return 0;
+}
+
+int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow)
+{
+       char buf[MAX_DRV_CMD_SIZE];
+
+       memset(buf, 0, sizeof(buf));
+       wpa_printf(MSG_DEBUG, "%s: Entry", __func__);
+       snprintf(buf, sizeof(buf), "P2P_SET_PS %d %d %d", legacy_ps, opp_ps, ctwindow);
+       return wpa_driver_nl80211_driver_cmd(priv, buf, buf, strlen(buf) + 1);
+}
+
+int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
+                                const struct wpabuf *proberesp,
+                                const struct wpabuf *assocresp)
+{
+       char *buf;
+       const struct wpabuf *ap_wps_p2p_ie = NULL;
+
+       char *_cmd = "SET_AP_WPS_P2P_IE";
+       char *pbuf;
+       int ret = 0;
+       int i, buf_len;
+       struct cmd_desc {
+               int cmd;
+               const struct wpabuf *src;
+       } cmd_arr[] = {
+               {0x1, beacon},
+               {0x2, proberesp},
+               {0x4, assocresp},
+               {-1, NULL}
+       };
+
+       wpa_printf(MSG_DEBUG, "%s: Entry", __func__);
+       for (i = 0; cmd_arr[i].cmd != -1; i++) {
+               ap_wps_p2p_ie = cmd_arr[i].src;
+               if (ap_wps_p2p_ie) {
+                       buf_len = strlen(_cmd) + 3 + wpabuf_len(ap_wps_p2p_ie);
+                       buf = os_zalloc(buf_len);
+                       if (NULL == buf) {
+                               wpa_printf(MSG_ERROR, "%s: Out of memory",
+                                          __func__);
+                               ret = -1;
+                               break;
+                       }
+               } else {
+                       continue;
+               }
+               pbuf = buf;
+               pbuf += snprintf(pbuf, buf_len - wpabuf_len(ap_wps_p2p_ie),
+                                "%s %d",_cmd, cmd_arr[i].cmd);
+               *pbuf++ = '\0';
+               os_memcpy(pbuf, wpabuf_head(ap_wps_p2p_ie), wpabuf_len(ap_wps_p2p_ie));
+               ret = wpa_driver_nl80211_driver_cmd(priv, buf, buf, buf_len);
+               os_free(buf);
+               if (ret < 0)
+                       break;
+       }
+
+       return ret;
+}
diff --git a/wlan/wpa_supplicant_8_lib/driver_cmd_wext.c b/wlan/wpa_supplicant_8_lib/driver_cmd_wext.c
new file mode 100644 (file)
index 0000000..3734cb0
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * Driver interaction with extended Linux Wireless Extensions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ */
+
+#include "includes.h"
+#include <sys/ioctl.h>
+#include <net/if_arp.h>
+#include <net/if.h>
+
+#include "linux_wext.h"
+#include "common.h"
+#include "driver.h"
+#include "eloop.h"
+#include "priv_netlink.h"
+#include "driver_wext.h"
+#include "ieee802_11_defs.h"
+#include "wpa_common.h"
+#include "wpa_ctrl.h"
+#include "wpa_supplicant_i.h"
+#include "config.h"
+#include "linux_ioctl.h"
+#include "scan.h"
+
+#include "driver_cmd_wext.h"
+#ifdef ANDROID
+#include "android_drv.h"
+#endif /* ANDROID */
+
+#define RSSI_CMD                       "RSSI"
+#define LINKSPEED_CMD                  "LINKSPEED"
+
+/**
+ * wpa_driver_wext_set_scan_timeout - Set scan timeout to report scan completion
+ * @priv:  Pointer to private wext data from wpa_driver_wext_init()
+ *
+ * This function can be used to set registered timeout when starting a scan to
+ * generate a scan completed event if the driver does not report this.
+ */
+static void wpa_driver_wext_set_scan_timeout(void *priv)
+{
+       struct wpa_driver_wext_data *drv = priv;
+       int timeout = 10; /* In case scan A and B bands it can be long */
+
+       /* Not all drivers generate "scan completed" wireless event, so try to
+        * read results after a timeout. */
+       if (drv->scan_complete_events) {
+       /*
+        * The driver seems to deliver SIOCGIWSCAN events to notify
+        * when scan is complete, so use longer timeout to avoid race
+        * conditions with scanning and following association request.
+        */
+               timeout = 30;
+       }
+       wpa_printf(MSG_DEBUG, "Scan requested - scan timeout %d seconds",
+                  timeout);
+       eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
+       eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv,
+                              drv->ctx);
+}
+
+/**
+ * wpa_driver_wext_combo_scan - Request the driver to initiate combo scan
+ * @priv: Pointer to private wext data from wpa_driver_wext_init()
+ * @params: Scan parameters
+ * Returns: 0 on success, -1 on failure
+ */
+int wpa_driver_wext_combo_scan(void *priv, struct wpa_driver_scan_params *params)
+{
+       char buf[WEXT_CSCAN_BUF_LEN];
+       struct wpa_driver_wext_data *drv = priv;
+       struct iwreq iwr;
+       int ret, bp;
+       unsigned i;
+
+       if (!drv->driver_is_started) {
+               wpa_printf(MSG_DEBUG, "%s: Driver stopped", __func__);
+               return 0;
+       }
+
+       wpa_printf(MSG_DEBUG, "%s: Start", __func__);
+
+       /* Set list of SSIDs */
+       bp = WEXT_CSCAN_HEADER_SIZE;
+       os_memcpy(buf, WEXT_CSCAN_HEADER, bp);
+       for(i=0; i < params->num_ssids; i++) {
+               if ((bp + IW_ESSID_MAX_SIZE + 10) >= (int)sizeof(buf))
+                       break;
+               wpa_printf(MSG_DEBUG, "For Scan: %s", params->ssids[i].ssid);
+               buf[bp++] = WEXT_CSCAN_SSID_SECTION;
+               buf[bp++] = params->ssids[i].ssid_len;
+               os_memcpy(&buf[bp], params->ssids[i].ssid, params->ssids[i].ssid_len);
+               bp += params->ssids[i].ssid_len;
+       }
+
+       /* Set list of channels */
+       buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION;
+       buf[bp++] = 0;
+
+       /* Set passive dwell time (default is 250) */
+       buf[bp++] = WEXT_CSCAN_PASV_DWELL_SECTION;
+       buf[bp++] = (u8)WEXT_CSCAN_PASV_DWELL_TIME;
+       buf[bp++] = (u8)(WEXT_CSCAN_PASV_DWELL_TIME >> 8);
+
+       /* Set home dwell time (default is 40) */
+       buf[bp++] = WEXT_CSCAN_HOME_DWELL_SECTION;
+       buf[bp++] = (u8)WEXT_CSCAN_HOME_DWELL_TIME;
+       buf[bp++] = (u8)(WEXT_CSCAN_HOME_DWELL_TIME >> 8);
+
+       os_memset(&iwr, 0, sizeof(iwr));
+       os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+       iwr.u.data.pointer = buf;
+       iwr.u.data.length = bp;
+
+       if ((ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr)) < 0) {
+               if (!drv->bgscan_enabled)
+                       wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (cscan): %d", ret);
+               else
+                       ret = 0;        /* Hide error in case of bg scan */
+       }
+       return ret;
+}
+
+static int wpa_driver_wext_set_cscan_params(char *buf, size_t buf_len, char *cmd)
+{
+       char *pasv_ptr;
+       int bp, i;
+       u16 pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_DEF;
+       u8 channel;
+
+       wpa_printf(MSG_DEBUG, "%s: %s", __func__, cmd);
+
+       /* Get command parameters */
+       pasv_ptr = os_strstr(cmd, ",TIME=");
+       if (pasv_ptr) {
+               *pasv_ptr = '\0';
+               pasv_ptr += 6;
+               pasv_dwell = (u16)atoi(pasv_ptr);
+               if (pasv_dwell == 0)
+                       pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_DEF;
+       }
+       channel = (u8)atoi(cmd + 5);
+
+       bp = WEXT_CSCAN_HEADER_SIZE;
+       os_memcpy(buf, WEXT_CSCAN_HEADER, bp);
+
+       /* Set list of channels */
+       buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION;
+       buf[bp++] = channel;
+       if (channel != 0) {
+               i = (pasv_dwell - 1) / WEXT_CSCAN_PASV_DWELL_TIME_DEF;
+               for (; i > 0; i--) {
+                       if ((size_t)(bp + 12) >= buf_len)
+                               break;
+                       buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION;
+                       buf[bp++] = channel;
+               }
+       } else {
+               if (pasv_dwell > WEXT_CSCAN_PASV_DWELL_TIME_MAX)
+                       pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_MAX;
+       }
+
+       /* Set passive dwell time (default is 250) */
+       buf[bp++] = WEXT_CSCAN_PASV_DWELL_SECTION;
+       if (channel != 0) {
+               buf[bp++] = (u8)WEXT_CSCAN_PASV_DWELL_TIME_DEF;
+               buf[bp++] = (u8)(WEXT_CSCAN_PASV_DWELL_TIME_DEF >> 8);
+       } else {
+               buf[bp++] = (u8)pasv_dwell;
+               buf[bp++] = (u8)(pasv_dwell >> 8);
+       }
+
+       /* Set home dwell time (default is 40) */
+       buf[bp++] = WEXT_CSCAN_HOME_DWELL_SECTION;
+       buf[bp++] = (u8)WEXT_CSCAN_HOME_DWELL_TIME;
+       buf[bp++] = (u8)(WEXT_CSCAN_HOME_DWELL_TIME >> 8);
+
+       /* Set cscan type */
+       buf[bp++] = WEXT_CSCAN_TYPE_SECTION;
+       buf[bp++] = WEXT_CSCAN_TYPE_PASSIVE;
+       return bp;
+}
+
+static char *wpa_driver_get_country_code(int channels)
+{
+       char *country = "US"; /* WEXT_NUMBER_SCAN_CHANNELS_FCC */
+
+       if (channels == WEXT_NUMBER_SCAN_CHANNELS_ETSI)
+               country = "EU";
+       else if( channels == WEXT_NUMBER_SCAN_CHANNELS_MKK1)
+               country = "JP";
+       return country;
+}
+
+static int wpa_driver_set_backgroundscan_params(void *priv)
+{
+       struct wpa_driver_wext_data *drv = priv;
+       struct wpa_supplicant *wpa_s;
+       struct iwreq iwr;
+       int ret = 0, i = 0, bp;
+       char buf[WEXT_PNO_MAX_COMMAND_SIZE];
+       struct wpa_ssid *ssid_conf;
+
+       if (drv == NULL) {
+               wpa_printf(MSG_ERROR, "%s: drv is NULL. Exiting", __func__);
+               return -1;
+       }
+       if (drv->ctx == NULL) {
+               wpa_printf(MSG_ERROR, "%s: drv->ctx is NULL. Exiting", __func__);
+               return -1;
+       }
+       wpa_s = (struct wpa_supplicant *)(drv->ctx);
+       if (wpa_s->conf == NULL) {
+               wpa_printf(MSG_ERROR, "%s: wpa_s->conf is NULL. Exiting", __func__);
+               return -1;
+       }
+       ssid_conf = wpa_s->conf->ssid;
+
+       bp = WEXT_PNOSETUP_HEADER_SIZE;
+       os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp);
+       buf[bp++] = WEXT_PNO_TLV_PREFIX;
+       buf[bp++] = WEXT_PNO_TLV_VERSION;
+       buf[bp++] = WEXT_PNO_TLV_SUBVERSION;
+       buf[bp++] = WEXT_PNO_TLV_RESERVED;
+
+       while ((i < WEXT_PNO_AMOUNT) && (ssid_conf != NULL)) {
+               /* Check that there is enough space needed for 1 more SSID, the other sections and null termination */
+               if ((bp + WEXT_PNO_SSID_HEADER_SIZE + IW_ESSID_MAX_SIZE + WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int)sizeof(buf))
+                       break;
+               if ((!ssid_conf->disabled) && (ssid_conf->ssid_len <= IW_ESSID_MAX_SIZE)){
+                       wpa_printf(MSG_DEBUG, "For PNO Scan: %s", ssid_conf->ssid);
+                       buf[bp++] = WEXT_PNO_SSID_SECTION;
+                       buf[bp++] = ssid_conf->ssid_len;
+                       os_memcpy(&buf[bp], ssid_conf->ssid, ssid_conf->ssid_len);
+                       bp += ssid_conf->ssid_len;
+                       i++;
+               }
+               ssid_conf = ssid_conf->next;
+       }
+
+       buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION;
+       os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x", WEXT_PNO_SCAN_INTERVAL);
+       bp += WEXT_PNO_SCAN_INTERVAL_LENGTH;
+
+       buf[bp++] = WEXT_PNO_REPEAT_SECTION;
+       os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x", WEXT_PNO_REPEAT);
+       bp += WEXT_PNO_REPEAT_LENGTH;
+
+       buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION;
+       os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x", WEXT_PNO_MAX_REPEAT);
+       bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1;
+
+       os_memset(&iwr, 0, sizeof(iwr));
+       os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+       iwr.u.data.pointer = buf;
+       iwr.u.data.length = bp;
+
+       ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
+
+       if (ret < 0) {
+               wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d", ret);
+               drv->errors++;
+               if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
+                       drv->errors = 0;
+                       wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
+               }
+       } else {
+               drv->errors = 0;
+       }
+       return ret;
+
+}
+
+int wpa_driver_wext_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
+{
+       struct wpa_driver_wext_data *drv = priv;
+       struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
+       struct iwreq iwr;
+       int ret = 0, flags;
+
+       wpa_printf(MSG_DEBUG, "%s %s len = %d", __func__, cmd, buf_len);
+
+       if (!drv->driver_is_started && (os_strcasecmp(cmd, "START") != 0)) {
+               wpa_printf(MSG_ERROR,"WEXT: Driver not initialized yet");
+               return -1;
+       }
+
+       if (os_strcasecmp(cmd, "RSSI-APPROX") == 0) {
+               os_strlcpy(cmd, RSSI_CMD, MAX_DRV_CMD_SIZE);
+       } else if( os_strncasecmp(cmd, "SCAN-CHANNELS", 13) == 0 ) {
+               int no_of_chan;
+
+               no_of_chan = atoi(cmd + 13);
+               os_snprintf(cmd, MAX_DRV_CMD_SIZE, "COUNTRY %s",
+                       wpa_driver_get_country_code(no_of_chan));
+       } else if (os_strcasecmp(cmd, "STOP") == 0) {
+               linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0);
+       } else if( os_strcasecmp(cmd, "RELOAD") == 0 ) {
+               wpa_printf(MSG_DEBUG,"Reload command");
+               wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
+               return ret;
+       } else if( os_strcasecmp(cmd, "BGSCAN-START") == 0 ) {
+               ret = wpa_driver_set_backgroundscan_params(priv);
+               if (ret < 0) {
+                       return ret;
+               }
+               os_strlcpy(cmd, "PNOFORCE 1", MAX_DRV_CMD_SIZE);
+               drv->bgscan_enabled = 1;
+       } else if( os_strcasecmp(cmd, "BGSCAN-STOP") == 0 ) {
+               os_strlcpy(cmd, "PNOFORCE 0", MAX_DRV_CMD_SIZE);
+               drv->bgscan_enabled = 0;
+       }
+
+       os_memset(&iwr, 0, sizeof(iwr));
+       os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+       os_memcpy(buf, cmd, strlen(cmd) + 1);
+       iwr.u.data.pointer = buf;
+       iwr.u.data.length = buf_len;
+
+       if( os_strncasecmp(cmd, "CSCAN", 5) == 0 ) {
+               if (!wpa_s->scanning && ((wpa_s->wpa_state <= WPA_SCANNING) ||
+                                       (wpa_s->wpa_state >= WPA_COMPLETED))) {
+                       iwr.u.data.length = wpa_driver_wext_set_cscan_params(buf, buf_len, cmd);
+               } else {
+                       wpa_printf(MSG_ERROR, "Ongoing Scan action...");
+                       return ret;
+               }
+       }
+
+       ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
+
+       if (ret < 0) {
+               wpa_printf(MSG_ERROR, "%s failed (%d): %s", __func__, ret, cmd);
+               drv->errors++;
+               if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
+                       drv->errors = 0;
+                       wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
+               }
+       } else {
+               drv->errors = 0;
+               ret = 0;
+               if ((os_strcasecmp(cmd, RSSI_CMD) == 0) ||
+                   (os_strcasecmp(cmd, LINKSPEED_CMD) == 0) ||
+                   (os_strcasecmp(cmd, "MACADDR") == 0) ||
+                   (os_strcasecmp(cmd, "GETPOWER") == 0) ||
+                   (os_strcasecmp(cmd, "GETBAND") == 0)) {
+                       ret = strlen(buf);
+               } else if (os_strcasecmp(cmd, "START") == 0) {
+                       drv->driver_is_started = TRUE;
+                       linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1);
+                       /* os_sleep(0, WPA_DRIVER_WEXT_WAIT_US);
+                       wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); */
+               } else if (os_strcasecmp(cmd, "STOP") == 0) {
+                       drv->driver_is_started = FALSE;
+                       /* wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); */
+               } else if (os_strncasecmp(cmd, "CSCAN", 5) == 0) {
+                       wpa_driver_wext_set_scan_timeout(priv);
+                       wpa_supplicant_notify_scanning(wpa_s, 1);
+               }
+               wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf));
+       }
+       return ret;
+}
+
+int wpa_driver_signal_poll(void *priv, struct wpa_signal_info *si)
+{
+       char buf[MAX_DRV_CMD_SIZE];
+       struct wpa_driver_wext_data *drv = priv;
+       char *prssi;
+       int res;
+
+       os_memset(si, 0, sizeof(*si));
+       res = wpa_driver_wext_driver_cmd(priv, RSSI_CMD, buf, sizeof(buf));
+       /* Answer: SSID rssi -Val */
+       if (res < 0)
+               return res;
+       prssi = strcasestr(buf, RSSI_CMD);
+       if (!prssi)
+               return -1;
+       si->current_signal = atoi(prssi + strlen(RSSI_CMD) + 1);
+
+       res = wpa_driver_wext_driver_cmd(priv, LINKSPEED_CMD, buf, sizeof(buf));
+       /* Answer: LinkSpeed Val */
+       if (res < 0)
+               return res;
+       si->current_txrate = atoi(buf + strlen(LINKSPEED_CMD) + 1) * 1000;
+
+       return 0;
+}
diff --git a/wlan/wpa_supplicant_8_lib/driver_cmd_wext.h b/wlan/wpa_supplicant_8_lib/driver_cmd_wext.h
new file mode 100644 (file)
index 0000000..56d54fc
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Driver interaction with extended Linux Wireless Extensions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ */
+#ifndef DRIVER_CMD_WEXT_H
+#define DRIVER_CMD_WEXT_H
+
+#define WEXT_NUMBER_SCAN_CHANNELS_FCC  11
+#define WEXT_NUMBER_SCAN_CHANNELS_ETSI 13
+#define WEXT_NUMBER_SCAN_CHANNELS_MKK1 14
+
+#define WPA_DRIVER_WEXT_WAIT_US                400000
+#define WEXT_CSCAN_BUF_LEN             360
+#define WEXT_CSCAN_HEADER              "CSCAN S\x01\x00\x00S\x00"
+#define WEXT_CSCAN_HEADER_SIZE         12
+#define WEXT_CSCAN_SSID_SECTION                'S'
+#define WEXT_CSCAN_CHANNEL_SECTION     'C'
+#define WEXT_CSCAN_NPROBE_SECTION      'N'
+#define WEXT_CSCAN_ACTV_DWELL_SECTION  'A'
+#define WEXT_CSCAN_PASV_DWELL_SECTION  'P'
+#define WEXT_CSCAN_HOME_DWELL_SECTION  'H'
+#define WEXT_CSCAN_TYPE_SECTION                'T'
+#define WEXT_CSCAN_TYPE_DEFAULT                0
+#define WEXT_CSCAN_TYPE_PASSIVE                1
+#define WEXT_CSCAN_PASV_DWELL_TIME     130
+#define WEXT_CSCAN_PASV_DWELL_TIME_DEF 250
+#define WEXT_CSCAN_PASV_DWELL_TIME_MAX 3000
+#define WEXT_CSCAN_HOME_DWELL_TIME     130
+
+#endif /* DRIVER_CMD_WEXT_H */
diff --git a/wlan/wpa_supplicant_8_lib/driver_nl80211.h b/wlan/wpa_supplicant_8_lib/driver_nl80211.h
new file mode 100644 (file)
index 0000000..081eee3
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Driver interaction with Linux nl80211/cfg80211
+ * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2004, Instant802 Networks, Inc.
+ * Copyright (c) 2005-2006, Devicescape Software, Inc.
+ * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright (c) 2009-2010, Atheros Communications
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef _DRIVER_NL80211_H_
+#define _DRIVER_NL80211_H_
+
+#include "includes.h"
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#ifdef CONFIG_LIBNL3_ROUTE
+#include <netlink/route/neighbour.h>
+#endif /* CONFIG_LIBNL3_ROUTE */
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+#include "nl80211_copy.h"
+
+#include "common.h"
+#include "eloop.h"
+#include "utils/list.h"
+#include "common/qca-vendor.h"
+#include "common/qca-vendor-attr.h"
+#include "common/ieee802_11_defs.h"
+#include "common/ieee802_11_common.h"
+#include "l2_packet/l2_packet.h"
+#include "netlink.h"
+#include "linux_ioctl.h"
+#include "radiotap.h"
+#include "radiotap_iter.h"
+#include "rfkill.h"
+#include "driver.h"
+
+#ifdef CONFIG_LIBNL20
+/* libnl 2.0 compatibility code */
+#define nl_handle nl_sock
+#define nl80211_handle_alloc nl_socket_alloc_cb
+#define nl80211_handle_destroy nl_socket_free
+#endif /* CONFIG_LIBNL20 */
+
+#ifndef IFF_LOWER_UP
+#define IFF_LOWER_UP   0x10000         /* driver signals L1 up         */
+#endif
+#ifndef IFF_DORMANT
+#define IFF_DORMANT    0x20000         /* driver signals dormant       */
+#endif
+
+#ifndef IF_OPER_DORMANT
+#define IF_OPER_DORMANT 5
+#endif
+#ifndef IF_OPER_UP
+#define IF_OPER_UP 6
+#endif
+
+struct nl80211_global {
+       void *ctx;
+       struct dl_list interfaces;
+       int if_add_ifindex;
+       u64 if_add_wdevid;
+       int if_add_wdevid_set;
+       struct netlink_data *netlink;
+       struct nl_cb *nl_cb;
+       struct nl_handle *nl;
+       int nl80211_id;
+       int ioctl_sock; /* socket for ioctl() use */
+
+       struct nl_handle *nl_event;
+};
+
+struct nl80211_wiphy_data {
+       struct dl_list list;
+       struct dl_list bsss;
+       struct dl_list drvs;
+
+       struct nl_handle *nl_beacons;
+       struct nl_cb *nl_cb;
+
+       int wiphy_idx;
+};
+
+struct i802_bss {
+       struct wpa_driver_nl80211_data *drv;
+       struct i802_bss *next;
+       int ifindex;
+       int br_ifindex;
+       u64 wdev_id;
+       char ifname[IFNAMSIZ + 1];
+       char brname[IFNAMSIZ];
+       unsigned int beacon_set:1;
+       unsigned int added_if_into_bridge:1;
+       unsigned int added_bridge:1;
+       unsigned int in_deinit:1;
+       unsigned int wdev_id_set:1;
+       unsigned int added_if:1;
+       unsigned int static_ap:1;
+
+       u8 addr[ETH_ALEN];
+
+       int freq;
+       int bandwidth;
+       int if_dynamic;
+
+       void *ctx;
+       struct nl_handle *nl_preq, *nl_mgmt;
+       struct nl_cb *nl_cb;
+
+       struct nl80211_wiphy_data *wiphy_data;
+       struct dl_list wiphy_list;
+};
+
+struct wpa_driver_nl80211_data {
+       struct nl80211_global *global;
+       struct dl_list list;
+       struct dl_list wiphy_list;
+       char phyname[32];
+       unsigned int wiphy_idx;
+       u8 perm_addr[ETH_ALEN];
+       void *ctx;
+       int ifindex;
+       int if_removed;
+       int if_disabled;
+       int ignore_if_down_event;
+       struct rfkill_data *rfkill;
+       struct wpa_driver_capa capa;
+       u8 *extended_capa, *extended_capa_mask;
+       unsigned int extended_capa_len;
+       int has_capability;
+
+       int operstate;
+
+       int scan_complete_events;
+       enum scan_states {
+               NO_SCAN, SCAN_REQUESTED, SCAN_STARTED, SCAN_COMPLETED,
+               SCAN_ABORTED, SCHED_SCAN_STARTED, SCHED_SCAN_STOPPED,
+               SCHED_SCAN_RESULTS
+       } scan_state;
+
+       //struct nl_cb *nl_cb;
+
+       u8 auth_bssid[ETH_ALEN];
+       u8 auth_attempt_bssid[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+       u8 prev_bssid[ETH_ALEN];
+       int associated;
+       u8 ssid[32];
+       size_t ssid_len;
+       enum nl80211_iftype nlmode;
+       enum nl80211_iftype ap_scan_as_station;
+       unsigned int assoc_freq;
+
+       int monitor_sock;
+       int monitor_ifidx;
+       int monitor_refcount;
+
+       unsigned int disabled_11b_rates:1;
+       unsigned int pending_remain_on_chan:1;
+       unsigned int in_interface_list:1;
+       unsigned int device_ap_sme:1;
+       unsigned int poll_command_supported:1;
+       unsigned int data_tx_status:1;
+       unsigned int scan_for_auth:1;
+       unsigned int retry_auth:1;
+       unsigned int use_monitor:1;
+       unsigned int ignore_next_local_disconnect:1;
+       unsigned int ignore_next_local_deauth:1;
+       //unsigned int allow_p2p_device:1;
+       unsigned int hostapd:1;
+       unsigned int start_mode_ap:1;
+       unsigned int start_iface_up:1;
+       unsigned int test_use_roc_tx:1;
+       unsigned int ignore_deauth_event:1;
+       unsigned int vendor_cmd_test_avail:1;
+       unsigned int roaming_vendor_cmd_avail:1;
+       unsigned int dfs_vendor_cmd_avail:1;
+       unsigned int have_low_prio_scan:1;
+       unsigned int force_connect_cmd:1;
+       unsigned int addr_changed:1;
+       unsigned int get_features_vendor_cmd_avail:1;
+       unsigned int set_rekey_offload:1;
+       unsigned int p2p_go_ctwindow_supported:1;
+       unsigned int setband_vendor_cmd_avail:1;
+       unsigned int get_pref_freq_list:1;
+       unsigned int set_prob_oper_freq:1;
+       unsigned int scan_vendor_cmd_avail:1;
+       unsigned int connect_reassoc:1;
+
+       u64 vendor_scan_cookie;
+       u64 remain_on_chan_cookie;
+       u64 send_action_cookie;
+#define MAX_SEND_ACTION_COOKIES 20
+       u64 send_action_cookies[MAX_SEND_ACTION_COOKIES];
+       unsigned int num_send_action_cookies;
+
+       unsigned int last_mgmt_freq;
+
+       struct wpa_driver_scan_filter *filter_ssids;
+       size_t num_filter_ssids;
+
+       struct i802_bss *first_bss;
+
+       int eapol_tx_sock;
+
+       int eapol_sock; /* socket for EAPOL frames */
+
+       struct nl_handle *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
+
+       int default_if_indices[16];
+       /* the AP/AP_VLAN iface that is in this bridge */
+       int default_if_indices_reason[16];
+       int *if_indices;
+       int *if_indices_reason;
+       int num_if_indices;
+
+       /* From failed authentication command */
+       int auth_freq;
+       u8 auth_bssid_[ETH_ALEN];
+       u8 auth_ssid[32];
+       size_t auth_ssid_len;
+       int auth_alg;
+       u8 *auth_ie;
+       size_t auth_ie_len;
+       u8 auth_wep_key[4][16];
+       size_t auth_wep_key_len[4];
+       int auth_wep_tx_keyidx;
+       int auth_local_state_change;
+       int auth_p2p;
+
+       /*
+        * Tells whether the last scan issued from wpa_supplicant was a normal
+        * scan (NL80211_CMD_TRIGGER_SCAN) or a vendor scan
+        * (NL80211_CMD_VENDOR). 0 if no pending scan request.
+        */
+       int last_scan_cmd;
+};
+
+#endif
diff --git a/wlan/wpa_supplicant_8_lib/rtw_version.h b/wlan/wpa_supplicant_8_lib/rtw_version.h
new file mode 100644 (file)
index 0000000..48edbdc
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef RTW_VERSION_H
+       #define RTW_VERSION_H
+       #define RTW_VERSION "rtw_r26589.20180227"
+#endif /* RTW_VERSION_H */