diff --git a/Android.mk b/Android.mk
new file mode 100755
index 0000000..8051d5c
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,40 @@
+#############################################################################
+#
+# Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd
+#
+#############################################################################
+
+ifeq ($(CONFIG_SAMSUNG_SCSC_WIFIBT),true)
+
+LOCAL_PATH := $(call my-dir)
+
+# Make the HAL library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -Wno-unused-parameter
+
+LOCAL_C_INCLUDES += \
+        system/core/include/ \
+	external/libnl/include \
+        $(call include-path-for, libhardware_legacy)/hardware_legacy \
+        external/wpa_supplicant_8/src/drivers
+
+LOCAL_SRC_FILES := \
+	wifi_hal.cpp \
+	rtt.cpp \
+	common.cpp \
+	cpp_bindings.cpp \
+	gscan.cpp \
+	link_layer_stats.cpp \
+	wifi_offload.cpp \
+	roam.cpp \
+	wifi_logger.cpp \
+	wifi_nan.cpp
+
+LOCAL_MODULE := libwifi-hal-slsi
+LOCAL_VENDOR_MODULE := true
+
+include $(BUILD_STATIC_LIBRARY)
+
+endif
diff --git a/common.cpp b/common.cpp
new file mode 100755
index 0000000..e0de0bc
--- /dev/null
+++ b/common.cpp
@@ -0,0 +1,244 @@
+
+#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 "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+interface_info *getIfaceInfo(wifi_interface_handle handle)
+{
+    return (interface_info *)handle;
+}
+
+wifi_handle getWifiHandle(wifi_interface_handle handle)
+{
+    return getIfaceInfo(handle)->handle;
+}
+
+hal_info *getHalInfo(wifi_handle handle)
+{
+    return (hal_info *)handle;
+}
+
+hal_info *getHalInfo(wifi_interface_handle handle)
+{
+    return getHalInfo(getWifiHandle(handle));
+}
+
+wifi_handle getWifiHandle(hal_info *info)
+{
+    return (wifi_handle)info;
+}
+
+wifi_interface_handle getIfaceHandle(interface_info *info)
+{
+    return (wifi_interface_handle)info;
+}
+
+wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg)
+{
+    hal_info *info = (hal_info *)handle;
+
+    /* TODO: check for multiple handlers? */
+    pthread_mutex_lock(&info->cb_lock);
+
+    wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
+
+    if (info->num_event_cb < info->alloc_event_cb) {
+        info->event_cb[info->num_event_cb].nl_cmd  = cmd;
+        info->event_cb[info->num_event_cb].vendor_id  = 0;
+        info->event_cb[info->num_event_cb].vendor_subcmd  = 0;
+        info->event_cb[info->num_event_cb].cb_func = func;
+        info->event_cb[info->num_event_cb].cb_arg  = arg;
+        /*
+        ALOGI("Successfully added event handler %p:%p for command %d at %d",
+                arg, func, cmd, info->num_event_cb);*/
+        info->num_event_cb++;
+        result = WIFI_SUCCESS;
+    }
+
+    pthread_mutex_unlock(&info->cb_lock);
+    return result;
+}
+
+wifi_error wifi_register_vendor_handler(wifi_handle handle,
+        uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg)
+{
+    hal_info *info = (hal_info *)handle;
+
+//ALOGD("GSCAN register handle wifi_register_vendor_handler %p", handle);
+    /* TODO: check for multiple handlers? */
+    pthread_mutex_lock(&info->cb_lock);
+    //ALOGI("Added event handler %p", info);
+
+    wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
+
+    //    ALOGD("register_vendor_handler: handle = %p", handle);
+    if (info->num_event_cb < info->alloc_event_cb) {
+        info->event_cb[info->num_event_cb].nl_cmd  = NL80211_CMD_VENDOR;
+        info->event_cb[info->num_event_cb].vendor_id  = id;
+        info->event_cb[info->num_event_cb].vendor_subcmd  = subcmd;
+        info->event_cb[info->num_event_cb].cb_func = func;
+        info->event_cb[info->num_event_cb].cb_arg  = arg;
+        /*
+        ALOGI("Added event handler %p:%p for vendor 0x%0x and subcmd 0x%0x at %d",
+                arg, func, id, subcmd, info->num_event_cb);*/
+        info->num_event_cb++;
+        result = WIFI_SUCCESS;
+    }
+
+    pthread_mutex_unlock(&info->cb_lock);
+    return result;
+}
+
+void wifi_unregister_handler(wifi_handle handle, int cmd)
+{
+    hal_info *info = (hal_info *)handle;
+
+    if (cmd == NL80211_CMD_VENDOR) {
+        ALOGE("Must use wifi_unregister_vendor_handler to remove vendor handlers");
+        return;
+    }
+
+    pthread_mutex_lock(&info->cb_lock);
+
+    for (int i = 0; i < info->num_event_cb; i++) {
+        if (info->event_cb[i].nl_cmd == cmd) {
+            /*
+            ALOGI("Successfully removed event handler %p:%p for cmd = 0x%0x from %d",
+                    info->event_cb[i].cb_arg, info->event_cb[i].cb_func, cmd, i);*/
+
+            memmove(&info->event_cb[i], &info->event_cb[i+1],
+                (info->num_event_cb - i - 1) * sizeof(cb_info));
+            info->num_event_cb--;
+            break;
+        }
+    }
+
+    pthread_mutex_unlock(&info->cb_lock);
+}
+
+void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
+{
+    hal_info *info = (hal_info *)handle;
+
+    pthread_mutex_lock(&info->cb_lock);
+
+    for (int i = 0; i < info->num_event_cb; i++) {
+
+        if (info->event_cb[i].nl_cmd == NL80211_CMD_VENDOR
+                && info->event_cb[i].vendor_id == id
+                && info->event_cb[i].vendor_subcmd == subcmd) {
+            /*
+            ALOGI("Successfully removed event handler %p:%p for vendor 0x%0x, subcmd 0x%0x from %d",
+                    info->event_cb[i].cb_arg, info->event_cb[i].cb_func, id, subcmd, i);*/
+            memmove(&info->event_cb[i], &info->event_cb[i+1],
+                (info->num_event_cb - i - 1) * sizeof(cb_info));
+            info->num_event_cb--;
+            break;
+        }
+    }
+
+    pthread_mutex_unlock(&info->cb_lock);
+}
+
+
+wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd)
+{
+    hal_info *info = (hal_info *)handle;
+
+    //ALOGD("registering command %d", id);
+
+    wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
+
+    if (info->num_cmd < info->alloc_cmd) {
+        info->cmd[info->num_cmd].id   = id;
+        info->cmd[info->num_cmd].cmd  = cmd;
+        //ALOGI("Successfully added command %d: %p at %d", id, cmd, info->num_cmd);
+        info->num_cmd++;
+        result = WIFI_SUCCESS;
+    }
+
+    return result;
+}
+
+WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id)
+{
+    hal_info *info = (hal_info *)handle;
+
+    //ALOGD("un-registering command %d", id);
+
+    WifiCommand *cmd = NULL;
+
+    for (int i = 0; i < info->num_cmd; i++) {
+        if (info->cmd[i].id == id) {
+            cmd = info->cmd[i].cmd;
+            memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i) * sizeof(cmd_info));
+            info->num_cmd--;
+            //ALOGI("Successfully removed command %d: %p from %d", id, cmd, i);
+            break;
+        }
+    }
+
+    return cmd;
+}
+
+WifiCommand *wifi_get_cmd(wifi_handle handle, int id)
+{
+    hal_info *info = (hal_info *)handle;
+
+    WifiCommand *cmd = NULL;
+
+    for (int i = 0; i < info->num_cmd; i++) {
+        if (info->cmd[i].id == id) {
+            cmd = info->cmd[i].cmd;
+            break;
+        }
+    }
+
+    return cmd;
+}
+
+void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd)
+{
+    hal_info *info = (hal_info *)handle;
+
+    for (int i = 0; i < info->num_cmd; i++) {
+        if (info->cmd[i].cmd == cmd) {
+            memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i) * sizeof(cmd_info));
+            info->num_cmd--;
+            //ALOGI("Successfully removed command %d: %p from %d", id, cmd, i);
+            break;
+        }
+    }
+}
+
+wifi_error wifi_cancel_cmd(wifi_request_id id, wifi_interface_handle iface)
+{
+	wifi_handle handle = getWifiHandle(iface);
+
+	WifiCommand *cmd = wifi_unregister_cmd(handle, id);
+	//ALOGD("Cancel WifiCommand = %p", cmd);
+	if (cmd) {
+		cmd->cancel();
+		cmd->releaseRef();
+		return WIFI_SUCCESS;
+	}
+
+    return WIFI_ERROR_INVALID_ARGS;
+}
diff --git a/common.h b/common.h
new file mode 100755
index 0000000..7f270a3
--- /dev/null
+++ b/common.h
@@ -0,0 +1,302 @@
+
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_COMMON_H__
+#define __WIFI_HAL_COMMON_H__
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG  "WifiHAL"
+
+#include <utils/Log.h>
+#include "nl80211_copy.h"
+#include "sync.h"
+
+#define SOCKET_BUFFER_SIZE      (32768U)
+#define RECV_BUF_SIZE           (4096)
+#define DEFAULT_EVENT_CB_SIZE   (64)
+#define DEFAULT_CMD_SIZE        (64)
+#define DOT11_OUI_LEN             3
+
+typedef struct {
+	int num_bssid;
+	mac_addr bssids[MAX_BLACKLIST_BSSID];
+} wifi_bssid_params;
+
+/*
+ Vendor OUI - This is a unique identifier that identifies organization. Lets
+ code Android specific functions with Google OUI; although vendors can do more
+ with their own OUI's as well.
+ */
+
+const uint32_t GOOGLE_OUI = 0x001A11;
+/* TODO: define vendor OUI here */
+
+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_REPORT_THRESHOLD_NUM_SCANS,
+    GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND,
+
+    GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20,
+    GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE,              /* indicates no more results */
+    GSCAN_ATTRIBUTE_REPORT_EVENTS,
+
+    /* remaining reserved for additional attributes */
+    GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30,
+    GSCAN_ATTRIBUTE_SCAN_RESULTS,                       /* flat array of wifi_scan_result */
+    GSCAN_ATTRIBUTE_NUM_CHANNELS,
+    GSCAN_ATTRIBUTE_CHANNEL_LIST,
+    GSCAN_ATTRIBUTE_SCAN_ID,
+    GSCAN_ATTRIBUTE_SCAN_FLAGS,
+    GSCAN_ATTRIBUTE_SCAN_BUCKET_BIT,
+
+    /* 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_CHANNEL_NUMBER,
+
+    /* 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_BUCKET_STEP_COUNT = 70,
+    GSCAN_ATTRIBUTE_BUCKET_EXPONENT,
+    GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD,
+
+    GSCAN_ATTRIBUTE_NUM_BSSID,
+    GSCAN_ATTRIBUTE_BLACKLIST_BSSID,
+
+    GSCAN_ATTRIBUTE_MAX
+
+} GSCAN_ATTRIBUTE;
+
+/*
+ This enum defines ranges for various commands; commands themselves
+ can be defined in respective feature headers; i.e. find gscan command
+ definitions in gscan.cpp
+ */
+
+typedef enum {
+    /* don't use 0 as a valid subcommand */
+    VENDOR_NL80211_SUBCMD_UNSPECIFIED,
+
+    /* define all vendor startup commands between 0x0 and 0x0FFF */
+    VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001,
+    VENDOR_NL80211_SUBCMD_RANGE_END   = 0x0FFF,
+
+    /* define all GScan related commands between 0x1000 and 0x10FF */
+    ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000,
+    ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END   = 0x10FF,
+
+    /* define all NearbyDiscovery related commands between 0x1100 and 0x11FF */
+    ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1100,
+    ANDROID_NL80211_SUBCMD_NBD_RANGE_END   = 0x11FF,
+
+    /* define all RTT related commands between 0x1100 and 0x11FF */
+    ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100,
+    ANDROID_NL80211_SUBCMD_RTT_RANGE_END   = 0x11FF,
+
+    ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200,
+    ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END   = 0x12FF,
+
+    /* define all Logger related commands between 0x1400 and 0x14FF */
+    ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400,
+    ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END   = 0x14FF,
+
+    /* define all wifi offload related commands between 0x1400 and 0x14FF */
+    ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1400,
+    ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END   = 0x14FF,
+
+    /* Range for NAN commands */
+    ANDROID_NL80211_SUBCMD_NAN_RANGE_START = 0x1500,
+    ANDROID_NL80211_SUBCMD_NAN_RANGE_END   = 0x15FF,
+   /* This is reserved for future usage */
+
+} ANDROID_VENDOR_SUB_COMMAND;
+
+typedef enum {
+    SLSI_NL80211_VENDOR_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
+    SLSI_NL80211_VENDOR_SUBCMD_GET_VALID_CHANNELS,
+    SLSI_NL80211_VENDOR_SUBCMD_ADD_GSCAN,
+    SLSI_NL80211_VENDOR_SUBCMD_DEL_GSCAN,
+    SLSI_NL80211_VENDOR_SUBCMD_GET_SCAN_RESULTS,
+    SLSI_NL80211_VENDOR_SUBCMD_SET_BSSID_HOTLIST,
+    SLSI_NL80211_VENDOR_SUBCMD_RESET_BSSID_HOTLIST,
+    SLSI_NL80211_VENDOR_SUBCMD_GET_HOTLIST_RESULTS,
+    SLSI_NL80211_VENDOR_SUBCMD_SET_SIGNIFICANT_CHANGE,
+    SLSI_NL80211_VENDOR_SUBCMD_RESET_SIGNIFICANT_CHANGE,
+    SLSI_NL80211_VENDOR_SUBCMD_SET_GSCAN_OUI,
+    SLSI_NL80211_VENDOR_SUBCMD_SET_NODFS,
+    SLSI_NL80211_VENDOR_SUBCMD_START_KEEP_ALIVE_OFFLOAD,
+    SLSI_NL80211_VENDOR_SUBCMD_STOP_KEEP_ALIVE_OFFLOAD,
+    SLSI_NL80211_VENDOR_SUBCMD_SET_BSSID_BLACKLIST,
+    SLSI_NL80211_VENDOR_SUBCMD_SET_EPNO_LIST,
+    SLSI_NL80211_VENDOR_SUBCMD_SET_HS_LIST,
+    SLSI_NL80211_VENDOR_SUBCMD_RESET_HS_LIST,
+    SLSI_NL80211_VENDOR_SUBCMD_SET_RSSI_MONITOR,
+    SLSI_NL80211_VENDOR_SUBCMD_LLS_SET_INFO,
+    SLSI_NL80211_VENDOR_SUBCMD_LLS_GET_INFO,
+    SLSI_NL80211_VENDOR_SUBCMD_LLS_CLEAR_INFO,
+    SLSI_NL80211_VENDOR_SUBCMD_GET_FEATURE_SET,
+    SLSI_NL80211_VENDOR_SUBCMD_SET_COUNTRY_CODE,
+    SLSI_NL80211_VENDOR_SUBCMD_CONFIGURE_ND_OFFLOAD,
+    SLSI_NL80211_VENDOR_SUBCMD_GET_ROAMING_CAPABILITIES,
+    SLSI_NL80211_VENDOR_SUBCMD_SET_ROAMING_STATE,
+
+    SLSI_NL80211_VENDOR_SUBCMD_NAN_ENABLE = ANDROID_NL80211_SUBCMD_NAN_RANGE_START,
+    SLSI_NL80211_VENDOR_SUBCMD_NAN_DISABLE,
+    SLSI_NL80211_VENDOR_SUBCMD_NAN_PUBLISH,
+    SLSI_NL80211_VENDOR_SUBCMD_NAN_PUBLISHCANCEL,
+    SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBE,
+    SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBECANCEL,
+    SLSI_NL80211_VENDOR_SUBCMD_NAN_TXFOLLOWUP,
+    SLSI_NL80211_VENDOR_SUBCMD_NAN_CONFIG,
+    SLSI_NL80211_VENDOR_SUBCMD_NAN_CAPABILITIES,
+    SLSI_NL80211_VENDOR_SUBCMD_RTT_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
+    SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_START,
+    SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_CANCEL
+} WIFI_SUB_COMMAND;
+
+typedef enum {
+    GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS ,
+    GSCAN_EVENT_HOTLIST_RESULTS_FOUND,
+    GSCAN_EVENT_SCAN_RESULTS_AVAILABLE,
+    GSCAN_EVENT_FULL_SCAN_RESULTS,
+    GSCAN_EVENT_COMPLETE_SCAN,
+    GSCAN_EVENT_HOTLIST_RESULTS_LOST,
+    WIFI_SUBCMD_KEY_MGMT_ROAM_AUTH, /* Handled by supplicant. not in Wifi-HAL */
+    WIFI_HANGED_EVENT,
+    WIFI_EPNO_EVENT,
+    WIFI_HOTSPOT_MATCH,
+    WIFI_RSSI_REPORT_EVENT,
+    ENHANCE_LOGGER_RING_EVENT,
+    ENHANCE_LOGGER_MEM_DUMP_EVENT,
+    /* NAN events start */
+    SLSI_NAN_EVENT_RESPONSE,
+    SLSI_NAN_EVENT_PUBLISH_TERMINATED,
+    SLSI_NAN_EVENT_MATCH,
+    SLSI_NAN_EVENT_MATCH_EXPIRED,
+    SLSI_NAN_EVENT_SUBSCRIBE_TERMINATED,
+    SLSI_NAN_EVENT_FOLLOWUP,
+    SLSI_NAN_EVENT_DISCOVERY_ENGINE,
+    SLSI_NAN_EVENT_DISABLED,
+    /* NAN events end */
+    SLSI_RTT_RESULT_EVENT,
+    SLSI_RTT_EVENT_COMPLETE
+
+} WIFI_EVENT;
+
+typedef void (*wifi_internal_event_handler) (wifi_handle handle, int events);
+
+class WifiCommand;
+
+typedef struct {
+    int nl_cmd;
+    uint32_t vendor_id;
+    int vendor_subcmd;
+    nl_recvmsg_msg_cb_t cb_func;
+    void *cb_arg;
+} cb_info;
+
+typedef struct {
+    wifi_request_id id;
+    WifiCommand *cmd;
+} cmd_info;
+
+typedef struct {
+    wifi_handle handle;                             // handle to wifi data
+    char name[8+1];                                 // interface name + trailing null
+    int  id;                                        // id to use when talking to driver
+} interface_info;
+
+typedef struct {
+
+    struct nl_sock *cmd_sock;                       // command socket object
+    struct nl_sock *event_sock;                     // event socket object
+    int nl80211_family_id;                          // family id for 80211 driver
+    int cleanup_socks[2];                           // sockets used to implement wifi_cleanup
+
+    bool in_event_loop;                             // Indicates that event loop is active
+    bool clean_up;                                  // Indication to clean up the socket
+
+    wifi_internal_event_handler event_handler;      // default event handler
+    wifi_cleaned_up_handler cleaned_up_handler;     // socket cleaned up handler
+
+    cb_info *event_cb;                              // event callbacks
+    int num_event_cb;                               // number of event callbacks
+    int alloc_event_cb;                             // number of allocated callback objects
+    pthread_mutex_t cb_lock;                        // mutex for the event_cb access
+
+    cmd_info *cmd;                                  // Outstanding commands
+    int num_cmd;                                    // number of commands
+    int alloc_cmd;                                  // number of commands allocated
+
+    interface_info **interfaces;                    // array of interfaces
+    int num_interfaces;                             // number of interfaces
+
+
+    // add other details
+} hal_info;
+
+wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg);
+wifi_error wifi_register_vendor_handler(wifi_handle handle,
+            uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg);
+
+void wifi_unregister_handler(wifi_handle handle, int cmd);
+void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd);
+
+wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd);
+WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id);
+WifiCommand *wifi_get_cmd(wifi_handle handle, int id);
+void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd);
+wifi_error wifi_cancel_cmd(wifi_request_id id, wifi_interface_handle iface);
+
+interface_info *getIfaceInfo(wifi_interface_handle);
+wifi_handle getWifiHandle(wifi_interface_handle handle);
+hal_info *getHalInfo(wifi_handle handle);
+hal_info *getHalInfo(wifi_interface_handle handle);
+wifi_handle getWifiHandle(hal_info *info);
+wifi_interface_handle getIfaceHandle(interface_info *info);
+
+
+// some common macros
+
+#define min(x, y)       ((x) < (y) ? (x) : (y))
+#define max(x, y)       ((x) > (y) ? (x) : (y))
+
+#define NULL_CHECK_RETURN(ptr, str, ret) \
+    do { \
+        if (!(ptr)) { \
+            ALOGE("%s(): null pointer - #ptr (%s)\n", __FUNCTION__, str); \
+            return ret; \
+        } \
+    } while (0)
+#endif
+
diff --git a/cpp_bindings.cpp b/cpp_bindings.cpp
new file mode 100755
index 0000000..5ab68b1
--- /dev/null
+++ b/cpp_bindings.cpp
@@ -0,0 +1,694 @@
+
+#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 <stdarg.h>
+
+#include <ctype.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+void appendFmt(char *buf, int &offset, const char *fmt, ...)
+{
+    va_list params;
+    va_start(params, fmt);
+    offset += vsprintf(buf + offset, fmt, params);
+    va_end(params);
+}
+
+#define C2S(x)  case x: return #x;
+
+static const char *cmdToString(int cmd)
+{
+	switch (cmd) {
+	C2S(NL80211_CMD_UNSPEC)
+	C2S(NL80211_CMD_GET_WIPHY)
+	C2S(NL80211_CMD_SET_WIPHY)
+	C2S(NL80211_CMD_NEW_WIPHY)
+	C2S(NL80211_CMD_DEL_WIPHY)
+	C2S(NL80211_CMD_GET_INTERFACE)
+	C2S(NL80211_CMD_SET_INTERFACE)
+	C2S(NL80211_CMD_NEW_INTERFACE)
+	C2S(NL80211_CMD_DEL_INTERFACE)
+	C2S(NL80211_CMD_GET_KEY)
+	C2S(NL80211_CMD_SET_KEY)
+	C2S(NL80211_CMD_NEW_KEY)
+	C2S(NL80211_CMD_DEL_KEY)
+	C2S(NL80211_CMD_GET_BEACON)
+	C2S(NL80211_CMD_SET_BEACON)
+	C2S(NL80211_CMD_START_AP)
+	C2S(NL80211_CMD_STOP_AP)
+	C2S(NL80211_CMD_GET_STATION)
+	C2S(NL80211_CMD_SET_STATION)
+	C2S(NL80211_CMD_NEW_STATION)
+	C2S(NL80211_CMD_DEL_STATION)
+	C2S(NL80211_CMD_GET_MPATH)
+	C2S(NL80211_CMD_SET_MPATH)
+	C2S(NL80211_CMD_NEW_MPATH)
+	C2S(NL80211_CMD_DEL_MPATH)
+	C2S(NL80211_CMD_SET_BSS)
+	C2S(NL80211_CMD_SET_REG)
+	C2S(NL80211_CMD_REQ_SET_REG)
+	C2S(NL80211_CMD_GET_MESH_CONFIG)
+	C2S(NL80211_CMD_SET_MESH_CONFIG)
+	C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
+	C2S(NL80211_CMD_GET_REG)
+	C2S(NL80211_CMD_GET_SCAN)
+	C2S(NL80211_CMD_TRIGGER_SCAN)
+	C2S(NL80211_CMD_NEW_SCAN_RESULTS)
+	C2S(NL80211_CMD_SCAN_ABORTED)
+	C2S(NL80211_CMD_REG_CHANGE)
+	C2S(NL80211_CMD_AUTHENTICATE)
+	C2S(NL80211_CMD_ASSOCIATE)
+	C2S(NL80211_CMD_DEAUTHENTICATE)
+	C2S(NL80211_CMD_DISASSOCIATE)
+	C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
+	C2S(NL80211_CMD_REG_BEACON_HINT)
+	C2S(NL80211_CMD_JOIN_IBSS)
+	C2S(NL80211_CMD_LEAVE_IBSS)
+	C2S(NL80211_CMD_TESTMODE)
+	C2S(NL80211_CMD_CONNECT)
+	C2S(NL80211_CMD_ROAM)
+	C2S(NL80211_CMD_DISCONNECT)
+	C2S(NL80211_CMD_SET_WIPHY_NETNS)
+	C2S(NL80211_CMD_GET_SURVEY)
+	C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
+	C2S(NL80211_CMD_SET_PMKSA)
+	C2S(NL80211_CMD_DEL_PMKSA)
+	C2S(NL80211_CMD_FLUSH_PMKSA)
+	C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
+	C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
+	C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
+	C2S(NL80211_CMD_REGISTER_FRAME)
+	C2S(NL80211_CMD_FRAME)
+	C2S(NL80211_CMD_FRAME_TX_STATUS)
+	C2S(NL80211_CMD_SET_POWER_SAVE)
+	C2S(NL80211_CMD_GET_POWER_SAVE)
+	C2S(NL80211_CMD_SET_CQM)
+	C2S(NL80211_CMD_NOTIFY_CQM)
+	C2S(NL80211_CMD_SET_CHANNEL)
+	C2S(NL80211_CMD_SET_WDS_PEER)
+	C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
+	C2S(NL80211_CMD_JOIN_MESH)
+	C2S(NL80211_CMD_LEAVE_MESH)
+	C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
+	C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
+	C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
+	C2S(NL80211_CMD_GET_WOWLAN)
+	C2S(NL80211_CMD_SET_WOWLAN)
+	C2S(NL80211_CMD_START_SCHED_SCAN)
+	C2S(NL80211_CMD_STOP_SCHED_SCAN)
+	C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
+	C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
+	C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
+	C2S(NL80211_CMD_PMKSA_CANDIDATE)
+	C2S(NL80211_CMD_TDLS_OPER)
+	C2S(NL80211_CMD_TDLS_MGMT)
+	C2S(NL80211_CMD_UNEXPECTED_FRAME)
+	C2S(NL80211_CMD_PROBE_CLIENT)
+	C2S(NL80211_CMD_REGISTER_BEACONS)
+	C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
+	C2S(NL80211_CMD_SET_NOACK_MAP)
+	C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
+	C2S(NL80211_CMD_START_P2P_DEVICE)
+	C2S(NL80211_CMD_STOP_P2P_DEVICE)
+	C2S(NL80211_CMD_CONN_FAILED)
+	C2S(NL80211_CMD_SET_MCAST_RATE)
+	C2S(NL80211_CMD_SET_MAC_ACL)
+	C2S(NL80211_CMD_RADAR_DETECT)
+	C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
+	C2S(NL80211_CMD_UPDATE_FT_IES)
+	C2S(NL80211_CMD_FT_EVENT)
+	C2S(NL80211_CMD_CRIT_PROTOCOL_START)
+	C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
+	C2S(NL80211_CMD_VENDOR)
+	default:
+		return "NL80211_CMD_UNKNOWN";
+	}
+}
+
+const char *attributeToString(int attribute)
+{
+    switch (attribute) {
+	C2S(NL80211_ATTR_UNSPEC)
+
+	C2S(NL80211_ATTR_WIPHY)
+	C2S(NL80211_ATTR_WIPHY_NAME)
+
+	C2S(NL80211_ATTR_IFINDEX)
+	C2S(NL80211_ATTR_IFNAME)
+	C2S(NL80211_ATTR_IFTYPE)
+
+	C2S(NL80211_ATTR_MAC)
+
+	C2S(NL80211_ATTR_KEY_DATA)
+	C2S(NL80211_ATTR_KEY_IDX)
+	C2S(NL80211_ATTR_KEY_CIPHER)
+	C2S(NL80211_ATTR_KEY_SEQ)
+	C2S(NL80211_ATTR_KEY_DEFAULT)
+
+	C2S(NL80211_ATTR_BEACON_INTERVAL)
+	C2S(NL80211_ATTR_DTIM_PERIOD)
+	C2S(NL80211_ATTR_BEACON_HEAD)
+	C2S(NL80211_ATTR_BEACON_TAIL)
+
+	C2S(NL80211_ATTR_STA_AID)
+	C2S(NL80211_ATTR_STA_FLAGS)
+	C2S(NL80211_ATTR_STA_LISTEN_INTERVAL)
+	C2S(NL80211_ATTR_STA_SUPPORTED_RATES)
+	C2S(NL80211_ATTR_STA_VLAN)
+	C2S(NL80211_ATTR_STA_INFO)
+
+	C2S(NL80211_ATTR_WIPHY_BANDS)
+
+	C2S(NL80211_ATTR_MNTR_FLAGS)
+
+	C2S(NL80211_ATTR_MESH_ID)
+	C2S(NL80211_ATTR_STA_PLINK_ACTION)
+	C2S(NL80211_ATTR_MPATH_NEXT_HOP)
+	C2S(NL80211_ATTR_MPATH_INFO)
+
+	C2S(NL80211_ATTR_BSS_CTS_PROT)
+	C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE)
+	C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME)
+
+	C2S(NL80211_ATTR_HT_CAPABILITY)
+
+	C2S(NL80211_ATTR_SUPPORTED_IFTYPES)
+
+	C2S(NL80211_ATTR_REG_ALPHA2)
+	C2S(NL80211_ATTR_REG_RULES)
+
+	C2S(NL80211_ATTR_MESH_CONFIG)
+
+	C2S(NL80211_ATTR_BSS_BASIC_RATES)
+
+	C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS)
+	C2S(NL80211_ATTR_WIPHY_FREQ)
+	C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE)
+
+	C2S(NL80211_ATTR_KEY_DEFAULT_MGMT)
+
+	C2S(NL80211_ATTR_MGMT_SUBTYPE)
+	C2S(NL80211_ATTR_IE)
+
+	C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS)
+
+	C2S(NL80211_ATTR_SCAN_FREQUENCIES)
+	C2S(NL80211_ATTR_SCAN_SSIDS)
+	C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */
+	C2S(NL80211_ATTR_BSS)
+
+	C2S(NL80211_ATTR_REG_INITIATOR)
+	C2S(NL80211_ATTR_REG_TYPE)
+
+	C2S(NL80211_ATTR_SUPPORTED_COMMANDS)
+
+	C2S(NL80211_ATTR_FRAME)
+	C2S(NL80211_ATTR_SSID)
+	C2S(NL80211_ATTR_AUTH_TYPE)
+	C2S(NL80211_ATTR_REASON_CODE)
+
+	C2S(NL80211_ATTR_KEY_TYPE)
+
+	C2S(NL80211_ATTR_MAX_SCAN_IE_LEN)
+	C2S(NL80211_ATTR_CIPHER_SUITES)
+
+	C2S(NL80211_ATTR_FREQ_BEFORE)
+	C2S(NL80211_ATTR_FREQ_AFTER)
+
+	C2S(NL80211_ATTR_FREQ_FIXED)
+
+
+	C2S(NL80211_ATTR_WIPHY_RETRY_SHORT)
+	C2S(NL80211_ATTR_WIPHY_RETRY_LONG)
+	C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD)
+	C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD)
+
+	C2S(NL80211_ATTR_TIMED_OUT)
+
+	C2S(NL80211_ATTR_USE_MFP)
+
+	C2S(NL80211_ATTR_STA_FLAGS2)
+
+	C2S(NL80211_ATTR_CONTROL_PORT)
+
+	C2S(NL80211_ATTR_TESTDATA)
+
+	C2S(NL80211_ATTR_PRIVACY)
+
+	C2S(NL80211_ATTR_DISCONNECTED_BY_AP)
+	C2S(NL80211_ATTR_STATUS_CODE)
+
+	C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE)
+	C2S(NL80211_ATTR_CIPHER_SUITE_GROUP)
+	C2S(NL80211_ATTR_WPA_VERSIONS)
+	C2S(NL80211_ATTR_AKM_SUITES)
+
+	C2S(NL80211_ATTR_REQ_IE)
+	C2S(NL80211_ATTR_RESP_IE)
+
+	C2S(NL80211_ATTR_PREV_BSSID)
+
+	C2S(NL80211_ATTR_KEY)
+	C2S(NL80211_ATTR_KEYS)
+
+	C2S(NL80211_ATTR_PID)
+
+	C2S(NL80211_ATTR_4ADDR)
+
+	C2S(NL80211_ATTR_SURVEY_INFO)
+
+	C2S(NL80211_ATTR_PMKID)
+	C2S(NL80211_ATTR_MAX_NUM_PMKIDS)
+
+	C2S(NL80211_ATTR_DURATION)
+
+	C2S(NL80211_ATTR_COOKIE)
+
+	C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS)
+
+	C2S(NL80211_ATTR_TX_RATES)
+
+	C2S(NL80211_ATTR_FRAME_MATCH)
+
+	C2S(NL80211_ATTR_ACK)
+
+	C2S(NL80211_ATTR_PS_STATE)
+
+	C2S(NL80211_ATTR_CQM)
+
+	C2S(NL80211_ATTR_LOCAL_STATE_CHANGE)
+
+	C2S(NL80211_ATTR_AP_ISOLATE)
+
+	C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING)
+	C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL)
+
+	C2S(NL80211_ATTR_TX_FRAME_TYPES)
+	C2S(NL80211_ATTR_RX_FRAME_TYPES)
+	C2S(NL80211_ATTR_FRAME_TYPE)
+
+	C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
+	C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)
+
+	C2S(NL80211_ATTR_SUPPORT_IBSS_RSN)
+
+	C2S(NL80211_ATTR_WIPHY_ANTENNA_TX)
+	C2S(NL80211_ATTR_WIPHY_ANTENNA_RX)
+
+	C2S(NL80211_ATTR_MCAST_RATE)
+
+	C2S(NL80211_ATTR_OFFCHANNEL_TX_OK)
+
+	C2S(NL80211_ATTR_BSS_HT_OPMODE)
+
+	C2S(NL80211_ATTR_KEY_DEFAULT_TYPES)
+
+	C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION)
+
+	C2S(NL80211_ATTR_MESH_SETUP)
+
+	C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX)
+	C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX)
+
+	C2S(NL80211_ATTR_SUPPORT_MESH_AUTH)
+	C2S(NL80211_ATTR_STA_PLINK_STATE)
+
+	C2S(NL80211_ATTR_WOWLAN_TRIGGERS)
+	C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED)
+
+	C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL)
+
+	C2S(NL80211_ATTR_INTERFACE_COMBINATIONS)
+	C2S(NL80211_ATTR_SOFTWARE_IFTYPES)
+
+	C2S(NL80211_ATTR_REKEY_DATA)
+
+	C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS)
+	C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN)
+
+	C2S(NL80211_ATTR_SCAN_SUPP_RATES)
+
+	C2S(NL80211_ATTR_HIDDEN_SSID)
+
+	C2S(NL80211_ATTR_IE_PROBE_RESP)
+	C2S(NL80211_ATTR_IE_ASSOC_RESP)
+
+	C2S(NL80211_ATTR_STA_WME)
+	C2S(NL80211_ATTR_SUPPORT_AP_UAPSD)
+
+	C2S(NL80211_ATTR_ROAM_SUPPORT)
+
+	C2S(NL80211_ATTR_SCHED_SCAN_MATCH)
+	C2S(NL80211_ATTR_MAX_MATCH_SETS)
+
+	C2S(NL80211_ATTR_PMKSA_CANDIDATE)
+
+	C2S(NL80211_ATTR_TX_NO_CCK_RATE)
+
+	C2S(NL80211_ATTR_TDLS_ACTION)
+	C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN)
+	C2S(NL80211_ATTR_TDLS_OPERATION)
+	C2S(NL80211_ATTR_TDLS_SUPPORT)
+	C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP)
+
+	C2S(NL80211_ATTR_DEVICE_AP_SME)
+
+	C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK)
+
+	C2S(NL80211_ATTR_FEATURE_FLAGS)
+
+	C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD)
+
+	C2S(NL80211_ATTR_PROBE_RESP)
+
+	C2S(NL80211_ATTR_DFS_REGION)
+
+	C2S(NL80211_ATTR_DISABLE_HT)
+	C2S(NL80211_ATTR_HT_CAPABILITY_MASK)
+
+	C2S(NL80211_ATTR_NOACK_MAP)
+
+	C2S(NL80211_ATTR_INACTIVITY_TIMEOUT)
+
+	C2S(NL80211_ATTR_RX_SIGNAL_DBM)
+
+	C2S(NL80211_ATTR_BG_SCAN_PERIOD)
+
+	C2S(NL80211_ATTR_WDEV)
+
+	C2S(NL80211_ATTR_USER_REG_HINT_TYPE)
+
+	C2S(NL80211_ATTR_CONN_FAILED_REASON)
+
+	C2S(NL80211_ATTR_SAE_DATA)
+
+	C2S(NL80211_ATTR_VHT_CAPABILITY)
+
+	C2S(NL80211_ATTR_SCAN_FLAGS)
+
+	C2S(NL80211_ATTR_CHANNEL_WIDTH)
+	C2S(NL80211_ATTR_CENTER_FREQ1)
+	C2S(NL80211_ATTR_CENTER_FREQ2)
+
+	C2S(NL80211_ATTR_P2P_CTWINDOW)
+	C2S(NL80211_ATTR_P2P_OPPPS)
+
+	C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE)
+
+	C2S(NL80211_ATTR_ACL_POLICY)
+
+	C2S(NL80211_ATTR_MAC_ADDRS)
+
+	C2S(NL80211_ATTR_MAC_ACL_MAX)
+
+	C2S(NL80211_ATTR_RADAR_EVENT)
+
+	C2S(NL80211_ATTR_EXT_CAPA)
+	C2S(NL80211_ATTR_EXT_CAPA_MASK)
+
+	C2S(NL80211_ATTR_STA_CAPABILITY)
+	C2S(NL80211_ATTR_STA_EXT_CAPABILITY)
+
+	C2S(NL80211_ATTR_PROTOCOL_FEATURES)
+	C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP)
+
+	C2S(NL80211_ATTR_DISABLE_VHT)
+	C2S(NL80211_ATTR_VHT_CAPABILITY_MASK)
+
+	C2S(NL80211_ATTR_MDID)
+	C2S(NL80211_ATTR_IE_RIC)
+
+	C2S(NL80211_ATTR_CRIT_PROT_ID)
+	C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION)
+
+	C2S(NL80211_ATTR_PEER_AID)
+
+
+	//S(NL80211_ATTR_VENDOR_ID)
+	C2S(NL80211_ATTR_VENDOR_SUBCMD)
+	C2S(NL80211_ATTR_VENDOR_DATA)
+	C2S(NL80211_ATTR_VENDOR_EVENTS)
+
+    default:
+        return "NL80211_ATTR_UNKNOWN";
+    }
+}
+
+void WifiEvent::log() {
+    parse();
+
+    byte *data = (byte *)genlmsg_attrdata(mHeader, 0);
+    int len = genlmsg_attrlen(mHeader, 0);
+    ALOGD("cmd = %s, len = %d", get_cmdString(), len);
+    ALOGD("vendor_id = %04x, vendor_subcmd = %d", get_vendor_id(), get_vendor_subcmd());
+
+    for (int i = 0; i < len; i += 16) {
+        char line[81];
+        int linelen = min(16, len - i);
+        int offset = 0;
+        appendFmt(line, offset, "%02x", data[i]);
+        for (int j = 1; j < linelen; j++) {
+            appendFmt(line, offset, " %02x", data[i+j]);
+        }
+
+        for (int j = linelen; j < 16; j++) {
+            appendFmt(line, offset, "   ");
+        }
+
+        line[23] = '-';
+
+        appendFmt(line, offset, "  ");
+
+        for (int j = 0; j < linelen; j++) {
+            if (isprint(data[i+j])) {
+                appendFmt(line, offset, "%c", data[i+j]);
+            } else {
+                appendFmt(line, offset, "-");
+            }
+        }
+
+        ALOGD("%s", line);
+    }
+
+    for (unsigned i = 0; i < NL80211_ATTR_MAX_INTERNAL; i++) {
+        if (mAttributes[i] != NULL) {
+            ALOGD("found attribute %s", attributeToString(i));
+        }
+    }
+}
+
+const char *WifiEvent::get_cmdString() {
+    return cmdToString(get_cmd());
+}
+
+
+int WifiEvent::parse() {
+    if (mHeader != NULL) {
+        return WIFI_SUCCESS;
+    }
+    mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
+    int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
+          genlmsg_attrlen(mHeader, 0), NULL);
+
+    return result;
+}
+
+int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
+    mMsg = nlmsg_alloc();
+    if (mMsg != NULL) {
+        genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
+                hdrlen, flags, cmd, /* version = */ 0);
+        return WIFI_SUCCESS;
+    } else {
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+}
+
+int WifiRequest::create(uint32_t id, int subcmd) {
+    int res = create(NL80211_CMD_VENDOR);
+    if (res < 0) {
+        return res;
+    }
+
+    res = put_u32(NL80211_ATTR_VENDOR_ID, id);
+    if (res < 0) {
+        return res;
+    }
+
+    res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
+    if (res < 0) {
+        return res;
+    }
+
+    if (mIface != -1) {
+        res = set_iface_id(mIface);
+    }
+
+    return res;
+}
+
+
+static int no_seq_check(struct nl_msg *msg, void *arg)
+{
+	return NL_OK;
+}
+
+int WifiCommand::requestResponse() {
+    int err = create();                 /* create the message */
+    if (err < 0) {
+        return err;
+    }
+
+    return requestResponse(mMsg);
+}
+
+int WifiCommand::requestResponse(WifiRequest& request) {
+    int err = 0;
+
+    struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
+    if (!cb)
+        goto out;
+
+    err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage());    /* send message */
+    if (err < 0)
+        goto out;
+
+    err = 1;
+
+    nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
+    nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
+    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
+    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
+    nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
+
+    while (err > 0) {                   /* wait for reply */
+        int res = nl_recvmsgs(mInfo->cmd_sock, cb);
+        if (res) {
+            ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __func__, res);
+        }
+    }
+out:
+    nl_cb_put(cb);
+    return err;
+}
+
+int WifiCommand::requestEvent(int cmd) {
+
+    int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this);
+    if (res < 0) {
+        return res;
+    }
+
+    res = create();                                                 /* create the message */
+    if (res < 0)
+        goto out;
+
+    res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
+    if (res < 0)
+        goto out;
+
+    res = mCondition.wait();
+    if (res < 0)
+        goto out;
+
+out:
+    wifi_unregister_handler(wifiHandle(), cmd);
+    return res;
+}
+
+int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
+
+    int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
+    if (res < 0) {
+        return res;
+    }
+
+    res = create();                                                 /* create the message */
+    if (res < 0)
+        goto out;
+
+    res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
+    if (res < 0)
+        goto out;
+
+    res = mCondition.wait();
+    if (res < 0)
+        goto out;
+
+out:
+    wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
+    return res;
+}
+
+/* Event handlers */
+int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
+    WifiCommand *cmd = (WifiCommand *)arg;
+    WifiEvent reply(msg);
+    int res = reply.parse();
+    if (res < 0) {
+        ALOGE("Failed to parse reply message = %d", res);
+        return NL_SKIP;
+    } else {
+        // reply.log();
+        return cmd->handleResponse(reply);
+    }
+}
+
+int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
+    WifiCommand *cmd = (WifiCommand *)arg;
+    WifiEvent event(msg);
+    int res = event.parse();
+    if (res < 0) {
+        ALOGE("Failed to parse event = %d", res);
+        res = NL_SKIP;
+    } else {
+        res = cmd->handleEvent(event);
+    }
+
+    cmd->mCondition.signal();
+    return res;
+}
+
+/* Other event handlers */
+int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
+    int *err = (int *)arg;
+    *err = 0;
+    return NL_SKIP;
+}
+
+int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
+    int *err = (int *)arg;
+    *err = 0;
+    return NL_STOP;
+}
+
+int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
+    int *ret = (int *)arg;
+    *ret = 0;
+    return NL_SKIP;
+}
+
+int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
+    int *ret = (int *)arg;
+    *ret = err->error;
+
+    /*ALOGD("error_handler received : %d", err->error);*/
+    return NL_SKIP;
+}
diff --git a/cpp_bindings.h b/cpp_bindings.h
new file mode 100755
index 0000000..d1e1e5a
--- /dev/null
+++ b/cpp_bindings.h
@@ -0,0 +1,347 @@
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "sync.h"
+
+class WifiEvent
+{
+    /* TODO: remove this when nl headers are updated */
+    static const unsigned NL80211_ATTR_MAX_INTERNAL = 256;
+private:
+    struct nl_msg *mMsg;
+    struct genlmsghdr *mHeader;
+    struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1];
+
+public:
+    WifiEvent(nl_msg *msg) {
+        mMsg = msg;
+        mHeader = NULL;
+        memset(mAttributes, 0, sizeof(mAttributes));
+    }
+    ~WifiEvent() {
+        /* don't destroy mMsg; it doesn't belong to us */
+    }
+
+    void log();
+
+    int parse();
+
+    genlmsghdr *header() {
+        return mHeader;
+    }
+
+    int get_cmd() {
+        return mHeader->cmd;
+    }
+
+    int get_vendor_id() {
+        return get_u32(NL80211_ATTR_VENDOR_ID);
+    }
+
+    int get_vendor_subcmd() {
+        return get_u32(NL80211_ATTR_VENDOR_SUBCMD);
+    }
+
+    void *get_vendor_data() {
+        return get_data(NL80211_ATTR_VENDOR_DATA);
+    }
+
+    int get_vendor_data_len() {
+        return get_len(NL80211_ATTR_VENDOR_DATA);
+    }
+
+    const char *get_cmdString();
+
+    nlattr ** attributes() {
+        return mAttributes;
+    }
+
+    nlattr *get_attribute(int attribute) {
+        return mAttributes[attribute];
+    }
+
+    uint8_t get_u8(int attribute) {
+        return mAttributes[attribute] ? nla_get_u8(mAttributes[attribute]) : 0;
+    }
+
+    uint16_t get_u16(int attribute) {
+        return mAttributes[attribute] ? nla_get_u16(mAttributes[attribute]) : 0;
+    }
+
+    uint32_t get_u32(int attribute) {
+        return mAttributes[attribute] ? nla_get_u32(mAttributes[attribute]) : 0;
+    }
+
+    uint64_t get_u64(int attribute) {
+        return mAttributes[attribute] ? nla_get_u64(mAttributes[attribute]) : 0;
+    }
+
+    int get_len(int attribute) {
+        return mAttributes[attribute] ? nla_len(mAttributes[attribute]) : 0;
+    }
+
+    void *get_data(int attribute) {
+        return mAttributes[attribute] ? nla_data(mAttributes[attribute]) : NULL;
+    }
+
+private:
+    WifiEvent(const WifiEvent&);        // hide copy constructor to prevent copies
+};
+
+class nl_iterator {
+    struct nlattr *pos;
+    int rem;
+public:
+    nl_iterator(struct nlattr *attr) {
+        pos = (struct nlattr *)nla_data(attr);
+        rem = nla_len(attr);
+    }
+    bool has_next() {
+        return nla_ok(pos, rem);
+    }
+    void next() {
+        pos = (struct nlattr *)nla_next(pos, &(rem));
+    }
+    struct nlattr *get() {
+        return pos;
+    }
+    uint16_t get_type() {
+        return pos->nla_type;
+    }
+    uint8_t get_u8() {
+        return nla_get_u8(pos);
+    }
+    uint16_t get_u16() {
+        return nla_get_u16(pos);
+    }
+    uint32_t get_u32() {
+        return nla_get_u32(pos);
+    }
+    uint64_t get_u64() {
+        return nla_get_u64(pos);
+    }
+    void* get_data() {
+        return nla_data(pos);
+    }
+    int get_len() {
+        return nla_len(pos);
+    }
+private:
+    nl_iterator(const nl_iterator&);    // hide copy constructor to prevent copies
+};
+
+class WifiRequest
+{
+private:
+    int mFamily;
+    int mIface;
+    struct nl_msg *mMsg;
+
+public:
+    WifiRequest(int family) {
+        mMsg = NULL;
+        mFamily = family;
+        mIface = -1;
+    }
+
+    WifiRequest(int family, int iface) {
+        mMsg = NULL;
+        mFamily = family;
+        mIface = iface;
+    }
+
+    ~WifiRequest() {
+        destroy();
+    }
+
+    void destroy() {
+        if (mMsg) {
+            nlmsg_free(mMsg);
+            mMsg = NULL;
+        }
+    }
+
+    nl_msg *getMessage() {
+        return mMsg;
+    }
+
+    /* Command assembly helpers */
+    int create(int family, uint8_t cmd, int flags, int hdrlen);
+    int create(uint8_t cmd) {
+        return create(mFamily, cmd, 0, 0);
+    }
+
+    int create(uint32_t id, int subcmd);
+
+    int put(int attribute, void *ptr, unsigned len) {
+        return nla_put(mMsg, attribute, len, ptr);
+    }
+    int put_u8(int attribute, uint8_t value) {
+        return nla_put(mMsg, attribute, sizeof(value), &value);
+    }
+    int put_u16(int attribute, uint16_t value) {
+        return nla_put(mMsg, attribute, sizeof(value), &value);
+    }
+    int put_u32(int attribute, uint32_t value) {
+        return nla_put(mMsg, attribute, sizeof(value), &value);
+    }
+    int put_u64(int attribute, uint64_t value) {
+        return nla_put(mMsg, attribute, sizeof(value), &value);
+    }
+    int put_string(int attribute, const char *value) {
+        return nla_put(mMsg, attribute, strlen(value) + 1, value);
+    }
+    int put_addr(int attribute, mac_addr value) {
+        return nla_put(mMsg, attribute, sizeof(mac_addr), value);
+    }
+
+    struct nlattr * attr_start(int attribute) {
+        return nla_nest_start(mMsg, attribute);
+    }
+    void attr_end(struct nlattr *attr) {
+        nla_nest_end(mMsg, attr);
+    }
+
+    int set_iface_id(int ifindex) {
+        return put_u32(NL80211_ATTR_IFINDEX, ifindex);
+    }
+private:
+    WifiRequest(const WifiRequest&);        // hide copy constructor to prevent copies
+
+};
+
+class WifiCommand
+{
+protected:
+    hal_info *mInfo;
+    WifiRequest mMsg;
+    Condition mCondition;
+    wifi_request_id mId;
+    interface_info *mIfaceInfo;
+    int mRefs;
+public:
+    WifiCommand(wifi_handle handle, wifi_request_id id)
+            : mMsg(getHalInfo(handle)->nl80211_family_id), mId(id), mRefs(1)
+    {
+        mIfaceInfo = NULL;
+        mInfo = getHalInfo(handle);
+        // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
+    }
+
+    WifiCommand(wifi_interface_handle iface, wifi_request_id id)
+            : mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id), mId(id), mRefs(1)
+    {
+        mIfaceInfo = getIfaceInfo(iface);
+        mInfo = getHalInfo(iface);
+        // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
+    }
+
+    virtual ~WifiCommand() {
+        // ALOGD("WifiCommand %p destroyed", this);
+    }
+
+    wifi_request_id id() {
+        return mId;
+    }
+
+    virtual void addRef() {
+        __sync_add_and_fetch(&mRefs, 1);
+        //int refs = __sync_add_and_fetch(&mRefs, 1);
+        // ALOGD("addRef: WifiCommand %p has %d references", this, refs);
+    }
+
+    virtual void releaseRef() {
+        int refs = __sync_sub_and_fetch(&mRefs, 1);
+        if (refs == 0) {
+            delete this;
+        } else {
+            // ALOGD("releaseRef: WifiCommand %p has %d references", this, refs);
+        }
+    }
+
+    virtual int create() {
+        /* by default there is no way to cancel */
+        //ALOGD("WifiCommand %p can't be created", this);
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    virtual int cancel() {
+        /* by default there is no way to cancel */
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
+    int requestResponse();
+    int requestEvent(int cmd);
+    int requestVendorEvent(uint32_t id, int subcmd);
+    int requestResponse(WifiRequest& request);
+
+protected:
+    wifi_handle wifiHandle() {
+        return getWifiHandle(mInfo);
+    }
+
+    wifi_interface_handle ifaceHandle() {
+        return getIfaceHandle(mIfaceInfo);
+    }
+
+    int familyId() {
+        return mInfo->nl80211_family_id;
+    }
+
+    int ifaceId() {
+        return mIfaceInfo->id;
+    }
+
+    /* Override this method to parse reply and dig out data; save it in the object */
+    virtual int handleResponse(WifiEvent& reply) {
+        ALOGI("skipping a response");
+        return NL_SKIP;
+    }
+
+    /* Override this method to parse event and dig out data; save it in the object */
+    virtual int handleEvent(WifiEvent& event) {
+        ALOGI("skipping an event");
+        return NL_SKIP;
+    }
+
+    int registerHandler(int cmd) {
+        return wifi_register_handler(wifiHandle(), cmd, &event_handler, this);
+    }
+
+    void unregisterHandler(int cmd) {
+        wifi_unregister_handler(wifiHandle(), cmd);
+    }
+
+    int registerVendorHandler(uint32_t id, int subcmd) {
+        return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
+    }
+
+    void unregisterVendorHandler(uint32_t id, int subcmd) {
+        wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
+    }
+
+private:
+    WifiCommand(const WifiCommand& );           // hide copy constructor to prevent copies
+
+    /* Event handling */
+    static int response_handler(struct nl_msg *msg, void *arg);
+
+    static int event_handler(struct nl_msg *msg, void *arg);
+
+    /* Other event handlers */
+    static int valid_handler(struct nl_msg *msg, void *arg);
+
+    static int ack_handler(struct nl_msg *msg, void *arg);
+
+    static int finish_handler(struct nl_msg *msg, void *arg);
+
+    static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
+};
+
+/* nl message processing macros (required to pass C++ type checks) */
+
+#define for_each_attr(pos, nla, rem) \
+    for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \
+        nla_ok(pos, rem); \
+        pos = (nlattr *)nla_next(pos, &(rem)))
+
diff --git a/gscan.cpp b/gscan.cpp
new file mode 100755
index 0000000..89d6dd6
--- /dev/null
+++ b/gscan.cpp
@@ -0,0 +1,1350 @@
+#include <stdint.h>
+#include <stddef.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"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+typedef enum {
+    EPNO_ATTRIBUTE_MINIMUM_5G_RSSI,
+    EPNO_ATTRIBUTE_MINIMUM_2G_RSSI,
+    EPNO_ATTRIBUTE_INITIAL_SCORE_MAX,
+    EPNO_ATTRIBUTE_CUR_CONN_BONUS,
+    EPNO_ATTRIBUTE_SAME_NETWORK_BONUS,
+    EPNO_ATTRIBUTE_SECURE_BONUS,
+    EPNO_ATTRIBUTE_5G_BONUS,
+    EPNO_ATTRIBUTE_SSID_NUM,
+    EPNO_ATTRIBUTE_SSID_LIST,
+    EPNO_ATTRIBUTE_SSID,
+    EPNO_ATTRIBUTE_SSID_LEN,
+    EPNO_ATTRIBUTE_FLAGS,
+    EPNO_ATTRIBUTE_AUTH,
+    EPNO_ATTRIBUTE_MAX
+} EPNO_ATTRIBUTE;
+
+typedef enum {
+    EPNO_ATTRIBUTE_HS_PARAM_LIST,
+    EPNO_ATTRIBUTE_HS_NUM,
+    EPNO_ATTRIBUTE_HS_ID,
+    EPNO_ATTRIBUTE_HS_REALM,
+    EPNO_ATTRIBUTE_HS_CONSORTIUM_IDS,
+    EPNO_ATTRIBUTE_HS_PLMN,
+    EPNO_ATTRIBUTE_HS_MAX
+} EPNO_HS_ATTRIBUTE;
+
+
+class GetCapabilitiesCommand : public WifiCommand
+{
+    wifi_gscan_capabilities *mCapabilities;
+public:
+    GetCapabilitiesCommand(wifi_interface_handle iface, wifi_gscan_capabilities *capabitlites)
+        : WifiCommand(iface, 0), mCapabilities(capabitlites)
+    {
+        memset(mCapabilities, 0, sizeof(*mCapabilities));
+    }
+
+    virtual int create() {
+        int ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_GET_CAPABILITIES);
+        if (ret < 0) {
+            ALOGE("NL message creation failed");
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGE("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        void *data = reply.get_vendor_data();
+        int len = reply.get_vendor_data_len();
+
+        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(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() {
+        int ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_GET_VALID_CHANNELS);
+        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) {
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGE("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int num_channels_to_copy = 0;
+
+        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 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();
+                /*ALOGD("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)
+{
+    GetChannelListCommand command(handle, channels, num_channels,
+                                        max_channels, band);
+    return (wifi_error) command.requestResponse();
+}
+/////////////////////////////////////////////////////////////////////////////
+
+/* 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++) {
+
+        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 result = request.create(GOOGLE_OUI, subcmd);
+    if (result < 0) {
+        return result;
+    }
+
+    return WIFI_SUCCESS;
+}
+
+class ScanCommand : public WifiCommand
+{
+    wifi_scan_cmd_params *mParams;
+    wifi_scan_result_handler mHandler;
+    static unsigned mGlobalFullScanBuckets;
+public:
+    ScanCommand(wifi_interface_handle iface, int id, wifi_scan_cmd_params *params,
+                wifi_scan_result_handler handler)
+        : WifiCommand(iface, id), mParams(params), mHandler(handler)
+    { }
+
+    int createSetupRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_ADD_GSCAN);
+        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_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;
+        }
+
+        result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_THRESHOLD_NUM_SCANS, mParams->report_threshold_num_scans);
+        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;
+            }
+
+            if (mParams->buckets[i].report_events == 0) {
+                mParams->buckets[i].report_events = REPORT_EVENTS_EACH_SCAN;
+            }
+            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;
+            }
+
+            result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_EXPONENT,
+                    mParams->buckets[i].base);
+            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_BUCKET_STEP_COUNT,
+                    mParams->buckets[i].step_count);
+            if (result < 0) {
+                return result;
+            }
+
+            if (mParams->buckets[i].num_channels) {
+                nlattr *channels = request.attr_start(GSCAN_ATTRIBUTE_BUCKET_CHANNELS);
+                for (int j = 0; j < mParams->buckets[i].num_channels; j++) {
+                    result = request.put_u32(j, 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 createStartRequest(WifiRequest& request) {
+        return createFeatureRequest(request, SLSI_NL80211_VENDOR_SUBCMD_ADD_GSCAN);
+    }
+
+    int createStopRequest(WifiRequest& request) {
+        return createFeatureRequest(request, SLSI_NL80211_VENDOR_SUBCMD_DEL_GSCAN);
+    }
+
+    int start() {
+        ALOGD("starting Gscan");
+        WifiRequest request(familyId(), ifaceId());
+        int result = createSetupRequest(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to create setup request; result = %d", result);
+            return result;
+        }
+
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
+
+        int nBuckets = 0;
+        for (int i = 0; i < mParams->num_buckets; i++) {
+            if (mParams->buckets[i].report_events & REPORT_EVENTS_FULL_RESULTS) {
+                nBuckets++;
+            }
+        }
+
+        if (nBuckets != 0) {
+           ALOGI("Full scan requested with nBuckets = %d", nBuckets);
+           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);
+            return result;
+        }
+
+
+        return result;
+    }
+
+    virtual int cancel() {
+        ALOGD("Stopping Gscan");
+
+        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) {
+        //event.log();
+
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        unsigned int len = event.get_vendor_data_len();
+        int event_id = event.get_vendor_subcmd();
+
+        if(event_id == GSCAN_EVENT_COMPLETE_SCAN) {
+            if (vendor_data == NULL || len != 4) {
+                ALOGE("Scan complete type not mentioned!");
+                return NL_SKIP;
+            }
+            wifi_scan_event evt_type;
+
+            evt_type = (wifi_scan_event) event.get_u32(NL80211_ATTR_VENDOR_DATA);
+            if(*mHandler.on_scan_event)
+                (*mHandler.on_scan_event)(id(), evt_type);
+        } else if(event_id == GSCAN_EVENT_FULL_SCAN_RESULTS) {
+            uint32_t bucket_scanned = 0;
+            wifi_scan_result *scan_result = NULL;
+            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_BUCKET_BIT) {
+                    bucket_scanned = it.get_u32();
+                } else if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS) {
+                    if (it.get_len() >= (int)sizeof(*scan_result))
+                        scan_result = (wifi_scan_result *)it.get_data();
+                }
+            }
+            if (scan_result) {
+                if(*mHandler.on_full_scan_result)
+                    (*mHandler.on_full_scan_result)(id(), scan_result, bucket_scanned);
+/*
+                    ALOGD("%-32s\t", scan_result->ssid);
+                    ALOGD("%02x:%02x:%02x:%02x:%02x:%02x ", scan_result->bssid[0], scan_result->bssid[1],
+                            scan_result->bssid[2], scan_result->bssid[3], scan_result->bssid[4], scan_result->bssid[5]);
+                    ALOGD("%d\t", scan_result->rssi);
+                    ALOGD("%d\t", scan_result->channel);
+                    ALOGD("%lld\t", scan_result->ts);
+                    ALOGD("%lld\t", scan_result->rtt);
+                    ALOGD("%lld\n", scan_result->rtt_sd);
+*/
+            }
+        }
+        return NL_SKIP;
+    }
+};
+
+unsigned ScanCommand::mGlobalFullScanBuckets = 0;
+
+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);
+
+    ScanCommand *cmd = new ScanCommand(iface, id, &params, handler);
+    wifi_register_cmd(handle, id, cmd);
+    return (wifi_error)cmd->start();
+}
+
+wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface)
+{
+    wifi_handle handle = getWifiHandle(iface);
+
+    if(id == -1) {
+        wifi_scan_result_handler handler;
+        wifi_scan_cmd_params dummy_params;
+        memset(&handler, 0, sizeof(handler));
+
+        ScanCommand *cmd = new ScanCommand(iface, id, &dummy_params, handler);
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+
+
+    WifiCommand *cmd = wifi_unregister_cmd(handle, id);
+    if (cmd) {
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+
+    return WIFI_ERROR_INVALID_ARGS;
+}
+
+class GetScanResultsCommand : public WifiCommand {
+    wifi_cached_scan_results *mScans;
+    int mMax;
+    int *mNum;
+    int mRetrieved;
+    byte mFlush;
+    int mCompleted;
+    static const int MAX_RESULTS = 320;
+    wifi_scan_result mScanResults[MAX_RESULTS];
+    int mNextScanResult;
+public:
+    GetScanResultsCommand(wifi_interface_handle iface, byte flush,
+            wifi_cached_scan_results *results, int max, int *num)
+        : WifiCommand(iface, -1), mScans(results), mMax(max), mNum(num),
+                mRetrieved(0), mFlush(flush), mCompleted(0)
+    {
+        memset(mScanResults,0,sizeof(mScanResults));
+        mNextScanResult = 0;
+    }
+
+    int createRequest(WifiRequest& request, int num, byte flush) {
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_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;
+        }
+
+        request.attr_end(data);
+        return WIFI_SUCCESS;
+    }
+
+    int execute() {
+        WifiRequest request(familyId(), ifaceId());
+
+        for (int i = 0; i < 10 && mRetrieved < mMax; i++) {
+            int result = createRequest(request, (mMax - mRetrieved), 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();
+        }
+
+        ALOGE("GetScanResults read %d results", mRetrieved);
+        *mNum = mRetrieved;
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGE("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();
+
+        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();
+                //ALOGD("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;
+                for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
+                    if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_ID) {
+                        scan_id = it2.get_u32();
+                        //ALOGD("retrieved scan_id : 0x%0x", scan_id);
+                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_FLAGS) {
+                        flags = it2.get_u8();
+                        //ALOGD("retrieved scan_flags : 0x%0x", flags);
+                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) {
+                        num = it2.get_u32();
+                        //ALOGD("retrieved num_results: %d", num);
+                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS) {
+                        if (mRetrieved >= mMax) {
+                            ALOGW("Stored %d scans, ignoring excess results", mRetrieved);
+                            break;
+                        }
+                        num = it2.get_len() / sizeof(wifi_scan_result);
+                        num = min(MAX_RESULTS - mNextScanResult, num);
+                        num = min((int)MAX_AP_CACHE_PER_SCAN, num);
+                        memcpy(mScanResults + mNextScanResult, it2.get_data(),
+                                sizeof(wifi_scan_result) * num);
+                        /*
+                        wifi_scan_result *results = (wifi_scan_result *)it2.get_data();
+                        for (int i = 0; i < num; i++) {
+                            wifi_scan_result *result = results + i;
+                            ALOGD("%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;
+                        //ALOGD("Setting result of scan_id : 0x%0x", mScans[mRetrieved].scan_id);
+                        memcpy(mScans[mRetrieved].results,
+                                &(mScanResults[mNextScanResult]), num * sizeof(wifi_scan_result));
+                        mNextScanResult += num;
+                        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());
+            }
+        }
+
+        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) {
+    GetScanResultsCommand *cmd = new GetScanResultsCommand(iface, flush, results, max, num);
+    return (wifi_error)cmd->execute();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+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(handle, id), mParams(params), mHandler(handler)
+    {
+            memset(mResults, 0, sizeof(mResults));
+    }
+
+    int createSetupRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_SET_BSSID_HOTLIST);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        result = request.put_u32(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, mParams.lost_ap_sample_size);
+        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, SLSI_NL80211_VENDOR_SUBCMD_RESET_BSSID_HOTLIST);
+        if (result < 0) {
+            return result;
+        }
+
+        return result;
+    }
+
+    int start() {
+        WifiRequest request(familyId(), ifaceId());
+        int result = createSetupRequest(request);
+        if (result < 0) {
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGE("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;
+        }
+
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
+
+        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;
+        }
+
+        return result;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& 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) {
+            ALOGE("No scan results found");
+            return NL_SKIP;
+        }
+
+
+        int num = len / sizeof(wifi_scan_result);
+        num = min(MAX_RESULTS, num);
+        memcpy(mResults, event.get_vendor_data(), num * sizeof(wifi_scan_result));
+
+        if (event_id == GSCAN_EVENT_HOTLIST_RESULTS_FOUND) {
+            ALOGD("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) {
+            ALOGD("LOST %d hotlist APs", num);
+            if (*mHandler.on_hotlist_ap_lost)
+                (*mHandler.on_hotlist_ap_lost)(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);
+    wifi_register_cmd(handle, id, cmd);
+    return (wifi_error)cmd->start();
+}
+
+wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface)
+{
+    wifi_handle handle = getWifiHandle(iface);
+
+    WifiCommand *cmd = wifi_unregister_cmd(handle, id);
+    if (cmd) {
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+
+    return WIFI_ERROR_INVALID_ARGS;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+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(handle, id), mParams(params), mHandler(handler)
+    {
+        memset(mResultsBuffer,0,sizeof(mResultsBuffer));
+        memset(mResults,0,sizeof(mResults));
+    }
+
+    int createSetupRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_SET_SIGNIFICANT_CHANGE);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        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;
+        }
+
+        struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS);
+
+        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, SLSI_NL80211_VENDOR_SUBCMD_RESET_SIGNIFICANT_CHANGE);
+        if (result < 0) {
+            return result;
+        }
+
+        return result;
+    }
+
+    int start() {
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = createSetupRequest(request);
+        if (result < 0) {
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGE("failed to set significant wifi change %d", result);
+            return result;
+        }
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS);
+
+        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;
+        }
+
+        return result;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = event.get_vendor_data_len();
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("No scan results found");
+            return NL_SKIP;
+        }
+
+        typedef struct {
+            uint16_t channel;
+            mac_addr bssid;
+            int16_t 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;
+            /* Driver sends N samples and the rest 8-N are filled 0x7FFF
+             * N = no of rssi samples to average sent in significant change request. */
+            int num_rssi = 0;
+            for (int j = 0; j < 8; j++) {
+                if (ci[i].rssi_history[j] == 0x7FFF) {
+                    num_rssi = j;
+                    break;
+                }
+                mResultsBuffer[i].rssi[j] = (int) ci[i].rssi_history[j];
+            }
+            mResultsBuffer[i].num_rssi = num_rssi;
+            mResults[i] = reinterpret_cast<wifi_significant_change_result *>(&(mResultsBuffer[i]));
+        }
+
+        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);
+    wifi_register_cmd(handle, id, cmd);
+    return (wifi_error)cmd->start();
+}
+
+wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface)
+{
+    wifi_handle handle = getWifiHandle(iface);
+
+    WifiCommand *cmd = wifi_unregister_cmd(handle, id);
+    if (cmd) {
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+
+    return WIFI_ERROR_INVALID_ARGS;
+}
+
+class ePNOCommand : public WifiCommand
+{
+private:
+    wifi_epno_params  *epno_params;
+    wifi_epno_handler mHandler;
+    wifi_scan_result  mResults;
+public:
+    ePNOCommand(wifi_interface_handle handle, int id,
+            wifi_epno_params *params, wifi_epno_handler handler)
+        : WifiCommand(handle, id), mHandler(handler)
+    {
+        epno_params = params;
+        memset(&mResults,0,sizeof(wifi_scan_result));
+    }
+
+    int createSetupRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_SET_EPNO_LIST);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (epno_params == NULL) {
+            result = request.put_u8(EPNO_ATTRIBUTE_SSID_NUM, 0);
+            if (result < 0) {
+                return result;
+            }
+            request.attr_end(data);
+            return result;
+        }
+        result = request.put_u16(EPNO_ATTRIBUTE_MINIMUM_5G_RSSI, epno_params->min5GHz_rssi);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(EPNO_ATTRIBUTE_MINIMUM_2G_RSSI, epno_params->min24GHz_rssi);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(EPNO_ATTRIBUTE_INITIAL_SCORE_MAX, epno_params->initial_score_max);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(EPNO_ATTRIBUTE_CUR_CONN_BONUS, epno_params->current_connection_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(EPNO_ATTRIBUTE_SAME_NETWORK_BONUS, epno_params->same_network_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(EPNO_ATTRIBUTE_SECURE_BONUS, epno_params->secure_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(EPNO_ATTRIBUTE_5G_BONUS, epno_params->band5GHz_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(EPNO_ATTRIBUTE_SSID_NUM, epno_params->num_networks);
+        if (result < 0) {
+            return result;
+        }
+
+       ALOGI("ePNO [min5GHz_rssi:%d min24GHz_rssi:%d initial_score_max:%d current_connection_bonus:%d same_network_bonus:%d secure_bonus:%d band5GHz_bonus:%d num_networks:%d]",
+         epno_params->min5GHz_rssi,
+         epno_params->min24GHz_rssi,
+         epno_params->initial_score_max,
+         epno_params->current_connection_bonus,
+         epno_params->same_network_bonus,
+         epno_params->secure_bonus,
+         epno_params->band5GHz_bonus,
+         epno_params->num_networks);
+
+        struct nlattr * attr = request.attr_start(EPNO_ATTRIBUTE_SSID_LIST);
+        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_u16(EPNO_ATTRIBUTE_FLAGS, epno_params->networks[i].flags);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u8(EPNO_ATTRIBUTE_AUTH, epno_params->networks[i].auth_bit_field);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u8(EPNO_ATTRIBUTE_SSID_LEN, strlen(epno_params->networks[i].ssid));
+            if (result < 0) {
+                return result;
+            }
+            result = request.put(EPNO_ATTRIBUTE_SSID, epno_params->networks[i].ssid, strlen(epno_params->networks[i].ssid));
+            if (result < 0) {
+                return result;
+            }
+            request.attr_end(attr2);
+        }
+
+        request.attr_end(attr);
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        ALOGI("ePNO num_network=%d", epno_params ? epno_params->num_networks : 0);
+        WifiRequest request(familyId(), ifaceId());
+        int result = createSetupRequest(request);
+        if (result < 0) {
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGI("Failed: ePNO setup request, result = %d", result);
+            unregisterVendorHandler(GOOGLE_OUI, WIFI_EPNO_EVENT);
+            return result;
+        }
+
+        if (epno_params) {
+            registerVendorHandler(GOOGLE_OUI, WIFI_EPNO_EVENT);
+        }
+        return result;
+    }
+
+    virtual int cancel() {
+        /* unregister event handler */
+        unregisterVendorHandler(GOOGLE_OUI, WIFI_EPNO_EVENT);
+        return 0;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        // 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;
+        }
+
+
+        mResults = *(wifi_scan_result *) event.get_vendor_data();
+        if (*mHandler.on_network_found)
+            (*mHandler.on_network_found)(id(), 1, &mResults);
+        return NL_SKIP;
+    }
+};
+
+wifi_error wifi_set_epno_list(wifi_request_id id,
+                              wifi_interface_handle iface,
+                              const wifi_epno_params *epno_params,
+                              wifi_epno_handler handler)
+{
+    wifi_handle handle = getWifiHandle(iface);
+    ePNOCommand *cmd = new ePNOCommand(iface, id, (wifi_epno_params *)epno_params, handler);
+    wifi_register_cmd(handle, id, cmd);
+    wifi_error result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+    }
+    return result;
+}
+
+wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface)
+{
+    wifi_handle handle = getWifiHandle(iface);
+    wifi_epno_handler handler;
+
+    handler.on_network_found = NULL;
+    ePNOCommand *cmd = new ePNOCommand(iface, id, NULL, handler);
+    wifi_register_cmd(handle, id, cmd);
+    wifi_error result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+    }
+    return result;
+}
+
+class HsListCommand : public WifiCommand
+{
+    int num_hs;
+    wifi_passpoint_network *mNetworks;
+    wifi_passpoint_event_handler mHandler;
+public:
+    HsListCommand(wifi_request_id id, wifi_interface_handle iface,
+        int num, wifi_passpoint_network *hs_list, wifi_passpoint_event_handler handler)
+        : WifiCommand(iface, id), num_hs(num), mNetworks(hs_list),
+            mHandler(handler)
+    {
+    }
+
+    HsListCommand(wifi_request_id id, wifi_interface_handle iface,
+        int num)
+        : WifiCommand(iface, id), num_hs(num), mNetworks(NULL)
+    {
+        mHandler.on_passpoint_network_found = NULL;
+    }
+
+    int createRequest(WifiRequest& request, int val) {
+        int result;
+
+        if (val) {
+            result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_SET_HS_LIST);
+            result = request.put_u32(EPNO_ATTRIBUTE_HS_NUM, num_hs);
+            if (result < 0) {
+                return result;
+            }
+            nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+            struct nlattr * attr = request.attr_start(EPNO_ATTRIBUTE_HS_PARAM_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(EPNO_ATTRIBUTE_HS_ID, mNetworks[i].id);
+                if (result < 0) {
+                    return result;
+                }
+                result = request.put(EPNO_ATTRIBUTE_HS_REALM, mNetworks[i].realm, 256);
+                if (result < 0) {
+                    return result;
+                }
+                result = request.put(EPNO_ATTRIBUTE_HS_CONSORTIUM_IDS, mNetworks[i].roamingConsortiumIds, 128);
+                if (result < 0) {
+                    return result;
+                }
+                result = request.put(EPNO_ATTRIBUTE_HS_PLMN, mNetworks[i].plmn, 3);
+                if (result < 0) {
+                    return result;
+                }
+                request.attr_end(attr2);
+            }
+            request.attr_end(attr);
+            request.attr_end(data);
+        }else {
+            result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_RESET_HS_LIST);
+            if (result < 0) {
+                return result;
+            }
+        }
+
+        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, WIFI_HOTSPOT_MATCH);
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to set ANQPO networks; result = %d", result);
+            unregisterVendorHandler(GOOGLE_OUI, WIFI_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, WIFI_HOTSPOT_MATCH);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& 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)) {
+            ALOGE("ERROR: No scan results found");
+            return NL_SKIP;
+        }
+
+        wifi_scan_result *result = (wifi_scan_result *)event.get_vendor_data();
+        byte *anqp = (byte *)result + offsetof(wifi_scan_result, ie_data) + result->ie_length;
+        int networkId = *(int *)anqp;
+        anqp += sizeof(int);
+        int anqp_len = *(u16 *)anqp;
+        anqp += sizeof(u16);
+
+        if(*mHandler.on_passpoint_network_found)
+            (*mHandler.on_passpoint_network_found)(id(), networkId, result, anqp_len, anqp);
+
+        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);
+    HsListCommand *cmd = new HsListCommand(id, iface, num, networks, handler);
+
+    wifi_register_cmd(handle, id, cmd);
+    wifi_error result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+    }
+    return result;
+}
+
+wifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle iface)
+{
+    wifi_handle   handle = getWifiHandle(iface);
+    wifi_error    result;
+    HsListCommand *cmd = (HsListCommand *)(wifi_get_cmd(handle, id));
+
+    if (cmd == NULL) {
+        cmd = new HsListCommand(id, iface, 0);
+        wifi_register_cmd(handle, id, cmd);
+    }
+    result = (wifi_error)cmd->cancel();
+    wifi_unregister_cmd(handle, id);
+    return result;
+}
diff --git a/link_layer_stats.cpp b/link_layer_stats.cpp
new file mode 100755
index 0000000..bfdeac8
--- /dev/null
+++ b/link_layer_stats.cpp
@@ -0,0 +1,274 @@
+#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"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+typedef enum {
+
+    LSTATS_ATTRIBUTE_SET_MPDU_SIZE_THRESHOLD = 1,
+    LSTATS_ATTRIBUTE_SET_AGGR_STATISTICS_GATHERING,
+    LSTATS_ATTRIBUTE_CLEAR_STOP_REQUEST_MASK,
+    LSTATS_ATTRIBUTE_CLEAR_STOP_REQUEST,
+
+    LSTATS_ATTRIBUTE_MAX
+
+} LSTATS_ATTRIBUTE;
+
+class LinkLayerStatsCommand : public WifiCommand
+{
+    wifi_link_layer_params mParams;
+    u32 mStatsClearReqMask;
+    u32 *mStatsClearRspMask;
+    u8 mStopReq;
+    u8 *mStopRsp;
+public:
+    LinkLayerStatsCommand(wifi_interface_handle handle, wifi_link_layer_params params)
+        : WifiCommand(handle, 0), mParams(params)
+    {
+        mStatsClearReqMask = 0;
+        mStatsClearRspMask = 0;
+        mStopReq = 0 ;
+        mStopRsp = NULL;
+
+    }
+
+    LinkLayerStatsCommand(wifi_interface_handle handle,
+        u32 stats_clear_req_mask, u32 *stats_clear_rsp_mask, u8 stop_req, u8 *stop_rsp)
+        : WifiCommand(handle, 0), mStatsClearReqMask(stats_clear_req_mask), mStatsClearRspMask(stats_clear_rsp_mask),
+        mStopReq(stop_req), mStopRsp(stop_rsp)
+    {
+        memset(&mParams,0,sizeof(wifi_link_layer_params));
+    }
+
+    int createSetRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_LLS_SET_INFO);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        result = request.put_u32(LSTATS_ATTRIBUTE_SET_MPDU_SIZE_THRESHOLD, mParams.mpdu_size_threshold);
+        if (result < 0) {
+            return result;
+        }
+
+        result = request.put_u32(LSTATS_ATTRIBUTE_SET_AGGR_STATISTICS_GATHERING, mParams.aggressive_statistics_gathering);
+        if (result < 0) {
+            return result;
+        }
+        request.attr_end(data);
+        return result;
+    }
+
+    int createClearRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_LLS_CLEAR_INFO);
+        if (result < 0) {
+            return result;
+        }
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        result = request.put_u32(LSTATS_ATTRIBUTE_CLEAR_STOP_REQUEST_MASK, mStatsClearReqMask);
+        if (result < 0) {
+            return result;
+        }
+
+        result = request.put_u32(LSTATS_ATTRIBUTE_CLEAR_STOP_REQUEST, mStopReq);
+        if (result < 0) {
+            return result;
+        }
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        ALOGD("Starting Link Layer Statistics measurement (%d, %d)", mParams.mpdu_size_threshold, mParams.aggressive_statistics_gathering);
+        WifiRequest request(familyId(), ifaceId());
+        int result = createSetRequest(request);
+        if (result < 0) {
+            ALOGE("failed to set Link Layer Statistics (result:%d)", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGE("failed to Set Link Layer Statistics (result:%d)", result);
+            return result;
+        }
+
+        return result;
+    }
+
+    virtual int clear() {
+        ALOGD("Clearing Link Layer Statistics (%d, %d)", mStatsClearReqMask, mStopReq);
+        WifiRequest request(familyId(), ifaceId());
+        int result = createClearRequest(request);
+        if (result < 0) {
+            ALOGE("failed to clear Link Layer Statistics (result:%d)", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGE("failed to clear Link Layer Statistics (result:%d)", result);
+            return result;
+        }
+
+        return result;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+};
+
+
+wifi_error wifi_set_link_stats(wifi_interface_handle iface, wifi_link_layer_params params)
+{
+    LinkLayerStatsCommand *command = new LinkLayerStatsCommand(iface, params);
+    wifi_error result = (wifi_error)command->start();
+    if (result != WIFI_SUCCESS) {
+        ALOGE("failed to Set link layer stats (result:%d)", result);
+    }
+    return result;
+}
+
+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)
+{
+    LinkLayerStatsCommand *command = new LinkLayerStatsCommand(iface, stats_clear_req_mask, stats_clear_rsp_mask, stop_req, stop_rsp);
+    wifi_error result = (wifi_error)command->clear();
+    if (result != WIFI_SUCCESS) {
+        ALOGE("failed to Clear link layer stats (result:%d)", result);
+        *stats_clear_rsp_mask = 0;
+        *stop_rsp = 0;
+    } else {
+        *stats_clear_rsp_mask = stats_clear_req_mask;
+        *stop_rsp = stop_req;
+    }
+    return result;
+}
+
+
+class GetLinkStatsCommand : public WifiCommand
+{
+    wifi_stats_result_handler mHandler;
+    wifi_interface_handle iface;
+public:
+    GetLinkStatsCommand(wifi_interface_handle iface, wifi_stats_result_handler handler)
+        : WifiCommand(iface, 0), mHandler(handler)
+    {
+        this->iface = iface;
+    }
+
+    virtual int create() {
+        int ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_LLS_GET_INFO);
+        if (ret < 0) {
+            ALOGE("Failed to create %x - %d", SLSI_NL80211_VENDOR_SUBCMD_LLS_GET_INFO, ret);
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+        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();
+        u8 *data = (u8 *)reply.get_vendor_data();
+        int num_radios = 0, i = 0;
+        num_radios = data[0];
+        data += sizeof(data[0]);
+
+        // assuming max peers is 16
+        wifi_iface_stat *iface_stat = (wifi_iface_stat *) malloc(sizeof(wifi_iface_stat) + sizeof(wifi_peer_info) * 16);
+        if (!iface_stat) {
+            ALOGE("Memory alloc failed for iface_stat in response handler!!!");
+            return NL_SKIP;
+        }
+
+        // max channel is 39 (14 2.4GHz and 25 5GHz)
+        wifi_radio_stat *radio_stat = (wifi_radio_stat *) malloc((num_radios * sizeof(wifi_radio_stat)) + sizeof(wifi_channel_stat) * 39);
+        wifi_radio_stat *radio_stat2;
+        radio_stat2 = radio_stat;
+        if (!radio_stat) {
+            ALOGE("Memory alloc failed for radio_stat in response handler!!!");
+            free(iface_stat);
+            return NL_SKIP;
+        }
+
+        /* Data sent from driver does not contain num_tx_levels and tx_time per level. So copy
+         * radio data in two parts - 1st part until num_tx_levels and 2nd part from rx_time.
+         * channel data is copied separately
+         */
+        int radio_data_len1,radio_data_len2;
+        radio_data_len1 = (u8 *)&(radio_stat->num_tx_levels) - (u8*)radio_stat;
+        radio_data_len2 = (u8 *)(radio_stat->channels) - (u8*)&(radio_stat->rx_time);
+
+        //kernel is 64 bit. if userspace is 64 bit, typecastting buffer works else, make corrections
+        if (sizeof(iface_stat->iface) == 8) {
+            memcpy(iface_stat, data, sizeof(wifi_iface_stat) + sizeof(wifi_peer_info) * ((wifi_iface_stat *)data)->num_peers);
+            data += sizeof(wifi_iface_stat) + sizeof(wifi_peer_info) * ((wifi_iface_stat *)data)->num_peers;
+        } else {
+            /* for 64 bit kernel ad 32 bit user space, there is 4 byte extra at the begining and another 4 byte pad after 80 bytes
+             * so remove first 4 and 81-84 bytes from NL buffer.*/
+            data += 4;
+            memcpy(iface_stat, data, 80);
+            data += 80 + 4; //for allignment skip 4 bytes
+            memcpy(((u8 *)iface_stat) + 80, data, sizeof(wifi_iface_stat) - 80);
+            data += sizeof(wifi_iface_stat) - 80;
+            memcpy(iface_stat->peer_info, data, sizeof(wifi_peer_info) * iface_stat->num_peers);
+            data += sizeof(wifi_peer_info) * iface_stat->num_peers;
+        }
+        for (i = 0; i < num_radios; i++) {
+            memcpy(radio_stat2, data, radio_data_len1);
+            data += radio_data_len1;
+            memcpy(&radio_stat2->rx_time, data, radio_data_len2);
+            data += radio_data_len2;
+            memcpy(radio_stat2->channels, data, sizeof(wifi_channel_stat)* radio_stat2->num_channels);
+            radio_stat2->num_tx_levels = 0;
+            radio_stat2->tx_time_per_levels = NULL;
+            data += sizeof(wifi_channel_stat)* radio_stat2->num_channels;
+            radio_stat2=(wifi_radio_stat *) ((u8 *)radio_stat2+ sizeof(wifi_radio_stat) +
+                        (sizeof(wifi_channel_stat) * radio_stat2->num_channels ));
+        }
+        iface_stat->iface = iface;
+        (*mHandler.on_link_stats_results)(id, iface_stat, num_radios, radio_stat);
+        free(iface_stat);
+        free(radio_stat);
+        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();
+}
+
+
diff --git a/roam.cpp b/roam.cpp
new file mode 100755
index 0000000..0993ec7
--- /dev/null
+++ b/roam.cpp
@@ -0,0 +1,224 @@
+#include <stdint.h>
+#include <stddef.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"
+
+#define REQUEST_ID_MAX 1000
+#define get_requestid() ((arc4random()%REQUEST_ID_MAX) + 1)
+
+enum roam_attributes {
+    SLSI_ATTR_ROAM_CAPABILITY_BLACKLIST_SIZE,
+    SLSI_ATTR_ROAM_CAPABILITY_WHITELIST_SIZE,
+    SLSI_ATTR_ROAM_STATE
+};
+
+class BssidBlacklistCommand : public WifiCommand
+{
+private:
+    wifi_bssid_params *mParams;
+public:
+    BssidBlacklistCommand(wifi_interface_handle handle, int id,
+            wifi_bssid_params *params)
+        : WifiCommand(handle, id), mParams(params)
+    { }
+     int createRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_SET_BSSID_BLACKLIST);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_BSSID, mParams->num_bssid);
+        if (result < 0) {
+            return result;
+        }
+
+        for (int i = 0; i < mParams->num_bssid; i++) {
+            result = request.put_addr(GSCAN_ATTRIBUTE_BLACKLIST_BSSID, mParams->bssids[i]);
+            if (result < 0) {
+                return result;
+            }
+        }
+        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) {
+            ALOGE("Failed to execute bssid blacklist request, result = %d", result);
+            return result;
+        }
+
+        return result;
+    }
+
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+};
+
+wifi_error wifi_set_bssid_blacklist(wifi_request_id id, wifi_interface_handle iface,
+        wifi_bssid_params params)
+{
+    BssidBlacklistCommand *cmd = new BssidBlacklistCommand(iface, id, &params);
+    wifi_error result = (wifi_error)cmd->start();
+    //release the reference of command as well
+    cmd->releaseRef();
+    return result;
+}
+
+
+class RoamingCapabilitiesCommand : public WifiCommand
+{
+private:
+    wifi_roaming_capabilities *mCaps;
+
+public:
+    RoamingCapabilitiesCommand(wifi_interface_handle handle, wifi_roaming_capabilities *caps)
+        : WifiCommand(handle, 0) {
+        mCaps = caps;
+    }
+
+    virtual int create() {
+        int ret;
+
+        ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_GET_ROAMING_CAPABILITIES);
+        if (ret < 0) {
+             ALOGE("Can't create message to send to driver - %d", ret);
+             return ret;
+        }
+        return WIFI_SUCCESS;
+
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignore reply; 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();
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("vendor data in GetFeatureSetCommand missing!!");
+            return NL_SKIP;
+        }
+
+        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+            switch(it.get_type()) {
+                case SLSI_ATTR_ROAM_CAPABILITY_BLACKLIST_SIZE:
+                    mCaps->max_blacklist_size = it.get_u32();
+                    break;
+                case SLSI_ATTR_ROAM_CAPABILITY_WHITELIST_SIZE:
+                    mCaps->max_whitelist_size = it.get_u32();
+                    break;
+                default :
+                    break;
+            }
+        }
+        return NL_OK;
+    }
+};
+
+wifi_error wifi_get_roaming_capabilities(wifi_interface_handle handle,
+                                         wifi_roaming_capabilities *caps)
+{
+    RoamingCapabilitiesCommand cmd(handle, caps);
+    return (wifi_error) cmd.requestResponse();
+}
+
+class RoamingStateCommand : public WifiCommand
+{
+private:
+    fw_roaming_state_t mRoamingState;
+
+public:
+    RoamingStateCommand(wifi_interface_handle handle, fw_roaming_state_t roaming_state)
+        : WifiCommand(handle, 0) {
+        mRoamingState = roaming_state;
+    }
+
+    virtual int create() {
+        int ret;
+        ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_SET_ROAMING_STATE);
+        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(SLSI_ATTR_ROAM_STATE, mRoamingState);
+        if (ret < 0) {
+            return ret;
+        }
+        mMsg.attr_end(data);
+        return WIFI_SUCCESS;
+    }
+};
+
+wifi_error wifi_enable_firmware_roaming(wifi_interface_handle handle, fw_roaming_state_t state) {
+    RoamingStateCommand cmd(handle, state);
+    wifi_error ret = (wifi_error) cmd.requestResponse();
+    return ret;
+}
+
+wifi_error wifi_configure_roaming(wifi_interface_handle iface, wifi_roaming_config *roaming_config)
+{
+    wifi_error ret;
+    int requestId;
+    wifi_bssid_params bssid_params;
+
+    if (!roaming_config) {
+        ALOGE("%s: Invalid Buffer provided. Exit", __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+   }
+
+    /* Generate request id randomly*/
+   requestId = get_requestid();
+   bssid_params.num_bssid = roaming_config->num_blacklist_bssid;
+
+   memcpy(bssid_params.bssids, roaming_config->blacklist_bssid,
+           (bssid_params.num_bssid * sizeof(mac_addr)));
+
+    ret = wifi_set_bssid_blacklist(requestId, iface, bssid_params);
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: Failed to configure blacklist bssids", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    return ret;
+}
diff --git a/rtt.cpp b/rtt.cpp
new file mode 100755
index 0000000..2c9114d
--- /dev/null
+++ b/rtt.cpp
@@ -0,0 +1,632 @@
+#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 <string>
+#include "nl80211_copy.h"
+
+#include "sync.h"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+using namespace std;
+
+typedef enum {
+    SLSI_RTT_ATTRIBUTE_TARGET_CNT = 0,
+    SLSI_RTT_ATTRIBUTE_TARGET_INFO,
+    SLSI_RTT_ATTRIBUTE_TARGET_MAC,
+    SLSI_RTT_ATTRIBUTE_TARGET_TYPE,
+    SLSI_RTT_ATTRIBUTE_TARGET_PEER,
+    SLSI_RTT_ATTRIBUTE_TARGET_CHAN_WIDTH,
+    SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ,
+    SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ0,
+    SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ1,
+    SLSI_RTT_ATTRIBUTE_TARGET_PERIOD,
+    SLSI_RTT_ATTRIBUTE_TARGET_NUM_BURST,
+    SLSI_RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
+    SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
+    SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
+    SLSI_RTT_ATTRIBUTE_TARGET_LCI,
+    SLSI_RTT_ATTRIBUTE_TARGET_LCR,
+    SLSI_RTT_ATTRIBUTE_TARGET_BURST_DURATION,
+    SLSI_RTT_ATTRIBUTE_TARGET_PREAMBLE,
+    SLSI_RTT_ATTRIBUTE_TARGET_BW,
+    SLSI_RTT_ATTRIBUTE_RESULTS_COMPLETE = 30,
+    SLSI_RTT_ATTRIBUTE_RESULTS_PER_TARGET,
+    SLSI_RTT_ATTRIBUTE_RESULT_CNT,
+    SLSI_RTT_ATTRIBUTE_RESULT,
+    SLSI_RTT_ATTRIBUTE_TARGET_ID
+} SLSI_RTT_ATTRIBUTE;
+
+enum slsi_rtt_event_attributes {
+	SLSI_RTT_EVENT_ATTR_ADDR     = 0,
+	SLSI_RTT_EVENT_ATTR_BURST_NUM,
+	SLSI_RTT_EVENT_ATTR_MEASUREMENT_NUM,
+	SLSI_RTT_EVENT_ATTR_SUCCESS_NUM,
+	SLSI_RTT_EVENT_ATTR_NUM_PER_BURST_PEER,
+	SLSI_RTT_EVENT_ATTR_STATUS,
+	SLSI_RTT_EVENT_ATTR_RETRY_AFTER_DURATION,
+	SLSI_RTT_EVENT_ATTR_TYPE,
+	SLSI_RTT_EVENT_ATTR_RSSI,
+	SLSI_RTT_EVENT_ATTR_RSSI_SPREAD,
+	SLSI_RTT_EVENT_ATTR_TX_PREAMBLE,
+	SLSI_RTT_EVENT_ATTR_TX_NSS,
+	SLSI_RTT_EVENT_ATTR_TX_BW,
+	SLSI_RTT_EVENT_ATTR_TX_MCS,
+	SLSI_RTT_EVENT_ATTR_TX_RATE,
+	SLSI_RTT_EVENT_ATTR_RX_PREAMBLE,
+	SLSI_RTT_EVENT_ATTR_RX_NSS,
+	SLSI_RTT_EVENT_ATTR_RX_BW,
+	SLSI_RTT_EVENT_ATTR_RX_MCS,
+	SLSI_RTT_EVENT_ATTR_RX_RATE,
+	SLSI_RTT_EVENT_ATTR_RTT,
+	SLSI_RTT_EVENT_ATTR_RTT_SD,
+	SLSI_RTT_EVENT_ATTR_RTT_SPREAD,
+	SLSI_RTT_EVENT_ATTR_DISTANCE_MM,
+	SLSI_RTT_EVENT_ATTR_DISTANCE_SD_MM,
+	SLSI_RTT_EVENT_ATTR_DISTANCE_SPREAD_MM,
+	SLSI_RTT_EVENT_ATTR_TIMESTAMP_US,
+	SLSI_RTT_EVENT_ATTR_BURST_DURATION_MSN,
+	SLSI_RTT_EVENT_ATTR_NEGOTIATED_BURST_NUM,
+	SLSI_RTT_EVENT_ATTR_LCI,
+	SLSI_RTT_EVENT_ATTR_LCR
+};
+
+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;
+typedef struct strmap_entry {
+    int			id;
+    string		text;
+} strmap_entry_t;
+
+static const strmap_entry_t err_info[] = {
+    {RTT_STATUS_SUCCESS, string("Success")},
+    {RTT_STATUS_FAILURE, string("Failure")},
+    {RTT_STATUS_FAIL_NO_RSP, string("No reponse")},
+    {RTT_STATUS_FAIL_INVALID_TS, string("Invalid Timestamp")},
+    {RTT_STATUS_FAIL_PROTOCOL, string("Protocol error")},
+    {RTT_STATUS_FAIL_REJECTED, string("Rejected")},
+    {RTT_STATUS_FAIL_NOT_SCHEDULED_YET, string("not scheduled")},
+    {RTT_STATUS_FAIL_SCHEDULE,  string("schedule failed")},
+    {RTT_STATUS_FAIL_TM_TIMEOUT, string("timeout")},
+    {RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, string("AP is on difference channel")},
+    {RTT_STATUS_FAIL_NO_CAPABILITY, string("no capability")},
+    {RTT_STATUS_FAIL_BUSY_TRY_LATER, string("busy and try later")},
+    {RTT_STATUS_ABORTED, string("aborted")}
+};
+/*static const string 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 RttCommand : public WifiCommand
+{
+    int rtt_id;
+    unsigned numTargetDevice;
+    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(iface, id), rtt_id(id), numTargetDevice(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(iface, id), rtt_id(id), rttParams(NULL)
+    {
+        rttHandler.on_rtt_results = NULL;
+        memset(rttResults, 0, sizeof(rttResults));
+        currentIdx = 0;
+        mCompleted = 0;
+        totalCnt = 0;
+        numTargetDevice = 0;
+    }
+ int createSetupRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_START);
+        if (result < 0) {
+            return result;
+        }
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+	result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_ID, rtt_id);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_CNT, numTargetDevice);
+		ALOGI("numTargetDevice %d\n",numTargetDevice);
+        if (result < 0) {
+            return result;
+        }
+        nlattr *rtt_config = request.attr_start(SLSI_RTT_ATTRIBUTE_TARGET_INFO);
+        for (unsigned i = 0; i < numTargetDevice; i++) {
+            nlattr *attr2 = request.attr_start(i);
+
+            result = request.put_addr(SLSI_RTT_ATTRIBUTE_TARGET_MAC, rttParams[i].addr);
+			ALOGI("mac_addr %p\n",rttParams[i].addr);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_TYPE, rttParams[i].type);
+			ALOGI("\trtt_type %d\n",rttParams[i].type);
+            if (result < 0) {
+                return result;
+            }
+
+	     result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_PEER, rttParams[i].peer);
+			ALOGI("\trtt_peer %d\n",rttParams[i].peer);
+            if (result < 0) {
+                return result;
+            	}
+		result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ, rttParams[i].channel.center_freq);
+			ALOGI("\trtt_ primary channel_freq %d\n",rttParams[i].channel.center_freq);
+            if (result < 0) {
+                return result;
+            }
+		result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_CHAN_WIDTH, rttParams[i].channel.width);
+			ALOGI("\trtt_channel width:%d\n",rttParams[i].channel.width);
+            if (result < 0) {
+                return result;
+            }
+		result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ0, rttParams[i].channel.center_freq0);
+			ALOGI("\trtt_channel_freq 0:%d\n",rttParams[i].channel.center_freq0);
+            if (result < 0) {
+                return result;
+            }
+		result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ1, rttParams[i].channel.center_freq1);
+			ALOGI("\trtt_channel_freq 1: %d\n",rttParams[i].channel.center_freq1);
+            if (result < 0) {
+                return result;
+            }
+            result = request.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_NUM_BURST, rttParams[i].num_burst);
+			ALOGI("\tnum_burst %d\n",rttParams[i].num_burst);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
+                    rttParams[i].num_frames_per_burst);
+			ALOGI("\tnum_frames_per_burst %d\n",rttParams[i].num_frames_per_burst);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
+                    rttParams[i].num_retries_per_rtt_frame);
+			ALOGI("\tnum_retries_per_rtt_frame %d\n",rttParams[i].num_retries_per_rtt_frame);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
+                    rttParams[i].num_retries_per_ftmr);
+			ALOGI("\tnum_retries_per_ftmr %d\n",rttParams[i].num_retries_per_ftmr);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_PERIOD,
+                    rttParams[i].burst_period);
+			ALOGI("\tburst_period %d\n",rttParams[i].burst_period);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_BURST_DURATION,
+                    rttParams[i].burst_duration);
+			ALOGI("\tburst_duration %d\n",rttParams[i].burst_duration);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_LCI,
+                    rttParams[i].LCI_request);
+			ALOGI("\tLCI_request %d\n",rttParams[i].LCI_request);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_LCR,
+                    rttParams[i].LCR_request);
+			ALOGI("\tLCR_ request%d\n",rttParams[i].LCR_request);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_BW,
+                    rttParams[i].bw);
+			ALOGI("\tBW%d\n",rttParams[i].bw);
+            if (result < 0) {
+                return result;
+            }
+
+            result = request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_PREAMBLE,
+                    rttParams[i].preamble);
+			ALOGI("\tpreamble%d\n",rttParams[i].preamble);
+            if (result < 0) {
+                return result;
+            }
+            request.attr_end(attr2);
+        }
+	ALOGE("setup request created");
+        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, SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_CANCEL);
+        if (result < 0) {
+            return result;
+        }
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+	 request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_ID, rtt_id);
+        request.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_CNT, num_devices);
+        for(unsigned i = 0; i < num_devices; i++) {
+            result = request.put_addr(SLSI_RTT_ATTRIBUTE_TARGET_MAC, addr[i]);
+            if (result < 0) {
+                return result;
+            }
+        }
+        request.attr_end(data);
+        return result;
+    }
+    int 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 RTT setup; result = %d", result);
+            return result;
+        }
+        registerVendorHandler(GOOGLE_OUI, SLSI_RTT_RESULT_EVENT);
+        registerVendorHandler(GOOGLE_OUI, SLSI_RTT_EVENT_COMPLETE);
+        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);
+            }
+        }
+        ALOGE("RTT stopped");
+		/*This needs to be check */
+	  unregisterVendorHandler(GOOGLE_OUI, SLSI_RTT_RESULT_EVENT);
+        unregisterVendorHandler(GOOGLE_OUI, SLSI_RTT_EVENT_COMPLETE);
+        return WIFI_SUCCESS;
+    }
+
+    int cancel_specific(unsigned num_devices, mac_addr addr[]) {
+        ALOGE("Stopping RTT specific");
+
+        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);
+            }
+        }
+        ALOGE("Specific RTT stopped");
+	  /*This needs to be check */
+	  unregisterVendorHandler(GOOGLE_OUI, SLSI_RTT_RESULT_EVENT);
+        unregisterVendorHandler(GOOGLE_OUI, SLSI_RTT_EVENT_COMPLETE);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+    virtual int handleEvent(WifiEvent& event) {
+        currentIdx=0;
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int event_id = event.get_vendor_subcmd();
+        ALOGD("Got an RTT event with id:%d\n",event_id);
+        if(event_id == SLSI_RTT_EVENT_COMPLETE) {
+             ALOGD("RTT event complete\n");
+             unregisterVendorHandler(GOOGLE_OUI, SLSI_RTT_RESULT_EVENT);
+             WifiCommand *cmd = wifi_unregister_cmd(wifiHandle(), id());
+              if (cmd)
+                  cmd->releaseRef();
+        } else if (event_id == SLSI_RTT_RESULT_EVENT) {
+             int result_cnt = 0;
+             int rtt_id = 0;
+             ALOGD("RTT result event\n");
+             for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                    if (it.get_type() == SLSI_RTT_ATTRIBUTE_RESULT_CNT) {
+                              result_cnt = it.get_u16();
+                              ALOGD("RTT results count : %d\n", result_cnt);
+                     }  else if (it.get_type() == SLSI_RTT_ATTRIBUTE_TARGET_ID) {
+                              rtt_id = it.get_u16();
+                              ALOGD("RTT target id : %d\n", rtt_id);
+                     } else if (it.get_type() == SLSI_RTT_ATTRIBUTE_RESULT) {
+                              ALOGD("RTT result attribute : %d\n", SLSI_RTT_ATTRIBUTE_RESULT);
+                              rttResults[currentIdx] =  (wifi_rtt_result *)malloc(sizeof(wifi_rtt_result));
+                               wifi_rtt_result *rtt_result = rttResults[currentIdx];
+                               if (rtt_result == NULL) {
+                                         ALOGE("failed to allocate the wifi_rtt_result\n");
+                                         unregisterVendorHandler(GOOGLE_OUI, SLSI_RTT_RESULT_EVENT);
+                                         break;
+                                }
+                               for(nl_iterator nl_nested_itr((struct nlattr *)it.get()); nl_nested_itr.has_next(); nl_nested_itr.next()) {
+                                  if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_ADDR) {
+                                         memcpy(rtt_result->addr, nl_nested_itr.get_data(), nl_nested_itr.get_len());
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_BURST_NUM) {
+                                         rtt_result->burst_num = (unsigned)nl_nested_itr.get_u8();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_MEASUREMENT_NUM) {
+                                         rtt_result->measurement_number = (unsigned)nl_nested_itr.get_u8();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_SUCCESS_NUM) {
+                                         rtt_result->success_number = (unsigned)nl_nested_itr.get_u8();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_NUM_PER_BURST_PEER) {
+                                         rtt_result->number_per_burst_peer = (unsigned char)nl_nested_itr.get_u8();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_STATUS) {
+                                         rtt_result->status = (wifi_rtt_status)nl_nested_itr.get_u16();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RETRY_AFTER_DURATION) {
+                                         rtt_result->retry_after_duration = (unsigned char)nl_nested_itr.get_u8();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_TYPE) {
+                                         rtt_result->type = (wifi_rtt_type)nl_nested_itr.get_u16();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RSSI) {
+                                         rtt_result->rssi = (wifi_rssi)nl_nested_itr.get_u16();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RSSI_SPREAD) {
+                                         rtt_result->rssi_spread= (wifi_rssi)nl_nested_itr.get_u16();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_TX_PREAMBLE) {
+                                         rtt_result->tx_rate.preamble = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_TX_NSS) {
+                                         rtt_result->tx_rate.nss = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_TX_BW) {
+                                         rtt_result->tx_rate.bw = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_TX_MCS) {
+                                         rtt_result->tx_rate.rateMcsIdx = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_TX_RATE) {
+                                         rtt_result->tx_rate.bitrate = nl_nested_itr.get_u32();
+                                  }else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RX_PREAMBLE) {
+                                         rtt_result->rx_rate.preamble = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RX_NSS) {
+                                         rtt_result->rx_rate.nss = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RX_BW) {
+                                         rtt_result->rx_rate.bw = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RX_MCS) {
+                                         rtt_result->rx_rate.rateMcsIdx = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RX_RATE) {
+                                         rtt_result->rx_rate.bitrate = nl_nested_itr.get_u32();
+                                  }  else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RTT) {
+                                         rtt_result->rtt = (wifi_timespan)nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RTT_SD) {
+                                         rtt_result->rtt_sd = (wifi_timespan)nl_nested_itr.get_u16();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_RTT_SPREAD) {
+                                         rtt_result->rtt_spread = (wifi_timespan)nl_nested_itr.get_u16();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_DISTANCE_MM) {
+                                         rtt_result->distance_mm = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_DISTANCE_SD_MM) {
+                                         rtt_result->distance_sd_mm = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_DISTANCE_SPREAD_MM) {
+                                         rtt_result->distance_spread_mm = nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_TIMESTAMP_US) {
+                                         rtt_result->ts = (wifi_timestamp)nl_nested_itr.get_u32();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_BURST_DURATION_MSN) {
+                                         rtt_result->burst_duration = nl_nested_itr.get_u16();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_NEGOTIATED_BURST_NUM) {
+                                         rtt_result->negotiated_burst_num = nl_nested_itr.get_u8();
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_LCI) {
+                                         u8 *lci_ie = (u8 *)nl_nested_itr.get_data();
+                                         rtt_result->LCI = (wifi_information_element *)malloc(sizeof(wifi_information_element) + nl_nested_itr.get_len() - 2);
+                                         rtt_result->LCI->id = lci_ie[0];
+                                         rtt_result->LCI->len =lci_ie[1];
+                                         memcpy(rtt_result->LCI->data, &lci_ie[2], nl_nested_itr.get_len() - 2);
+                                  } else if (nl_nested_itr.get_type() == SLSI_RTT_EVENT_ATTR_LCR) {
+                                          u8 *lcr_ie = (u8 *)nl_nested_itr.get_data();
+                                          rtt_result->LCR = (wifi_information_element *)malloc(sizeof(wifi_information_element) + nl_nested_itr.get_len() - 2);
+                                          rtt_result->LCR->id = lcr_ie[0];
+                                          rtt_result->LCR->len =lcr_ie[1];
+                                          memcpy(rtt_result->LCR->data, &lcr_ie[2], nl_nested_itr.get_len() - 2);
+                                  }
+                           }
+                           currentIdx++;
+                       }
+               }
+             (*rttHandler.on_rtt_results)(id() ,currentIdx, rttResults);
+              for (int i = 0; i < currentIdx; i++) {
+                     free(rttResults[i]);
+                     rttResults[i] = NULL;
+              }
+              currentIdx = 0;
+       }
+        ALOGE("Handled response for rtt config");
+        return NL_SKIP;
+    }
+};
+class GetRttCapabilitiesCommand : public WifiCommand
+	{
+	wifi_rtt_capabilities *mCapabilities;
+public:
+    GetRttCapabilitiesCommand(wifi_interface_handle iface, wifi_rtt_capabilities *capabitlites)
+        : WifiCommand(iface, 0), mCapabilities(capabitlites)
+    {
+        memset(mCapabilities, 0, sizeof(*mCapabilities));
+    }
+
+    virtual int create() {
+        int ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_RTT_GET_CAPABILITIES);
+        if (ret < 0) {
+            ALOGE("NL message creation failed");
+            return ret;
+        }
+
+        return ret;
+    }
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGE("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+        void *data = reply.get_vendor_data();
+        int len = reply.get_vendor_data_len();
+
+        memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities)));
+	  ALOGE("RTT capa response");
+        return NL_OK;
+    }
+};
+/*class GetRttResponderInfoCommand : public WifiCommand
+{
+    wifi_rtt_responder* mResponderInfo;
+public:
+    GetRttResponderInfoCommand(wifi_interface_handle iface, wifi_rtt_responder *responderInfo)
+        : WifiCommand(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, SLSI_NL80211_VENDOR_SUBCMD_RTT_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;
+    }
+};*/
+
+	/* 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)
+{
+    ALOGE("Inside RTT RANGE range request");
+    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;
+    }
+	ALOGE("wifi range request successfully executed");
+    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[])
+{
+    if (!iface)
+             return WIFI_ERROR_UNINITIALIZED;
+    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)
+{
+	 ALOGE("Inside get rtt capabilities cap:%p iface:%p", capabilities, iface);
+	 if (!iface)
+             return WIFI_ERROR_UNINITIALIZED;
+	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();*/
+    return WIFI_ERROR_NOT_SUPPORTED;
+
+}
diff --git a/sync.h b/sync.h
new file mode 100755
index 0000000..cea2ea9
--- /dev/null
+++ b/sync.h
@@ -0,0 +1,54 @@
+
+#include <pthread.h>
+
+#ifndef __WIFI_HAL_SYNC_H__
+#define __WIFI_HAL_SYNC_H__
+
+class Mutex
+{
+private:
+    pthread_mutex_t mMutex;
+public:
+    Mutex() {
+        pthread_mutex_init(&mMutex, NULL);
+    }
+    ~Mutex() {
+        pthread_mutex_destroy(&mMutex);
+    }
+    int tryLock() {
+        return pthread_mutex_trylock(&mMutex);
+    }
+    int lock() {
+        return pthread_mutex_lock(&mMutex);
+    }
+    void unlock() {
+        pthread_mutex_unlock(&mMutex);
+    }
+};
+
+class Condition
+{
+private:
+    pthread_cond_t mCondition;
+    pthread_mutex_t mMutex;
+
+public:
+    Condition() {
+        pthread_mutex_init(&mMutex, NULL);
+        pthread_cond_init(&mCondition, NULL);
+    }
+    ~Condition() {
+        pthread_cond_destroy(&mCondition);
+        pthread_mutex_destroy(&mMutex);
+    }
+
+    int wait() {
+        return pthread_cond_wait(&mCondition, &mMutex);
+    }
+
+    void signal() {
+        pthread_cond_signal(&mCondition);
+    }
+};
+
+#endif
\ No newline at end of file
diff --git a/wifi_hal.cpp b/wifi_hal.cpp
new file mode 100755
index 0000000..abcd1fd
--- /dev/null
+++ b/wifi_hal.cpp
@@ -0,0 +1,1029 @@
+#include <errno.h>
+#include <stdint.h>
+#include <string.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/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 "roam.h"
+
+
+#define WIFI_HAL_CMD_SOCK_PORT       644
+#define WIFI_HAL_EVENT_SOCK_PORT     645
+
+#define FEATURE_SET                  0
+#define FEATURE_SET_MATRIX           1
+#define ATTR_NODFS_VALUE             3
+#define ATTR_COUNTRY_CODE            4
+
+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);
+
+typedef enum wifi_attr {
+    ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_CONFIG,
+    ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI
+} wifi_attr_t;
+
+enum wifi_rssi_monitor_attr {
+    RSSI_MONITOR_ATTRIBUTE_MAX_RSSI,
+    RSSI_MONITOR_ATTRIBUTE_MIN_RSSI,
+    RSSI_MONITOR_ATTRIBUTE_START,
+};
+
+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);
+wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface, WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt);
+
+/* 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));
+}
+
+class SetNdoffloadCommand : public WifiCommand {
+
+private:
+    u8 mEnable;
+public:
+    SetNdoffloadCommand(wifi_interface_handle handle, u8 enable)
+        : WifiCommand(handle, 0) {
+        mEnable = enable;
+    }
+    virtual int create() {
+        int ret;
+
+        ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_CONFIGURE_ND_OFFLOAD);
+        if (ret < 0) {
+            ALOGE("Can't create message to send to driver - %d", ret);
+            return WIFI_ERROR_NOT_AVAILABLE;
+        }
+
+        nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
+        ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_CONFIG, mEnable);
+        if (ret < 0) {
+        	return ret;
+        }
+	ALOGD("Driver message has been created successfully--> %d", mEnable);
+        mMsg.attr_end(data);
+        return WIFI_SUCCESS;
+    }
+};
+
+static nl_sock * wifi_create_nl_socket(int port)
+{
+    struct nl_sock *sock = nl_socket_alloc();
+    if (sock == NULL) {
+        ALOGE("Could not create handle");
+        return NULL;
+    }
+
+    wifi_socket_set_local_port(sock, port);
+
+    if (nl_connect(sock, NETLINK_GENERIC)) {
+        ALOGE("Could not connect handle");
+        nl_socket_free(sock);
+        return NULL;
+    }
+
+    return sock;
+}
+
+
+wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable)
+{
+	SetNdoffloadCommand command(handle, enable);
+	int ret = command.requestResponse();
+	if (ret != WIFI_SUCCESS) {
+		if (ret == -EPERM) {           /*This is just to pass VTS test */
+			ALOGD("return value from driver--> %d",ret);
+			return WIFI_SUCCESS;
+		}
+	}
+	return (wifi_error)ret;
+}
+
+wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
+                                                      u32 *version, u32 *max_len)
+{
+	/*Return success to pass VTS test.*/
+	ALOGD("Packet filter not supported");
+
+	*version = 0;
+	*max_len = 0;
+
+	return WIFI_SUCCESS;
+}
+
+/* Initialize HAL function pointer table */
+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_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_set_nodfs_flag = wifi_set_nodfs_flag;
+//fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet;
+    fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet;
+    fn->wifi_set_epno_list = wifi_set_epno_list;
+    fn->wifi_reset_epno_list = wifi_reset_epno_list;
+    fn->wifi_set_passpoint_list = wifi_set_passpoint_list;
+    fn->wifi_reset_passpoint_list = wifi_reset_passpoint_list;
+    fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring;
+    fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring;
+    fn->wifi_set_link_stats = wifi_set_link_stats;
+    fn->wifi_get_link_stats = wifi_get_link_stats;
+    fn->wifi_clear_link_stats = wifi_clear_link_stats;
+    fn->wifi_set_country_code = wifi_set_country_code;
+    fn->wifi_configure_roaming = wifi_configure_roaming;
+    fn->wifi_configure_nd_offload = wifi_configure_nd_offload;
+    fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities;
+    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_start_logging = wifi_start_logging;
+    fn->wifi_set_log_handler = wifi_set_log_handler;
+    fn->wifi_set_alert_handler= wifi_set_alert_handler;
+    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_get_firmware_version = wifi_get_firmware_version;
+    fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump;
+    fn->wifi_get_driver_memory_dump = wifi_get_driver_memory_dump;
+    fn->wifi_get_wake_reason_stats = wifi_get_wake_reason_stats;
+    fn->wifi_nan_enable_request = nan_enable_request;
+    fn->wifi_nan_disable_request = nan_disable_request;
+    fn->wifi_nan_publish_request = nan_publish_request;
+    fn->wifi_nan_publish_cancel_request = nan_publish_cancel_request;
+    fn->wifi_nan_subscribe_request = nan_subscribe_request;
+    fn->wifi_nan_subscribe_cancel_request = nan_subscribe_cancel_request;
+    fn->wifi_nan_transmit_followup_request = nan_transmit_followup_request;
+    fn->wifi_nan_config_request = nan_config_request;
+    fn->wifi_nan_register_handler = nan_register_handler;
+    fn->wifi_nan_get_version = nan_get_version;
+    fn->wifi_nan_get_capabilities = nan_get_capabilities;
+    fn->wifi_get_roaming_capabilities = wifi_get_roaming_capabilities;
+    fn->wifi_enable_firmware_roaming = wifi_enable_firmware_roaming;
+
+    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));
+
+    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;
+    wifi_add_membership(*handle, "scan");
+    wifi_add_membership(*handle, "mlme");
+    wifi_add_membership(*handle, "regulatory");
+    wifi_add_membership(*handle, "vendor");
+
+    wifi_init_interfaces(*handle);
+    char intf_name_buff[10 * 10 + 4]; /* Randomly choosen max interface 10. each interface name max 9 + 1(for space) */
+    char *pos = intf_name_buff;
+    for (int i = 0; i < (info->num_interfaces < 10 ? info->num_interfaces : 10); i++) {
+        strncpy(pos, info->interfaces[i]->name, sizeof(intf_name_buff) - (pos - intf_name_buff));
+        pos += strlen(pos);
+    }
+    if (info->num_interfaces > 10) {
+        strncpy(pos, "...", 3);
+    }
+
+    ALOGD("Found %d interfaces[%s]. Initialized Wifi HAL Successfully", info->num_interfaces, intf_name_buff);
+
+    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);
+    }
+    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);
+}
+
+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 (write(info->cleanup_socks[0], "Exit", 4) < 1) {
+        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));
+        int result = read(info->cleanup_socks[0], buf, sizeof(buf));
+        ALOGE("%s: Read after POLL returned %d, error no = %d", __FUNCTION__, result, errno);
+        if (strncmp(buf, "Done", 4) != 0) {
+            ALOGD("Rx'ed %s", buf);
+        }
+    }
+    info->clean_up = true;
+    pthread_mutex_lock(&info->cb_lock);
+
+    int bad_commands = 0;
+
+    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) {
+            pthread_mutex_unlock(&info->cb_lock);
+            cmd->cancel();
+            pthread_mutex_lock(&info->cb_lock);
+            /* release reference added when command is saved */
+            cmd->releaseRef();
+            if (num_cmd == info->num_cmd) {
+                bad_commands++;
+            }
+        }
+    }
+
+    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);
+    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];
+
+    do {
+        int timeout = -1;                   /* Infinite timeout */
+        pfd[0].revents = 0;
+        pfd[1].revents = 0;
+        int result = poll(pfd, 2, timeout);
+        if (result < 0) {
+        } else if (pfd[0].revents & POLLERR) {
+            int prev_err = (int)errno;
+            int result2 = read(pfd[0].fd, buf, sizeof(buf));
+            ALOGE("Poll err:%d | Read after POLL returned %d, error no = %d", prev_err, result2, errno);
+        } else if (pfd[0].revents & POLLHUP) {
+            ALOGE("Remote side hung up");
+            break;
+        } else if (pfd[0].revents & POLLIN) {
+            internal_pollin_handler(handle);
+        } else if (pfd[1].revents & POLLIN) {
+            memset(buf, 0, sizeof(buf));
+            int result2 = read(pfd[1].fd, buf, sizeof(buf));
+            ALOGE("%s: Read after POLL returned %d, error no = %d", __FUNCTION__, result2, errno);
+            if (strncmp(buf, "Exit", 4) == 0) {
+                ALOGD("Got a signal to exit!!!");
+                if (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);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+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)
+{
+    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);
+        /*
+        ALOGI("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x",
+                event.get_cmdString(), vendor_id, subcmd);*/
+    }
+
+     //ALOGI("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id);
+     //event.log();
+
+    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(handle, 0)
+    {
+        mName = name;
+        mGroup = group;
+        mId = -1;
+    }
+
+    int getId() {
+        return mId;
+    }
+
+    virtual int create() {
+        int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl");
+        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) {
+        struct nlattr **tb = reply.attributes();
+        struct nlattr *mcgrp = NULL;
+        int i;
+
+        if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
+            ALOGE("No multicast groups found");
+            return NL_SKIP;
+        }
+
+        for_each_attr(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
+
+            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]);
+
+            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(handle, 0)
+    {
+        mOui = scan_oui;
+	fset = NULL;
+	feature_matrix = NULL;
+	fm_size = NULL;
+	set_size_max = 0;
+    }
+
+    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() {
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request, SLSI_NL80211_VENDOR_SUBCMD_SET_GSCAN_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) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+};
+
+class SetNodfsCommand : public WifiCommand {
+
+private:
+    u32 mNoDfs;
+public:
+    SetNodfsCommand(wifi_interface_handle handle, u32 nodfs)
+        : WifiCommand(handle, 0) {
+        mNoDfs = nodfs;
+    }
+    virtual int create() {
+        int ret;
+
+        ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_SET_NODFS);
+        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(ATTR_NODFS_VALUE, mNoDfs);
+        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(handle, id), mMax_rssi(max_rssi), mMin_rssi
+        (min_rssi), mHandler(eh)
+        {
+        }
+   int createRequest(WifiRequest& request, int enable) {
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_SET_RSSI_MONITOR);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u8(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0));
+        if (result < 0) {
+            return result;
+        }
+
+        result = request.put_u8(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0));
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(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, WIFI_RSSI_REPORT_EVENT);
+
+        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, WIFI_RSSI_REPORT_EVENT);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+   virtual int handleEvent(WifiEvent& 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;
+        }
+
+        typedef struct {
+            s8 cur_rssi;
+            mac_addr BSSID;
+        } rssi_monitor_evt;
+
+        rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data();
+
+        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 SetCountryCodeCommand : public WifiCommand {
+private:
+    const char *mCountryCode;
+public:
+    SetCountryCodeCommand(wifi_interface_handle handle, const char *country_code)
+        : WifiCommand(handle, 0) {
+        mCountryCode = country_code;
+        }
+    virtual int create() {
+        int ret;
+
+        ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_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(ATTR_COUNTRY_CODE, mCountryCode);
+        if (ret < 0) {
+            return ret;
+        }
+
+        mMsg.attr_end(data);
+        return WIFI_SUCCESS;
+
+    }
+};
+
+class GetFeatureSetCommand : public WifiCommand {
+
+private:
+
+    feature_set *fset;
+
+public:
+    GetFeatureSetCommand(wifi_interface_handle handle, feature_set *set)
+        : WifiCommand(handle, 0)
+    {
+        fset = set;
+    }
+
+    virtual int create() {
+        int ret;
+
+        ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_GET_FEATURE_SET);
+        if (ret < 0) {
+            ALOGE("create failed - %d", ret);
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignore reply; 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();
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("vendor data in GetFeatureSetCommand missing!!");
+            return NL_SKIP;
+        }
+
+        void *data = reply.get_vendor_data();
+        if(!fset) {
+            ALOGE("feature_set Pointer not set");
+            return NL_SKIP;
+        }
+        memcpy(fset, data, min(len, (int) sizeof(*fset)));
+        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);
+    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);
+
+    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_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
+       feature_set set[], int *set_size)
+{
+    return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+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();
+}
+
+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);
+    wifi_register_cmd(handle, id, cmd);
+
+    wifi_error result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+    }
+    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;
+        memset(&handler, 0, sizeof(handler));
+        SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface,
+                                                    0, 0, handler);
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
+    return wifi_cancel_cmd(id, iface);
+}
+
+wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
+{
+    GetFeatureSetCommand command(handle, set);
+    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();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
diff --git a/wifi_logger.cpp b/wifi_logger.cpp
new file mode 100755
index 0000000..4ab5d74
--- /dev/null
+++ b/wifi_logger.cpp
@@ -0,0 +1,1444 @@
+#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 "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+/* using namespace android; */
+
+typedef enum {
+    ENHANCE_LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START,
+    ENHANCE_LOGGER_TRIGGER_FW_MEM_DUMP,
+    ENHANCE_LOGGER_GET_FW_MEM_DUMP,
+    ENHANCE_LOGGER_GET_VER,
+    ENHANCE_LOGGER_GET_RING_STATUS,
+    ENHANCE_LOGGER_GET_RING_DATA,
+    ENHANCE_LOGGER_GET_FEATURE,
+    ENHANCE_LOGGER_RESET_LOGGING,
+    ENHANCE_LOGGER_TRIGGER_DRIVER_MEM_DUMP,
+    ENHANCE_LOGGER_GET_DRIVER_MEM_DUMP,
+    ENHANCE_LOGGER_START_PKT_FATE_MONITORING,
+    ENHANCE_LOGGER_GET_TX_PKT_FATES,
+    ENHANCE_LOGGER_GET_RX_PKT_FATES,
+    ENHANCE_LOGGER_GET_WAKE_REASON_STATS,
+} DEBUG_SUB_COMMAND;
+
+typedef enum {
+    ENHANCE_LOGGER_ATTRIBUTE_DRIVER_VER,
+    ENHANCE_LOGGER_ATTRIBUTE_FW_VER,
+    ENHANCE_LOGGER_ATTRIBUTE_RING_ID,
+    ENHANCE_LOGGER_ATTRIBUTE_RING_NAME,
+    ENHANCE_LOGGER_ATTRIBUTE_RING_FLAGS,
+    ENHANCE_LOGGER_ATTRIBUTE_LOG_LEVEL,
+    ENHANCE_LOGGER_ATTRIBUTE_LOG_TIME_INTVAL,
+    ENHANCE_LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE,
+    ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_LEN,
+    ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_DATA,
+    // LOGGER_ATTRIBUTE_FW_ERR_CODE,
+    ENHANCE_LOGGER_ATTRIBUTE_RING_DATA,
+    ENHANCE_LOGGER_ATTRIBUTE_RING_STATUS,
+    ENHANCE_LOGGER_ATTRIBUTE_RING_NUM,
+    ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN,
+    ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA,
+    ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_NUM,
+    ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_DATA,
+    //Attributes for data used by wake stats subcmd.
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_INVALID = 0,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_CMD_EVENT_WAKE,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_CMD_EVENT_WAKE_CNT_PTR,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_CMD_EVENT_WAKE_CNT_SZ,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_DRIVER_FW_LOCAL_WAKE,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_PTR,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_SZ,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_RX_DATA_WAKE,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_UNICAST_CNT,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_MULTICAST_CNT,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_BROADCAST_CNT,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP_PKT,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_PKT,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_RA,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_NA,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_NS,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP4_RX_MULTICAST_CNT,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_RX_MULTICAST_CNT,
+    ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_OTHER_RX_MULTICAST_CNT,
+} ENHANCE_LOGGER_ATTRIBUTE;
+
+typedef enum {
+    DEBUG_OFF = 0,
+    DEBUG_NORMAL,
+    DEBUG_VERBOSE,
+    DEBUG_VERY,
+    DEBUG_VERY_VERY,
+} ENHANCE_LOGGER_LEVEL;
+
+typedef enum {
+    GET_FW_VER,
+    GET_DRV_VER,
+    GET_RING_DATA,
+    GET_RING_STATUS,
+    GET_FEATURE,
+    START_RING_LOG,
+    GET_FW_DUMP,
+    GET_DRIVER_DUMP,
+} GetCmdType;
+
+typedef enum {
+    PACKET_MONITOR_START,
+    TX_PACKET_FATE,
+    RX_PACKET_FATE,
+} PktFateReqType;
+
+class DebugCommand : public WifiCommand
+{
+    char *mBuff = NULL;
+    int *mBuffSize = NULL;
+    u32 *mNumRings = NULL;
+    wifi_ring_buffer_status *mStatus = NULL;
+    unsigned int *mSupport = NULL;
+    u32 mVerboseLevel = 0;
+    u32 mFlags = 0;
+    u32 mMaxIntervalSec = 0;
+    u32 mMinDataSize = 0;
+    char *mRingName = NULL;
+    GetCmdType mType;
+
+public:
+
+    // constructor for get version
+    DebugCommand(wifi_interface_handle iface, char *buffer, int *buffer_size,
+            GetCmdType cmdType)
+        : WifiCommand(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(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(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(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(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, ENHANCE_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(ENHANCE_LOGGER_ATTRIBUTE_LOG_LEVEL, mVerboseLevel);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to put log level; result = %d", result);
+            return result;
+        }
+        result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_RING_FLAGS, mFlags);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to put ring flags; result = %d", result);
+            return result;
+        }
+        result = request.put_u32(ENHANCE_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(ENHANCE_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(ENHANCE_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, ENHANCE_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(ENHANCE_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, ENHANCE_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(ENHANCE_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, ENHANCE_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(ENHANCE_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, ENHANCE_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, ENHANCE_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() == ENHANCE_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(), ENHANCE_LOGGER_ATTRIBUTE_RING_NUM);
+                    return NL_SKIP;
+                }
+
+                it.next();
+                if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_RING_STATUS) {
+                    memcpy(status, it.get_data(), sizeof(wifi_ring_buffer_status) * (*mNumRings));
+                } 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();
+
+                ALOGD("len = %d, expected len = %lu", reply.get_vendor_data_len(), (unsigned long)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 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;
+    }
+}
+
+/* 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 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;
+}
+
+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;
+    }
+}
+
+/* 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;
+    }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+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(iface, id), mHandler(handler)
+    { }
+
+    int start() {
+        ALOGV("Register loghandler");
+        registerVendorHandler(GOOGLE_OUI, ENHANCE_LOGGER_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, ENHANCE_LOGGER_RING_EVENT);
+
+        WifiRequest request(familyId(), ifaceId());
+        int result = request.create(GOOGLE_OUI, ENHANCE_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 == ENHANCE_LOGGER_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() == ENHANCE_LOGGER_ATTRIBUTE_RING_STATUS) {
+                    memcpy(&status, it.get_data(), sizeof(status));
+                } else if (it.get_type() == ENHANCE_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(iface, id), mHandler(handler), mBuffSize(0), mBuff(NULL),
+            mErrCode(0)
+    { }
+
+    int start() {
+        ALOGV("Start Alerting");
+        registerVendorHandler(GOOGLE_OUI, ENHANCE_LOGGER_MEM_DUMP_EVENT);
+        return WIFI_SUCCESS;
+    }
+
+    virtual int cancel() {
+        ALOGV("Clear alerthandler");
+
+        /* unregister alert handler */
+        unregisterVendorHandler(GOOGLE_OUI, ENHANCE_LOGGER_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() == ENHANCE_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) {
+        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 == ENHANCE_LOGGER_MEM_DUMP_EVENT) {
+            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_LEN) {
+                    mBuffSize = it.get_u32();
+                } else if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_RING_DATA) {
+                    buffer_size = it.get_len();
+                    buffer = (char *)it.get_data();
+            /*
+                } else if (it.get_type() == ENHANCE_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, ENHANCE_LOGGER_MEM_DUMP_EVENT);
+                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(ENHANCE_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(ENHANCE_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 PacketFateCommand: public WifiCommand
+{
+    void *mReportBufs = NULL;
+    size_t mNoReqFates = 0;
+    size_t *mNoProvidedFates = NULL;
+    PktFateReqType mReqType;
+
+public:
+    PacketFateCommand(wifi_interface_handle handle)
+        : WifiCommand(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(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(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, ENHANCE_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, ENHANCE_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(ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u64(ENHANCE_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, ENHANCE_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(ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u64(ENHANCE_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() == ENHANCE_LOGGER_ATTRIBUTE_PKT_FATE_NUM) {
+                *mNoProvidedFates = it.get_u32();
+                ALOGI("No: of pkt fates provided is %zu\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();
+    memset(tx_report_bufs, 0, (n_requested_fates * sizeof(wifi_tx_report)));
+    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();
+    memset(rx_report_bufs, 0, (n_requested_fates * sizeof(wifi_rx_report)));
+    return result;
+}
+
+class MemoryDumpCommand: public WifiCommand
+{
+    wifi_firmware_memory_dump_handler mHandler;
+    wifi_driver_memory_dump_callbacks mcallback;
+    int mBuffSize;
+    char *mBuff;
+    GetCmdType mType;
+
+public:
+    MemoryDumpCommand(wifi_interface_handle iface, wifi_firmware_memory_dump_handler handler, GetCmdType cmdtype )
+        : WifiCommand(iface, 0), mHandler(handler), mBuffSize(0), mBuff(NULL), mType(cmdtype)
+    {
+        memset(&mcallback, 0, sizeof(wifi_driver_memory_dump_callbacks));
+    }
+
+    MemoryDumpCommand(wifi_interface_handle iface, wifi_driver_memory_dump_callbacks callback, GetCmdType cmdtype)
+        : WifiCommand(iface, 0), mcallback(callback), mBuffSize(0), mBuff(NULL), mType(cmdtype)
+    {
+        memset(&mHandler, 0, sizeof(wifi_firmware_memory_dump_handler));
+    }
+
+     int createRequest(WifiRequest &request) {
+        int result;
+
+        switch (mType) {
+                case GET_FW_DUMP:
+                    {
+                        result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_TRIGGER_FW_MEM_DUMP);
+                        if (result != WIFI_SUCCESS) {
+                                 ALOGE("Failed to create trigger fw memory dump request; result = %d", result);
+                                 return result;
+                        }
+                        break;
+                    }
+                case GET_DRIVER_DUMP :
+                    {
+                        result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_TRIGGER_DRIVER_MEM_DUMP);
+                        if (result != WIFI_SUCCESS) {
+                                ALOGE("Failed to create trigger driver memory dump request; result = %d", result);
+                                return result;
+                         }
+                        break;
+                      }
+                 default:
+                         ALOGE("Unknown Debug command");
+                         result = WIFI_ERROR_UNKNOWN;
+                     }
+        return result;
+     }
+    int start() {
+        ALOGD("Start memory dump command");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = createRequest(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to create trigger 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;
+        }
+        switch(mType) {
+            case GET_FW_DUMP:
+                 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                     if (it.get_type() == ENHANCE_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, ENHANCE_LOGGER_GET_FW_MEM_DUMP);
+                         if (result != WIFI_SUCCESS) {
+                             ALOGE("Failed to create get fw memory dump request; result = %d", result);
+                             free(mBuff);
+                             return NL_SKIP;
+                          }
+                          nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+                          result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_LEN, mBuffSize);
+                          if (result != WIFI_SUCCESS) {
+                              ALOGE("Failed to put get fw memory dump request; result = %d", result);
+                              return result;
+                          }
+                          result = request.put_u64(ENHANCE_LOGGER_ATTRIBUTE_FW_DUMP_DATA, (uint64_t)mBuff);
+                          if (result != WIFI_SUCCESS) {
+                              ALOGE("Failed to put get fw memory dump request; result = %d", result);
+                              return result;
+                          }
+                          request.attr_end(data);
+                          result = requestResponse(request);
+                          if (result != WIFI_SUCCESS) {
+                              ALOGE("Failed to register get fw momory dump response; result = %d", result);
+                          }
+                     } else if (it.get_type() == ENHANCE_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());
+                     }
+                 }
+                 break;
+            case GET_DRIVER_DUMP :
+                 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                     if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_DRIVER_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, ENHANCE_LOGGER_GET_DRIVER_MEM_DUMP);
+                         if (result != WIFI_SUCCESS) {
+                             ALOGE("Failed to create get driver memory dump request; result = %d", result);
+                             free(mBuff);
+                             return NL_SKIP;
+                          }
+                          nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+                          result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN, mBuffSize);
+                          if (result != WIFI_SUCCESS) {
+                              ALOGE("Failed to put get driver memory dump request; result = %d", result);
+                              return result;
+                          }
+                          result = request.put_u64(ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA, (uint64_t)mBuff);
+                          if (result != WIFI_SUCCESS) {
+                              ALOGE("Failed to put get driver memory dump request; result = %d", result);
+                              return result;
+                          }
+                          request.attr_end(data);
+                          result = requestResponse(request);
+                          if (result != WIFI_SUCCESS) {
+                              ALOGE("Failed to register get driver momory dump response; result = %d", result);
+                          }
+                     } else if (it.get_type() == ENHANCE_LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA) {
+                          ALOGI("Initiating memory dump callback");
+                          if (mcallback.on_driver_memory_dump) {
+                              (*mcallback.on_driver_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());
+                     }
+                 }
+                 break;
+            case GET_FW_VER:
+            case GET_DRV_VER:
+            case GET_RING_DATA:
+            case GET_RING_STATUS:
+            case GET_FEATURE:
+            case START_RING_LOG:
+            default:
+                   {
+                          ALOGW("Ignoring GetCmdType %d \n", mType);
+                   }
+            }
+        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, GET_FW_DUMP);
+    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_driver_memory_dump(wifi_interface_handle iface,
+                                wifi_driver_memory_dump_callbacks callbacks)
+{
+    MemoryDumpCommand *cmd = new MemoryDumpCommand(iface, callbacks, GET_DRIVER_DUMP);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
+class WifiLoggerCommand: public WifiCommand
+{
+     WLAN_DRIVER_WAKE_REASON_CNT *mGetWakeStats;
+
+public:
+    WifiLoggerCommand(wifi_interface_handle handle, WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt)
+        : WifiCommand(handle, 0), mGetWakeStats(wifi_wake_reason_cnt)
+    { }
+
+    int createRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, ENHANCE_LOGGER_GET_WAKE_REASON_STATS);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_CMD_EVENT_WAKE_CNT_SZ, mGetWakeStats->cmd_event_wake_cnt_sz);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to put wake_cnt_sz; result = %d", result);
+            return result;
+        }
+        result = request.put_u32(ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_SZ, mGetWakeStats->driver_fw_local_wake_cnt_sz);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to put driver_fw_local_wake_cnt; result = %d", result);
+            return result;
+        }
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        ALOGD("Start get wake reason stats command\n");
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request);
+        if (result < 0) {
+                 ALOGE("Failed to create get wake reason stats request; result = %d\n", result);
+                 return result;
+        }
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+                ALOGE("Failed to register get wake reason stats response; result = %d\n", result);
+        }
+        return result;
+    }
+
+    int handleResponse(WifiEvent& reply) {
+         int len = 0;
+         ALOGD("In WifiLoggerCommand::handleResponse\n");
+
+         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+             ALOGI("Ignoring reply with cmd = %d", reply.get_cmd());
+             return NL_SKIP;
+        }
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        len = reply.get_vendor_data_len();
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("No Debug data found");
+            return NL_SKIP;
+       }
+       nl_iterator it(vendor_data);
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_CMD_EVENT_WAKE) {
+            ALOGE("TOTAL_CMD_EVENT_WAKE not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->total_cmd_event_wake = it.get_u32();
+       it.next();
+
+       if(mGetWakeStats->total_cmd_event_wake && mGetWakeStats->cmd_event_wake_cnt) {
+            if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_CMD_EVENT_WAKE_CNT_PTR) {
+                 ALOGE("CMD_EVENT_WAKE_CNT_PTR not found %d", it.get_type());
+                 return NL_SKIP;
+            }
+
+            len = it.get_len();
+            mGetWakeStats->cmd_event_wake_cnt_used = (len < mGetWakeStats->cmd_event_wake_cnt_sz) ? len : mGetWakeStats->cmd_event_wake_cnt_sz;
+            memcpy(mGetWakeStats->cmd_event_wake_cnt, it.get_data(), mGetWakeStats->cmd_event_wake_cnt_used * sizeof(int));
+       } else {
+            mGetWakeStats->cmd_event_wake_cnt_used = 0;
+       }
+
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_DRIVER_FW_LOCAL_WAKE) {
+            ALOGE("TOTAL_DRIVER_FW_LOCAL_WAKE not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->total_driver_fw_local_wake = it.get_u32();
+       it.next();
+
+       if(mGetWakeStats->total_driver_fw_local_wake && mGetWakeStats->driver_fw_local_wake_cnt) {
+            if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_PTR) {
+                 ALOGE("DRIVER_FW_LOCAL_WAKE_CNT_PTR not found %d", it.get_type());
+                 return NL_SKIP;
+            }
+
+            len = it.get_len();
+            mGetWakeStats->driver_fw_local_wake_cnt_used= (len < mGetWakeStats->driver_fw_local_wake_cnt_sz) ? len : mGetWakeStats->driver_fw_local_wake_cnt_sz;
+            memcpy(mGetWakeStats->driver_fw_local_wake_cnt, it.get_data(), mGetWakeStats->driver_fw_local_wake_cnt_used * sizeof(int));
+       } else {
+            mGetWakeStats->driver_fw_local_wake_cnt_used= 0;
+       }
+
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_TOTAL_RX_DATA_WAKE) {
+            ALOGE("TOTAL_RX_DATA_WAKE not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->total_rx_data_wake = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_UNICAST_CNT) {
+            ALOGE("RX_UNICAST_CNT not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_wake_details.rx_unicast_cnt = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_MULTICAST_CNT) {
+            ALOGE("RX_MULTICAST_CNT not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_wake_details.rx_multicast_cnt = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_RX_BROADCAST_CNT) {
+            ALOGE("RX_BROADCAST_CNT not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_wake_details.rx_broadcast_cnt = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP_PKT) {
+            ALOGE("ICMP_PKT not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_wake_pkt_classification_info .icmp_pkt = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_PKT) {
+            ALOGE("ICMP6_PKT not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_wake_pkt_classification_info .icmp6_pkt = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_RA) {
+            ALOGE("ICMP6_RA not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_wake_pkt_classification_info .icmp6_ra = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_NA) {
+            ALOGE("ICMP6_NA not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_wake_pkt_classification_info .icmp6_na = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_NS) {
+            ALOGE("ICMP6_NS not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_wake_pkt_classification_info .icmp6_ns = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP4_RX_MULTICAST_CNT) {
+            ALOGE("ICMP4_RX_MULTICAST_CNT not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_ICMP6_RX_MULTICAST_CNT) {
+            ALOGE("ICMP6_RX_MULTICAST_CNT not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt = it.get_u32();
+       it.next();
+
+       if (it.get_type() != ENHANCE_LOGGER_ATTRIBUTE_WAKE_STATS_OTHER_RX_MULTICAST_CNT) {
+            ALOGE("OTHER_RX_MULTICAST_CNT not found %d", it.get_type());
+            return NL_SKIP;
+       }
+
+       mGetWakeStats->rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt = it.get_u32();
+
+       return NL_OK;
+    }
+
+    int handleEvent(WifiEvent& event) {
+        /* NO events to handle here! */
+        return NL_SKIP;
+    }
+};
+
+ /* Function to get wake lock stats */
+wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface,
+                             WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt)
+{
+    if(wifi_wake_reason_cnt) {
+        WifiLoggerCommand *cmd =  new WifiLoggerCommand(iface,wifi_wake_reason_cnt);
+        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("Reason cnt NULL");
+        return  WIFI_ERROR_INVALID_ARGS;
+    }
+}
+
diff --git a/wifi_nan.cpp b/wifi_nan.cpp
new file mode 100755
index 0000000..35c01ee
--- /dev/null
+++ b/wifi_nan.cpp
@@ -0,0 +1,1419 @@
+
+#include <stdint.h>
+#include <stddef.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"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+#define SLSI_WIFI_HAL_NAN_VERSION 1
+
+#define CHECK_WIFI_STATUS_RETURN_FAIL(result, LOGSTR) \
+    if (result != WIFI_SUCCESS) {\
+        ALOGE(LOGSTR" [result:%d]", result);\
+        return result;\
+    }
+
+#define CHECK_CONFIG_PUT_8_RETURN_FAIL(config, val, nan_attribute, request, result, FAIL_STR) \
+    if (config) {\
+        result = request.put_u8(nan_attribute, val); \
+        if (result != WIFI_SUCCESS) {\
+            ALOGE(FAIL_STR" [result:%d]", result);\
+            return result;\
+        }\
+    }
+
+#define CHECK_CONFIG_PUT_16_RETURN_FAIL(config, val, nan_attribute, request, result, FAIL_STR) \
+    if (config) {\
+        result = request.put_u16(nan_attribute, val); \
+        if (result != WIFI_SUCCESS) {\
+            ALOGE(FAIL_STR" [result:%d]", result);\
+            return result;\
+        }\
+    }
+
+
+#define CHECK_CONFIG_PUT_32_RETURN_FAIL(config, val, nan_attribute, request, result, FAIL_STR) \
+    if (config) {\
+        result = request.put_u32(nan_attribute, val); \
+        if (result != WIFI_SUCCESS) {\
+            ALOGE(FAIL_STR" [result:%d]", result);\
+            return result;\
+        }\
+    }
+
+#define CHECK_CONFIG_PUT_RETURN_FAIL(config, valptr, len, nan_attribute, request, result, FAIL_STR) \
+    if (config) {\
+        result = request.put(nan_attribute, valptr, len); \
+        if (result != WIFI_SUCCESS) {\
+            ALOGE(FAIL_STR" [result:%d]", result);\
+            return result;\
+        }\
+    }
+
+typedef enum {
+    NAN_REQ_ATTR_MASTER_PREF,
+    NAN_REQ_ATTR_CLUSTER_LOW,
+    NAN_REQ_ATTR_CLUSTER_HIGH,
+    NAN_REQ_ATTR_HOP_COUNT_LIMIT_VAL,
+    NAN_REQ_ATTR_SID_BEACON_VAL,
+
+    NAN_REQ_ATTR_SUPPORT_2G4_VAL,
+    NAN_REQ_ATTR_SUPPORT_5G_VAL,
+
+    NAN_REQ_ATTR_RSSI_CLOSE_2G4_VAL,
+    NAN_REQ_ATTR_RSSI_MIDDLE_2G4_VAL,
+    NAN_REQ_ATTR_RSSI_PROXIMITY_2G4_VAL,
+    NAN_REQ_ATTR_BEACONS_2G4_VAL,
+    NAN_REQ_ATTR_SDF_2G4_VAL,
+    NAN_REQ_ATTR_CHANNEL_2G4_MHZ_VAL,
+    NAN_REQ_ATTR_RSSI_PROXIMITY_VAL,
+
+
+    NAN_REQ_ATTR_RSSI_CLOSE_5G_VAL,
+    NAN_REQ_ATTR_RSSI_CLOSE_PROXIMITY_5G_VAL,
+    NAN_REQ_ATTR_RSSI_MIDDLE_5G_VAL,
+    NAN_REQ_ATTR_RSSI_PROXIMITY_5G_VAL,
+    NAN_REQ_ATTR_BEACON_5G_VAL,
+    NAN_REQ_ATTR_SDF_5G_VAL,
+    NAN_REQ_ATTR_CHANNEL_5G_MHZ_VAL,
+
+    NAN_REQ_ATTR_RSSI_WINDOW_SIZE_VAL,
+    NAN_REQ_ATTR_OUI_VAL,
+    NAN_REQ_ATTR_MAC_ADDR_VAL,
+    NAN_REQ_ATTR_CLUSTER_VAL,
+    NAN_REQ_ATTR_SOCIAL_CH_SCAN_DWELL_TIME,
+    NAN_REQ_ATTR_SOCIAL_CH_SCAN_PERIOD,
+    NAN_REQ_ATTR_RANDOM_FACTOR_FORCE_VAL,
+    NAN_REQ_ATTR_HOP_COUNT_FORCE_VAL,
+    NAN_REQ_ATTR_CONN_CAPABILITY_PAYLOAD_TX,
+    NAN_REQ_ATTR_CONN_CAPABILITY_IBSS,
+    NAN_REQ_ATTR_CONN_CAPABILITY_WFD,
+    NAN_REQ_ATTR_CONN_CAPABILITY_WFDS,
+    NAN_REQ_ATTR_CONN_CAPABILITY_TDLS,
+    NAN_REQ_ATTR_CONN_CAPABILITY_MESH,
+    NAN_REQ_ATTR_CONN_CAPABILITY_WLAN_INFRA,
+    NAN_REQ_ATTR_DISCOVERY_ATTR_NUM_ENTRIES,
+    NAN_REQ_ATTR_DISCOVERY_ATTR_VAL,
+    NAN_REQ_ATTR_CONN_TYPE,
+    NAN_REQ_ATTR_NAN_ROLE,
+    NAN_REQ_ATTR_TRANSMIT_FREQ,
+    NAN_REQ_ATTR_AVAILABILITY_DURATION,
+    NAN_REQ_ATTR_AVAILABILITY_INTERVAL,
+    NAN_REQ_ATTR_MESH_ID_LEN,
+    NAN_REQ_ATTR_MESH_ID,
+    NAN_REQ_ATTR_INFRASTRUCTURE_SSID_LEN,
+    NAN_REQ_ATTR_INFRASTRUCTURE_SSID,
+    NAN_REQ_ATTR_FURTHER_AVAIL_NUM_ENTRIES,
+    NAN_REQ_ATTR_FURTHER_AVAIL_VAL,
+    NAN_REQ_ATTR_FURTHER_AVAIL_ENTRY_CTRL,
+    NAN_REQ_ATTR_FURTHER_AVAIL_CHAN_CLASS,
+    NAN_REQ_ATTR_FURTHER_AVAIL_CHAN,
+    NAN_REQ_ATTR_FURTHER_AVAIL_CHAN_MAPID,
+    NAN_REQ_ATTR_FURTHER_AVAIL_INTERVAL_BITMAP,
+    NAN_REQ_ATTR_PUBLISH_ID,
+    NAN_REQ_ATTR_PUBLISH_TTL,
+    NAN_REQ_ATTR_PUBLISH_PERIOD,
+    NAN_REQ_ATTR_PUBLISH_TYPE,
+    NAN_REQ_ATTR_PUBLISH_TX_TYPE,
+    NAN_REQ_ATTR_PUBLISH_COUNT,
+    NAN_REQ_ATTR_PUBLISH_SERVICE_NAME_LEN,
+    NAN_REQ_ATTR_PUBLISH_SERVICE_NAME,
+    NAN_REQ_ATTR_PUBLISH_MATCH_ALGO,
+    NAN_REQ_ATTR_PUBLISH_SERVICE_INFO_LEN,
+    NAN_REQ_ATTR_PUBLISH_SERVICE_INFO,
+    NAN_REQ_ATTR_PUBLISH_RX_MATCH_FILTER_LEN,
+    NAN_REQ_ATTR_PUBLISH_RX_MATCH_FILTER,
+    NAN_REQ_ATTR_PUBLISH_TX_MATCH_FILTER_LEN,
+    NAN_REQ_ATTR_PUBLISH_TX_MATCH_FILTER,
+    NAN_REQ_ATTR_PUBLISH_RSSI_THRESHOLD_FLAG,
+    NAN_REQ_ATTR_PUBLISH_CONN_MAP,
+    NAN_REQ_ATTR_PUBLISH_RECV_IND_CFG,
+    NAN_REQ_ATTR_SUBSCRIBE_ID,
+    NAN_REQ_ATTR_SUBSCRIBE_TTL,
+    NAN_REQ_ATTR_SUBSCRIBE_PERIOD,
+    NAN_REQ_ATTR_SUBSCRIBE_TYPE,
+    NAN_REQ_ATTR_SUBSCRIBE_RESP_FILTER_TYPE,
+    NAN_REQ_ATTR_SUBSCRIBE_RESP_INCLUDE,
+    NAN_REQ_ATTR_SUBSCRIBE_USE_RESP_FILTER,
+    NAN_REQ_ATTR_SUBSCRIBE_SSI_REQUIRED,
+    NAN_REQ_ATTR_SUBSCRIBE_MATCH_INDICATOR,
+    NAN_REQ_ATTR_SUBSCRIBE_COUNT,
+    NAN_REQ_ATTR_SUBSCRIBE_SERVICE_NAME_LEN,
+    NAN_REQ_ATTR_SUBSCRIBE_SERVICE_NAME,
+    NAN_REQ_ATTR_SUBSCRIBE_SERVICE_INFO_LEN,
+    NAN_REQ_ATTR_SUBSCRIBE_SERVICE_INFO,
+    NAN_REQ_ATTR_SUBSCRIBE_RX_MATCH_FILTER_LEN,
+    NAN_REQ_ATTR_SUBSCRIBE_RX_MATCH_FILTER,
+    NAN_REQ_ATTR_SUBSCRIBE_TX_MATCH_FILTER_LEN,
+    NAN_REQ_ATTR_SUBSCRIBE_TX_MATCH_FILTER,
+    NAN_REQ_ATTR_SUBSCRIBE_RSSI_THRESHOLD_FLAG,
+    NAN_REQ_ATTR_SUBSCRIBE_CONN_MAP,
+    NAN_REQ_ATTR_SUBSCRIBE_NUM_INTF_ADDR_PRESENT,
+    NAN_REQ_ATTR_SUBSCRIBE_INTF_ADDR,
+    NAN_REQ_ATTR_SUBSCRIBE_RECV_IND_CFG,
+    NAN_REQ_ATTR_FOLLOWUP_ID,
+    NAN_REQ_ATTR_FOLLOWUP_REQUESTOR_ID,
+    NAN_REQ_ATTR_FOLLOWUP_ADDR,
+    NAN_REQ_ATTR_FOLLOWUP_PRIORITY,
+    NAN_REQ_ATTR_FOLLOWUP_SERVICE_NAME_LEN,
+    NAN_REQ_ATTR_FOLLOWUP_SERVICE_NAME,
+    NAN_REQ_ATTR_FOLLOWUP_TX_WINDOW,
+    NAN_REQ_ATTR_FOLLOWUP_RECV_IND_CFG,
+} NAN_REQ_ATTRIBUTES;
+
+typedef enum {
+	NAN_REPLY_ATTR_STATUS_TYPE,
+	NAN_REPLY_ATTR_VALUE,
+	NAN_REPLY_ATTR_RESPONSE_TYPE,
+	NAN_REPLY_ATTR_PUBLISH_SUBSCRIBE_TYPE,
+	NAN_REPLY_ATTR_CAP_MAX_CONCURRENT_CLUSTER,
+	NAN_REPLY_ATTR_CAP_MAX_PUBLISHES,
+	NAN_REPLY_ATTR_CAP_MAX_SUBSCRIBES,
+	NAN_REPLY_ATTR_CAP_MAX_SERVICE_NAME_LEN,
+	NAN_REPLY_ATTR_CAP_MAX_MATCH_FILTER_LEN,
+	NAN_REPLY_ATTR_CAP_MAX_TOTAL_MATCH_FILTER_LEN,
+	NAN_REPLY_ATTR_CAP_MAX_SERVICE_SPECIFIC_INFO_LEN,
+	NAN_REPLY_ATTR_CAP_MAX_VSA_DATA_LEN,
+	NAN_REPLY_ATTR_CAP_MAX_MESH_DATA_LEN,
+	NAN_REPLY_ATTR_CAP_MAX_NDI_INTERFACES,
+	NAN_REPLY_ATTR_CAP_MAX_NDP_SESSIONS,
+	NAN_REPLY_ATTR_CAP_MAX_APP_INFO_LEN,
+} NAN_RESP_ATTRIBUTES;
+
+typedef enum {
+    NAN_EVT_ATTR_MATCH_PUBLISH_SUBSCRIBE_ID,
+    NAN_EVT_ATTR_MATCH_REQUESTOR_INSTANCE_ID,
+    NAN_EVT_ATTR_MATCH_ADDR,
+    NAN_EVT_ATTR_MATCH_SERVICE_SPECIFIC_INFO_LEN,
+    NAN_EVT_ATTR_MATCH_SERVICE_SPECIFIC_INFO,
+    NAN_EVT_ATTR_MATCH_SDF_MATCH_FILTER_LEN,
+    NAN_EVT_ATTR_MATCH_SDF_MATCH_FILTER,
+    NAN_EVT_ATTR_MATCH_MATCH_OCCURED_FLAG,
+    NAN_EVT_ATTR_MATCH_OUT_OF_RESOURCE_FLAG,
+    NAN_EVT_ATTR_MATCH_RSSI_VALUE,
+/*CONN_CAPABILITY*/
+    NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_WFD_SUPPORTED,
+    NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_WFDS_SUPPORTED,
+    NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_TDLS_SUPPORTED,
+    NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_IBSS_SUPPORTED,
+    NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_MESH_SUPPORTED,
+    NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_WLAN_INFRA_FIELD,
+    NAN_EVT_ATTR_MATCH_NUM_RX_DISCOVERY_ATTR,
+    NAN_EVT_ATTR_MATCH_RX_DISCOVERY_ATTR,
+/*NANRECEIVEPOSTDISCOVERY DISCOVERY_ATTR,*/
+    NAN_EVT_ATTR_MATCH_DISC_ATTR_TYPE,
+    NAN_EVT_ATTR_MATCH_DISC_ATTR_ROLE,
+    NAN_EVT_ATTR_MATCH_DISC_ATTR_DURATION,
+    NAN_EVT_ATTR_MATCH_DISC_ATTR_AVAIL_INTERVAL_BITMAP,
+    NAN_EVT_ATTR_MATCH_DISC_ATTR_MAPID,
+    NAN_EVT_ATTR_MATCH_DISC_ATTR_ADDR,
+    NAN_EVT_ATTR_MATCH_DISC_ATTR_MESH_ID_LEN,
+    NAN_EVT_ATTR_MATCH_DISC_ATTR_MESH_ID,
+    NAN_EVT_ATTR_MATCH_DISC_ATTR_INFRASTRUCTURE_SSID_LEN,
+    NAN_EVT_ATTR_MATCH_DISC_ATTR_INFRASTRUCTURE_SSID_VAL,
+
+    NAN_EVT_ATTR_MATCH_NUM_CHANS,
+    NAN_EVT_ATTR_MATCH_FAMCHAN,
+/*FAMCHAN[32],*/
+    NAN_EVT_ATTR_MATCH_FAM_ENTRY_CONTROL,
+    NAN_EVT_ATTR_MATCH_FAM_CLASS_VAL,
+    NAN_EVT_ATTR_MATCH_FAM_CHANNEL,
+    NAN_EVT_ATTR_MATCH_FAM_MAPID,
+    NAN_EVT_ATTR_MATCH_FAM_AVAIL_INTERVAL_BITMAP,
+    NAN_EVT_ATTR_MATCH_CLUSTER_ATTRIBUTE_LEN,
+    NAN_EVT_ATTR_MATCH_CLUSTER_ATTRIBUTE,
+    NAN_EVT_ATTR_PUBLISH_ID,
+    NAN_EVT_ATTR_PUBLISH_REASON,
+    NAN_EVT_ATTR_SUBSCRIBE_ID,
+    NAN_EVT_ATTR_SUBSCRIBE_REASON,
+    NAN_EVT_ATTR_DISABLED_REASON,
+    NAN_EVT_ATTR_FOLLOWUP_PUBLISH_SUBSCRIBE_ID,
+    NAN_EVT_ATTR_FOLLOWUP_REQUESTOR_INSTANCE_ID,
+    NAN_EVT_ATTR_FOLLOWUP_ADDR,
+    NAN_EVT_ATTR_FOLLOWUP_DW_OR_FAW,
+    NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO_LEN,
+    NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO,
+    NAN_EVT_ATTR_DISCOVERY_ENGINE_EVT_TYPE	,
+    NAN_EVT_ATTR_DISCOVERY_ENGINE_MAC_ADDR,
+    NAN_EVT_ATTR_DISCOVERY_ENGINE_CLUSTER
+
+} NAN_EVT_ATTRIBUTES;
+
+class NanCommand : public WifiCommand {
+    static NanCallbackHandler callbackEventHandler;
+    int subscribeID[2];
+    int publishID[2];
+    int followupID[2];
+    int version;
+    NanCapabilities capabilities;
+
+    void registerNanEvents(void) {
+        registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_PUBLISH_TERMINATED);
+        registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_MATCH);
+        registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_MATCH_EXPIRED);
+        registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_SUBSCRIBE_TERMINATED);
+        registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_FOLLOWUP);
+        registerVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_DISCOVERY_ENGINE);
+    }
+
+    void unregisterNanEvents(void) {
+        unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_PUBLISH_TERMINATED);
+        unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_MATCH);
+        unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_MATCH_EXPIRED);
+        unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_SUBSCRIBE_TERMINATED);
+        unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_FOLLOWUP);
+        unregisterVendorHandler(GOOGLE_OUI, SLSI_NAN_EVENT_DISCOVERY_ENGINE);
+    }
+
+    int processResponse(WifiEvent &reply, NanResponseMsg *response) {
+        NanCapabilities *capabilities = &response->body.nan_capabilities;
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        unsigned int val;
+
+        for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
+            switch(nl_itr.get_type()) {
+            case NAN_REPLY_ATTR_STATUS_TYPE:
+                response->status = NanStatusType(nl_itr.get_u32());
+                break;
+            case NAN_REPLY_ATTR_VALUE:
+                val = nl_itr.get_u32();
+                if (val) {
+                    strncpy(response->nan_error, "Lower_layer_error",NAN_ERROR_STR_LEN);
+                }
+                break;
+            case NAN_REPLY_ATTR_RESPONSE_TYPE:
+                response->response_type = NanResponseType(nl_itr.get_u32());
+                break;
+            case NAN_REPLY_ATTR_PUBLISH_SUBSCRIBE_TYPE:
+                response->body.publish_response.publish_id = nl_itr.get_u16();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_CONCURRENT_CLUSTER:
+                capabilities->max_concurrent_nan_clusters = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_PUBLISHES:
+                capabilities->max_publishes = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_SUBSCRIBES:
+                capabilities->max_subscribes = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_SERVICE_NAME_LEN:
+                capabilities->max_service_name_len = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_MATCH_FILTER_LEN:
+                capabilities->max_match_filter_len = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_TOTAL_MATCH_FILTER_LEN:
+                capabilities->max_total_match_filter_len = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_SERVICE_SPECIFIC_INFO_LEN:
+                capabilities->max_service_specific_info_len = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_VSA_DATA_LEN:
+                capabilities->max_vsa_data_len = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_MESH_DATA_LEN:
+                capabilities->max_mesh_data_len = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_NDI_INTERFACES:
+                capabilities->max_ndi_interfaces = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_NDP_SESSIONS:
+                capabilities->max_ndp_sessions = nl_itr.get_u32();
+                break;
+            case NAN_REPLY_ATTR_CAP_MAX_APP_INFO_LEN:
+                capabilities->max_app_info_len = nl_itr.get_u32();
+                break;
+            default :
+                ALOGE("received unknown type(%d) in response", nl_itr.get_type());
+                return NL_SKIP;
+            }
+        }
+        this->capabilities = *capabilities;
+        return NL_OK;
+    }
+
+    int processMatchEvent(WifiEvent &event) {
+        NanMatchInd ind;
+        memset(&ind,0,sizeof(NanMatchInd));
+        int famchan_idx = 0, disc_idx = 0;
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+
+        for(nl_iterator nl_itr(vendor_data); nl_itr.has_next(); nl_itr.next()) {
+            switch(nl_itr.get_type()) {
+            case NAN_EVT_ATTR_MATCH_PUBLISH_SUBSCRIBE_ID:
+                ind.publish_subscribe_id = nl_itr.get_u16();
+                break;
+            case NAN_EVT_ATTR_MATCH_REQUESTOR_INSTANCE_ID:
+                ind.requestor_instance_id = nl_itr.get_u32();
+                break;
+            case NAN_EVT_ATTR_MATCH_ADDR:
+                memcpy(ind.addr, nl_itr.get_data(), NAN_MAC_ADDR_LEN);
+                break;
+            case NAN_EVT_ATTR_MATCH_SERVICE_SPECIFIC_INFO_LEN:
+                ind.service_specific_info_len = nl_itr.get_u16();
+                break;
+            case NAN_EVT_ATTR_MATCH_SERVICE_SPECIFIC_INFO:
+                memcpy(ind.service_specific_info, nl_itr.get_data(), ind.service_specific_info_len);
+                break;
+            case NAN_EVT_ATTR_MATCH_SDF_MATCH_FILTER_LEN:
+                ind.sdf_match_filter_len = nl_itr.get_u16();
+                break;
+            case NAN_EVT_ATTR_MATCH_SDF_MATCH_FILTER:
+                memcpy(ind.sdf_match_filter, nl_itr.get_data(), ind.sdf_match_filter_len);
+                break;
+            case NAN_EVT_ATTR_MATCH_MATCH_OCCURED_FLAG:
+                ind.match_occured_flag = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_OUT_OF_RESOURCE_FLAG:
+                ind.out_of_resource_flag = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_RSSI_VALUE:
+                ind.rssi_value = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_IBSS_SUPPORTED:
+                ind.conn_capability.is_ibss_supported = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_WFD_SUPPORTED:
+                ind.conn_capability.is_wfd_supported = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_WFDS_SUPPORTED:
+                ind.conn_capability.is_wfds_supported = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_TDLS_SUPPORTED:
+                ind.conn_capability.is_tdls_supported = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_IS_MESH_SUPPORTED:
+                ind.conn_capability.is_mesh_supported= nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_CONN_CAPABILITY_WLAN_INFRA_FIELD:
+                ind.conn_capability.wlan_infra_field = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_NUM_RX_DISCOVERY_ATTR:
+                ind.num_rx_discovery_attr = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_RX_DISCOVERY_ATTR:
+                NanReceivePostDiscovery *disc_attr;
+                disc_attr = &ind.discovery_attr[disc_idx];
+                disc_idx++;
+                for(nl_iterator nl_nested_itr((struct nlattr *)nl_itr.get_data()); nl_nested_itr.has_next(); nl_nested_itr.next()) {
+                    switch(nl_nested_itr.get_type()) {
+                    case NAN_EVT_ATTR_MATCH_DISC_ATTR_TYPE:
+                        disc_attr->type = (NanConnectionType)nl_nested_itr.get_u8();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_DISC_ATTR_ROLE:
+                        disc_attr->role = (NanDeviceRole)nl_nested_itr.get_u8();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_DISC_ATTR_DURATION:
+                        disc_attr->duration = (NanAvailDuration)nl_nested_itr.get_u8();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_DISC_ATTR_AVAIL_INTERVAL_BITMAP:
+                        disc_attr->avail_interval_bitmap = nl_nested_itr.get_u32();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_DISC_ATTR_MAPID:
+                        disc_attr->mapid = nl_nested_itr.get_u8();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_DISC_ATTR_ADDR:
+                        memcpy(disc_attr->addr, nl_nested_itr.get_data(), NAN_MAC_ADDR_LEN);
+                        break;
+                    case NAN_EVT_ATTR_MATCH_DISC_ATTR_MESH_ID_LEN:
+                        disc_attr->mesh_id_len = nl_nested_itr.get_u8();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_DISC_ATTR_MESH_ID:
+                        memcpy(disc_attr->mesh_id, nl_nested_itr.get_data(), disc_attr->mesh_id_len);
+                        break;
+                    case NAN_EVT_ATTR_MATCH_DISC_ATTR_INFRASTRUCTURE_SSID_LEN:
+                        disc_attr->infrastructure_ssid_len = nl_nested_itr.get_u16();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_DISC_ATTR_INFRASTRUCTURE_SSID_VAL:
+                        memcpy(disc_attr->infrastructure_ssid_val, nl_nested_itr.get_data(), disc_attr->infrastructure_ssid_len);
+                        break;
+                    }
+                }
+                break;
+            case NAN_EVT_ATTR_MATCH_NUM_CHANS:
+                ind.num_chans = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_FAMCHAN:
+                NanFurtherAvailabilityChannel *famchan;
+                famchan = &ind.famchan[famchan_idx];
+                famchan_idx++;
+                for(nl_iterator nl_nested_itr((struct nlattr *)nl_itr.get_data()); nl_nested_itr.has_next(); nl_nested_itr.next()) {
+                    switch(nl_nested_itr.get_type()) {
+                    case NAN_EVT_ATTR_MATCH_FAM_ENTRY_CONTROL:
+                        famchan->entry_control = (NanAvailDuration)nl_nested_itr.get_u8();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_FAM_CLASS_VAL:
+                        famchan->class_val = nl_nested_itr.get_u8();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_FAM_CHANNEL:
+                        famchan->channel = nl_nested_itr.get_u8();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_FAM_MAPID:
+                        famchan->mapid = nl_nested_itr.get_u8();
+                        break;
+                    case NAN_EVT_ATTR_MATCH_FAM_AVAIL_INTERVAL_BITMAP:
+                        famchan->avail_interval_bitmap = nl_nested_itr.get_u32();
+                        break;
+                    }
+                }
+                break;
+            case NAN_EVT_ATTR_MATCH_CLUSTER_ATTRIBUTE_LEN:
+                ind.cluster_attribute_len = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_MATCH_CLUSTER_ATTRIBUTE:
+                memcpy(ind.cluster_attribute, nl_itr.get_data(), ind.cluster_attribute_len);
+                break;
+            }
+        }
+
+        if (this->callbackEventHandler.EventMatch)
+            this->callbackEventHandler.EventMatch(&ind);
+        return NL_OK;
+    }
+
+    int processMatchExpiredEvent(WifiEvent &event) {
+        NanMatchExpiredInd ind;
+        memset(&ind,0,sizeof(NanMatchExpiredInd));
+
+        for(nl_iterator nl_itr((struct nlattr *)event.get_vendor_data()); nl_itr.has_next(); nl_itr.next()) {
+            switch(nl_itr.get_type()) {
+            case NAN_EVT_ATTR_MATCH_PUBLISH_SUBSCRIBE_ID:
+                ind.publish_subscribe_id = nl_itr.get_u16();
+                break;
+            case NAN_EVT_ATTR_MATCH_REQUESTOR_INSTANCE_ID:
+                ind.requestor_instance_id = nl_itr.get_u32();
+                break;
+            default :
+                ALOGE("processMatchExpiredEvent: unknown attribute(%d)", nl_itr.get_type());
+                return NL_SKIP;
+            }
+        }
+
+        if (callbackEventHandler.EventMatchExpired)
+            callbackEventHandler.EventMatchExpired(&ind);
+
+        return NL_OK;
+    }
+
+    int processPublishTerminatedEvent(WifiEvent &event) {
+        NanPublishTerminatedInd ind;
+        memset(&ind,0,sizeof(ind));
+
+        for(nl_iterator nl_itr((struct nlattr *)event.get_vendor_data()); nl_itr.has_next(); nl_itr.next()) {
+            switch(nl_itr.get_type()) {
+            case NAN_EVT_ATTR_PUBLISH_ID:
+                ind.publish_id = nl_itr.get_u16();
+                break;
+            case NAN_EVT_ATTR_PUBLISH_REASON:
+                ind.reason = (NanStatusType)nl_itr.get_u32();
+                break;
+            default :
+                ALOGE("processPublishTerminatedEvent: unknown attribute(%d)", nl_itr.get_type());
+                return NL_SKIP;
+            }
+        }
+
+        if (callbackEventHandler.EventPublishTerminated)
+            callbackEventHandler.EventPublishTerminated(&ind);
+
+        return NL_OK;
+
+    }
+
+    int processSubscribeTerminatedEvent(WifiEvent &event) {
+        NanSubscribeTerminatedInd ind;
+        memset(&ind,0,sizeof(ind));
+
+        for(nl_iterator nl_itr((struct nlattr *)event.get_vendor_data()); nl_itr.has_next(); nl_itr.next()) {
+            switch(nl_itr.get_type()) {
+            case NAN_EVT_ATTR_SUBSCRIBE_ID:
+                ind.subscribe_id = nl_itr.get_u16();
+                break;
+            case NAN_EVT_ATTR_SUBSCRIBE_REASON:
+                ind.reason = (NanStatusType)nl_itr.get_u32();
+                break;
+            default :
+                ALOGE("processSubscribeTerminatedEvent: unknown attribute(%d)", nl_itr.get_type());
+                return NL_SKIP;
+            }
+        }
+
+        if (callbackEventHandler.EventSubscribeTerminated)
+            callbackEventHandler.EventSubscribeTerminated(&ind);
+
+        return NL_OK;
+    }
+
+    int processFollowupEvent(WifiEvent &event) {
+        NanFollowupInd ind;
+        memset(&ind,0,sizeof(ind));
+
+        for(nl_iterator nl_itr((struct nlattr *)event.get_vendor_data()); nl_itr.has_next(); nl_itr.next()) {
+            switch(nl_itr.get_type()) {
+            case NAN_EVT_ATTR_FOLLOWUP_PUBLISH_SUBSCRIBE_ID:
+                ind.publish_subscribe_id = nl_itr.get_u16();
+                break;
+            case NAN_EVT_ATTR_FOLLOWUP_REQUESTOR_INSTANCE_ID:
+                ind.requestor_instance_id = nl_itr.get_u32();
+                break;
+            case NAN_EVT_ATTR_FOLLOWUP_ADDR:
+                memcpy(ind.addr, nl_itr.get_data(), NAN_MAC_ADDR_LEN);
+                break;
+            case NAN_EVT_ATTR_FOLLOWUP_DW_OR_FAW:
+                ind.dw_or_faw = nl_itr.get_u8();
+                break;
+            case NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO_LEN:
+                ind.service_specific_info_len = nl_itr.get_u16();
+                break;
+            case NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO:
+                memcpy(ind.service_specific_info, nl_itr.get_data(), ind.service_specific_info_len);
+                break;
+            default :
+                ALOGE("processNanDisabledEvent: unknown attribute(%d)", nl_itr.get_type());
+                return NL_SKIP;
+            }
+        }
+
+        if (callbackEventHandler.EventFollowup)
+            callbackEventHandler.EventFollowup(&ind);
+
+        return NL_OK;
+    }
+
+    int processNanDisabledEvent(WifiEvent &event) {
+        NanDisabledInd ind;
+        memset(&ind,0,sizeof(ind));
+
+        for(nl_iterator nl_itr((struct nlattr *)event.get_vendor_data()); nl_itr.has_next(); nl_itr.next()) {
+            switch(nl_itr.get_type()) {
+            case NAN_EVT_ATTR_DISABLED_REASON:
+                ind.reason = (NanStatusType)nl_itr.get_u32();
+                break;
+            default :
+                ALOGE("processNanDisabledEvent: unknown attribute(%d)", nl_itr.get_type());
+                return NL_SKIP;
+            }
+        }
+
+        if (callbackEventHandler.EventDisabled)
+            callbackEventHandler.EventDisabled(&ind);
+
+        return NL_OK;
+    }
+
+    int processNanDiscoveryEvent(WifiEvent &event) {
+        NanDiscEngEventInd ind;
+        memset(&ind,0,sizeof(ind));
+        u8 *addr = NULL;
+
+        for(nl_iterator nl_itr((struct nlattr *)event.get_vendor_data()); nl_itr.has_next(); nl_itr.next()) {
+            switch(nl_itr.get_type()) {
+            case NAN_EVT_ATTR_DISCOVERY_ENGINE_EVT_TYPE:
+                ind.event_type = (NanDiscEngEventType)nl_itr.get_u16();
+                break;
+            case NAN_EVT_ATTR_DISCOVERY_ENGINE_MAC_ADDR:
+                addr = (u8 *)nl_itr.get_data();
+                break;
+            default :
+                ALOGE("processNanDiscoveryEvent: unknown attribute(%d)", nl_itr.get_type());
+                return NL_SKIP;
+            }
+        }
+        if (addr) {
+            if (ind.event_type == NAN_EVENT_ID_DISC_MAC_ADDR)
+                memcpy(ind.data.mac_addr.addr, addr, NAN_MAC_ADDR_LEN);
+            else
+                memcpy(ind.data.cluster.addr, addr, NAN_MAC_ADDR_LEN);
+        } else {
+            ALOGE("processNanDiscoveryEvent: No Mac/cluster Address");
+        }
+
+        if (callbackEventHandler.EventDiscEngEvent)
+            callbackEventHandler.EventDiscEngEvent(&ind);
+
+        return NL_OK;
+    }
+
+public:
+    NanCommand(wifi_interface_handle iface, int id)
+        : WifiCommand(iface, id)
+    {
+        subscribeID[0] = 0;
+        subscribeID[1] = 0;
+        publishID[0] = 0;
+        publishID[1] = 0;
+        followupID[0] = 0;
+        followupID[0] = 0;
+        version = 0;
+        memset(&capabilities, 0, sizeof(capabilities));
+    }
+
+    int enable(NanEnableRequest *msg) {
+        ALOGD("Start NAN...");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_ENABLE);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to create WifiRequest");
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!data) {
+            ALOGE("enable: request.attr_start fail");
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        }
+        /* Valid master pref values are 2-254 */
+        int master_pref;
+        if (msg->master_pref < 2)
+            master_pref = 2;
+        else if (msg->master_pref > 254)
+            master_pref = 254;
+        else
+            master_pref = msg->master_pref;
+        result = request.put_u8(NAN_REQ_ATTR_MASTER_PREF, master_pref);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put master_pref");
+
+        result = request.put_u16(NAN_REQ_ATTR_CLUSTER_LOW, msg->cluster_low);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put cluster_low");
+
+        result = request.put_u16(NAN_REQ_ATTR_CLUSTER_HIGH, msg->cluster_high);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "enable:Failed to put cluster_high");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_support_5g, msg->support_5g_val,
+                    NAN_REQ_ATTR_SUPPORT_5G_VAL, request, result, "enable:Failed to put support_5g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_sid_beacon, msg->sid_beacon_val,
+                    NAN_REQ_ATTR_SID_BEACON_VAL, request, result, "enable:Failed to put sid_beacon_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_rssi_close, msg->rssi_close_2dot4g_val,
+                    NAN_REQ_ATTR_RSSI_CLOSE_2G4_VAL, request, result, "enable:Failed to put rssi_close_2dot4g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_rssi_middle, msg->rssi_middle_2dot4g_val,
+                    NAN_REQ_ATTR_RSSI_MIDDLE_2G4_VAL, request, result, "enable:Failed to put rssi_middle_2dot4g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_rssi_proximity, msg->rssi_proximity_2dot4g_val,
+                    NAN_REQ_ATTR_RSSI_PROXIMITY_2G4_VAL, request, result, "enable:Failed to put rssi_proximity_2dot4g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_hop_count_limit, msg->hop_count_limit_val,
+                    NAN_REQ_ATTR_HOP_COUNT_LIMIT_VAL, request, result, "enable:Failed to put hop_count_limit_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_support, msg->support_2dot4g_val,
+                    NAN_REQ_ATTR_SUPPORT_2G4_VAL, request, result, "enable:Failed to put support_2dot4g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_beacons, msg->beacon_2dot4g_val,
+                    NAN_REQ_ATTR_BEACONS_2G4_VAL, request, result, "enable:Failed to put beacon_2dot4g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_2dot4g_sdf, msg->sdf_2dot4g_val,
+                    NAN_REQ_ATTR_SDF_2G4_VAL, request, result, "enable:Failed to put sdf_2dot4g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_beacons, msg->beacon_5g_val,
+                    NAN_REQ_ATTR_BEACON_5G_VAL, request, result, "enable:Failed to put beacon_5g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_sdf, msg->sdf_5g_val,
+                    NAN_REQ_ATTR_SDF_5G_VAL, request, result, "enable:Failed to put sdf_5g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_rssi_close, msg->rssi_close_5g_val,
+                    NAN_REQ_ATTR_RSSI_CLOSE_5G_VAL, request, result, "enable:Failed to put rssi_close_5g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_rssi_middle, msg->rssi_middle_5g_val,
+                    NAN_REQ_ATTR_RSSI_MIDDLE_5G_VAL, request, result, "enable:Failed to put rssi_middle_5g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_rssi_close_proximity, msg->rssi_close_proximity_5g_val,
+                    NAN_REQ_ATTR_RSSI_CLOSE_PROXIMITY_5G_VAL, request, result, "enable:Failed to put rssi_close_proximity_5g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_rssi_window_size, msg->rssi_window_size_val,
+                    NAN_REQ_ATTR_RSSI_WINDOW_SIZE_VAL, request, result, "enable:Failed to put rssi_window_size_val");
+
+        CHECK_CONFIG_PUT_32_RETURN_FAIL(msg->config_oui, msg->oui_val,
+                    NAN_REQ_ATTR_OUI_VAL, request, result, "enable:Failed to put oui_val");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->config_intf_addr, msg->intf_addr_val, NAN_MAC_ADDR_LEN,
+                    NAN_REQ_ATTR_MAC_ADDR_VAL, request, result, "enable:Failed to put intf_addr_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->config_cluster_attribute_val,
+                    NAN_REQ_ATTR_CLUSTER_VAL, request, result, "enable:Failed to put config_cluster_attribute_val");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->config_scan_params, msg->scan_params_val.dwell_time, sizeof(msg->scan_params_val.dwell_time),
+                    NAN_REQ_ATTR_SOCIAL_CH_SCAN_DWELL_TIME, request, result, "enable:Failed to put scan_params_val.dwell_time");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->config_scan_params, msg->scan_params_val.scan_period, sizeof(msg->scan_params_val.scan_period),
+                    NAN_REQ_ATTR_SOCIAL_CH_SCAN_PERIOD, request, result, "enable:Failed to put scan_params_val.scan_period");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_random_factor_force, msg->random_factor_force_val,
+                    NAN_REQ_ATTR_RANDOM_FACTOR_FORCE_VAL, request, result, "enable:Failed to put random_factor_force_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_hop_count_force, msg->hop_count_force_val,
+                    NAN_REQ_ATTR_HOP_COUNT_FORCE_VAL, request, result, "enable:Failed to put hop_count_force_val");
+
+        CHECK_CONFIG_PUT_32_RETURN_FAIL(msg->config_24g_channel, msg->channel_24g_val,
+                    NAN_REQ_ATTR_CHANNEL_2G4_MHZ_VAL, request, result, "enable:Failed to put channel_24g_val");
+
+        CHECK_CONFIG_PUT_32_RETURN_FAIL(msg->config_5g_channel, msg->channel_5g_val,
+                    NAN_REQ_ATTR_CHANNEL_5G_MHZ_VAL, request, result, "enable:Failed to put channel_5g_val");
+
+        request.attr_end(data);
+
+        registerNanEvents();
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to NAN; result = %d", result);
+            unregisterNanEvents();
+        } else {
+            ALOGD("Start NAN...success");
+        }
+        return result;
+    }
+
+    int disable()
+    {
+        ALOGD("Stop NAN...");
+        WifiRequest request(familyId(), ifaceId());
+
+        unregisterNanEvents();
+
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_DISABLE);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "disable:Failed to create WifiRequest");
+        result = requestResponse(request);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "disable:Failed to requestResponse");
+        return result;
+    }
+
+    int config(NanConfigRequest *msg) {
+        ALOGD("NAN config...");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_CONFIG);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "config:Failed to create WifiRequest");
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!data) {
+            ALOGE("config: request.attr_start fail");
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        }
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_sid_beacon, msg->sid_beacon,
+                    NAN_REQ_ATTR_SID_BEACON_VAL, request, result, "config:Failed to put sid_beacon");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_rssi_proximity, msg->rssi_proximity,
+                    NAN_REQ_ATTR_RSSI_PROXIMITY_2G4_VAL, request, result, "config:Failed to put rssi_proximity");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_master_pref, msg->master_pref,
+                    NAN_REQ_ATTR_MASTER_PREF, request, result, "config:Failed to put master_pref");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_5g_rssi_close_proximity, msg->rssi_close_proximity_5g_val,
+                    NAN_REQ_ATTR_RSSI_CLOSE_PROXIMITY_5G_VAL, request, result, "config:Failed to put rssi_close_proximity_5g_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_rssi_window_size, msg->rssi_window_size_val,
+                    NAN_REQ_ATTR_RSSI_WINDOW_SIZE_VAL, request, result, "config:Failed to put rssi_window_size_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->config_cluster_attribute_val,
+                    NAN_REQ_ATTR_CLUSTER_VAL, request, result, "config:Failed to put config_cluster_attribute_val");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->config_scan_params, msg->scan_params_val.dwell_time, sizeof(msg->scan_params_val.dwell_time),
+                    NAN_REQ_ATTR_SOCIAL_CH_SCAN_DWELL_TIME, request, result, "config:Failed to put scan_params_val.dwell_time");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->config_scan_params, msg->scan_params_val.scan_period, sizeof(msg->scan_params_val.scan_period),
+                    NAN_REQ_ATTR_SOCIAL_CH_SCAN_PERIOD, request, result, "config:Failed to put scan_params_val.scan_period");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_random_factor_force, msg->random_factor_force_val,
+                    NAN_REQ_ATTR_RANDOM_FACTOR_FORCE_VAL, request, result, "config:Failed to put random_factor_force_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_hop_count_force, msg->hop_count_force_val,
+                    NAN_REQ_ATTR_HOP_COUNT_FORCE_VAL, request, result, "config:Failed to put hop_count_force_val");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.payload_transmit_flag,
+                    NAN_REQ_ATTR_CONN_CAPABILITY_PAYLOAD_TX, request, result, "config:Failed to put payload_transmit_flag");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.is_wfd_supported,
+                    NAN_REQ_ATTR_CONN_CAPABILITY_WFD, request, result, "config:Failed to put is_wfd_supported");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.is_wfds_supported,
+                    NAN_REQ_ATTR_CONN_CAPABILITY_WFDS, request, result, "config:Failed to put is_wfds_supported");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.is_tdls_supported,
+                    NAN_REQ_ATTR_CONN_CAPABILITY_TDLS, request, result, "config:Failed to put is_tdls_supported");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.is_ibss_supported,
+                    NAN_REQ_ATTR_CONN_CAPABILITY_IBSS, request, result, "config:Failed to put is_ibss_supported");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.is_mesh_supported,
+                    NAN_REQ_ATTR_CONN_CAPABILITY_MESH, request, result, "config:Failed to put is_mesh_supported");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->config_conn_capability, msg->conn_capability_val.wlan_infra_field,
+                    NAN_REQ_ATTR_CONN_CAPABILITY_WLAN_INFRA, request, result, "config:Failed to put wlan_infra_field");
+
+        if (msg->num_config_discovery_attr) {
+            CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->num_config_discovery_attr,
+                        NAN_REQ_ATTR_DISCOVERY_ATTR_NUM_ENTRIES, request, result, "config:Failed to put msg->num_config_discovery_attr");
+            for (int i = 0; i < msg->num_config_discovery_attr; i++) {
+                nlattr *nl_disc_attribute = request.attr_start(NAN_REQ_ATTR_DISCOVERY_ATTR_VAL);
+                NanTransmitPostDiscovery *discovery_attr = &msg->discovery_attr_val[i];
+                CHECK_CONFIG_PUT_8_RETURN_FAIL(1, discovery_attr->type,
+                    NAN_REQ_ATTR_CONN_TYPE, request, result, "config:Failed to put discovery_attr->type");
+                CHECK_CONFIG_PUT_8_RETURN_FAIL(1, discovery_attr->role,
+                    NAN_REQ_ATTR_NAN_ROLE, request, result, "config:Failed to put discovery_attr->role");
+                CHECK_CONFIG_PUT_8_RETURN_FAIL(1, discovery_attr->transmit_freq,
+                    NAN_REQ_ATTR_TRANSMIT_FREQ, request, result, "config:Failed to put discovery_attr->transmit_freq");
+                CHECK_CONFIG_PUT_8_RETURN_FAIL(1, discovery_attr->duration,
+                    NAN_REQ_ATTR_AVAILABILITY_DURATION, request, result, "config:Failed to put discovery_attr->duration");
+                CHECK_CONFIG_PUT_32_RETURN_FAIL(1, discovery_attr->avail_interval_bitmap,
+                    NAN_REQ_ATTR_AVAILABILITY_INTERVAL, request, result, "config:Failed to put discovery_attr->avail_interval_bitmap");
+                CHECK_CONFIG_PUT_RETURN_FAIL(1, discovery_attr->addr, NAN_MAC_ADDR_LEN,
+                    NAN_REQ_ATTR_MAC_ADDR_VAL, request, result, "config:Failed to put discovery_attr->addr");
+                CHECK_CONFIG_PUT_16_RETURN_FAIL(1, discovery_attr->mesh_id_len,
+                    NAN_REQ_ATTR_MESH_ID_LEN, request, result, "config:Failed to put discovery_attr->mesh_id");
+                CHECK_CONFIG_PUT_RETURN_FAIL(discovery_attr->mesh_id_len, discovery_attr->mesh_id, discovery_attr->mesh_id_len,
+                    NAN_REQ_ATTR_MESH_ID, request, result, "config:Failed to put discovery_attr->mesh_id");
+                CHECK_CONFIG_PUT_16_RETURN_FAIL(1, discovery_attr->infrastructure_ssid_len,
+                    NAN_REQ_ATTR_INFRASTRUCTURE_SSID_LEN, request, result, "config:Failed to put discovery_attr->infrastructure_ssid_val");
+                CHECK_CONFIG_PUT_RETURN_FAIL(discovery_attr->infrastructure_ssid_len, discovery_attr->infrastructure_ssid_val, discovery_attr->infrastructure_ssid_len,
+                    NAN_REQ_ATTR_INFRASTRUCTURE_SSID, request, result, "config:Failed to put discovery_attr->infrastructure_ssid_val");
+                request.attr_end(nl_disc_attribute);
+            }
+        }
+
+        if (msg->config_fam) {
+            CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->fam_val.numchans,
+                        NAN_REQ_ATTR_FURTHER_AVAIL_NUM_ENTRIES, request, result, "config:Failed to put msg->fam_val.numchans");
+            for (int i = 0; i < msg->fam_val.numchans; i++) {
+                nlattr *nl_fam_attribute = request.attr_start(NAN_REQ_ATTR_FURTHER_AVAIL_VAL);
+                NanFurtherAvailabilityChannel *further_avail_chan = &msg->fam_val.famchan[i];
+                CHECK_CONFIG_PUT_8_RETURN_FAIL(1, further_avail_chan->entry_control,
+                            NAN_REQ_ATTR_FURTHER_AVAIL_ENTRY_CTRL, request, result, "config:Failed to put further_avail_chan->entry_control");
+                CHECK_CONFIG_PUT_8_RETURN_FAIL(1, further_avail_chan->class_val,
+                            NAN_REQ_ATTR_FURTHER_AVAIL_CHAN_CLASS, request, result, "config:Failed to put further_avail_chan->class_val");
+                CHECK_CONFIG_PUT_8_RETURN_FAIL(1, further_avail_chan->channel,
+                            NAN_REQ_ATTR_FURTHER_AVAIL_CHAN, request, result, "config:Failed to put further_avail_chan->channel");
+                CHECK_CONFIG_PUT_8_RETURN_FAIL(1, further_avail_chan->mapid,
+                            NAN_REQ_ATTR_FURTHER_AVAIL_CHAN_MAPID, request, result, "config:Failed to put further_avail_chan->mapid");
+                CHECK_CONFIG_PUT_32_RETURN_FAIL(1, further_avail_chan->avail_interval_bitmap,
+                            NAN_REQ_ATTR_FURTHER_AVAIL_INTERVAL_BITMAP, request, result, "config:Failed to put further_avail_chan->avail_interval_bitmap");
+                request.attr_end(nl_fam_attribute);
+            }
+        }
+
+        request.attr_end(data);
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to set_config; result = %d", result);
+        } else {
+            ALOGD("NAN config...success");
+        }
+        return result;
+    }
+
+    static int setCallbackHandler(NanCallbackHandler handlers) {
+        callbackEventHandler = handlers;
+        return WIFI_SUCCESS;
+    }
+
+    static int getVersion(NanVersion *version) {
+        *version = SLSI_WIFI_HAL_NAN_VERSION;
+        return WIFI_SUCCESS;
+    }
+
+    int publish(NanPublishRequest *msg) {
+        ALOGD("NAN publish...");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_PUBLISH);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "publish:Failed to create WifiRequest");
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!data) {
+            ALOGE("publish: request.attr_start fail");
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        }
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->publish_id, msg->publish_id,
+                NAN_REQ_ATTR_PUBLISH_ID, request, result, "publish:Failed to put msg->publish_id");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->ttl, msg->ttl,
+                NAN_REQ_ATTR_PUBLISH_TTL, request, result, "publish:Failed to put msg->ttl");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->period,
+                NAN_REQ_ATTR_PUBLISH_PERIOD, request, result, "publish:Failed to put msg->period");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->publish_type,
+                NAN_REQ_ATTR_PUBLISH_TYPE, request, result, "publish:Failed to put msg->publish_type");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->tx_type,
+                NAN_REQ_ATTR_PUBLISH_TX_TYPE, request, result, "publish:Failed to put msg->tx_type");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->publish_count,
+                NAN_REQ_ATTR_PUBLISH_COUNT, request, result, "publish:Failed to put msg->publish_count");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->service_name_len, msg->service_name_len,
+                NAN_REQ_ATTR_PUBLISH_SERVICE_NAME_LEN, request, result, "publish:Failed to put msg->service_name_len");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->service_name_len, msg->service_name, msg->service_name_len,
+                NAN_REQ_ATTR_PUBLISH_SERVICE_NAME, request, result, "publish:Failed to put msg->service_name");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->publish_match_indicator,
+                NAN_REQ_ATTR_PUBLISH_MATCH_ALGO, request, result, "publish:Failed to put msg->publish_match_indicator");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info_len,
+                NAN_REQ_ATTR_PUBLISH_SERVICE_INFO_LEN, request, result, "publish:Failed to put msg->service_specific_info_len");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info, msg->service_specific_info_len,
+                NAN_REQ_ATTR_PUBLISH_SERVICE_INFO, request, result, "publish:Failed to put msg->service_specific_info");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->rx_match_filter_len, msg->rx_match_filter_len,
+                NAN_REQ_ATTR_PUBLISH_RX_MATCH_FILTER_LEN, request, result, "publish:Failed to put msg->rx_match_filter_len");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->rx_match_filter_len, msg->rx_match_filter, msg->rx_match_filter_len,
+                NAN_REQ_ATTR_PUBLISH_RX_MATCH_FILTER, request, result, "publish:Failed to put msg->rx_match_filter");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->tx_match_filter_len, msg->tx_match_filter_len,
+                NAN_REQ_ATTR_PUBLISH_TX_MATCH_FILTER_LEN, request, result, "publish:Failed to put msg->tx_match_filter_len");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->tx_match_filter_len, msg->tx_match_filter, msg->tx_match_filter_len,
+                NAN_REQ_ATTR_PUBLISH_TX_MATCH_FILTER, request, result, "publish:Failed to put msg->tx_match_filter");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->rssi_threshold_flag,
+                NAN_REQ_ATTR_PUBLISH_RSSI_THRESHOLD_FLAG, request, result, "publish:Failed to put msg->rssi_threshold_flag");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->connmap,
+                NAN_REQ_ATTR_PUBLISH_CONN_MAP, request, result, "publish:Failed to put msg->connmap");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->recv_indication_cfg,
+                NAN_REQ_ATTR_PUBLISH_RECV_IND_CFG, request, result, "publish:Failed to put msg->recv_indication_cfg");
+
+        request.attr_end(data);
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to publish; result = %d", result);
+        } else {
+            ALOGD("NAN publish...success");
+        }
+        return result;
+    }
+
+    int publishCancel(NanPublishCancelRequest *msg) {
+        ALOGD("NAN publishCancel...");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_PUBLISHCANCEL);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "publishCancel:Failed to create WifiRequest");
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!data) {
+            ALOGE("publishCancel: request.attr_start fail");
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        }
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->publish_id,
+                NAN_REQ_ATTR_PUBLISH_ID, request, result, "publishCancel:Failed to put msg->publish_id");
+
+        request.attr_end(data);
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to publishCancel; result = %d", result);
+        } else {
+            ALOGD("NAN publishCancel...success");
+        }
+        return result;
+
+    }
+
+    int subscribe(NanSubscribeRequest *msg) {
+        ALOGD("NAN subscribe...");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBE);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "subscribe:Failed to create WifiRequest");
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!data) {
+            ALOGE("subscribe: request.attr_start fail");
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        }
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->subscribe_id, msg->subscribe_id,
+                NAN_REQ_ATTR_SUBSCRIBE_ID, request, result, "subscribe:Failed to put msg->publish_id");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->ttl,
+                NAN_REQ_ATTR_SUBSCRIBE_TTL, request, result, "subscribe:Failed to put msg->ttl");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->period,
+                NAN_REQ_ATTR_SUBSCRIBE_PERIOD, request, result, "subscribe:Failed to put msg->period");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->subscribe_type,
+                NAN_REQ_ATTR_SUBSCRIBE_TYPE, request, result, "subscribe:Failed to put msg->subscribe_type");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->serviceResponseFilter,
+                NAN_REQ_ATTR_SUBSCRIBE_RESP_FILTER_TYPE, request, result, "subscribe:Failed to put msg->serviceResponseFilter");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->serviceResponseInclude,
+                NAN_REQ_ATTR_SUBSCRIBE_RESP_INCLUDE, request, result, "subscribe:Failed to put msg->serviceResponseInclude");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->useServiceResponseFilter,
+                NAN_REQ_ATTR_SUBSCRIBE_USE_RESP_FILTER, request, result, "subscribe:Failed to put msg->useServiceResponseFilter");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->ssiRequiredForMatchIndication,
+                NAN_REQ_ATTR_SUBSCRIBE_SSI_REQUIRED, request, result, "subscribe:Failed to put msg->ssiRequiredForMatchIndication");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->subscribe_match_indicator,
+                NAN_REQ_ATTR_SUBSCRIBE_MATCH_INDICATOR, request, result, "subscribe:Failed to put msg->subscribe_match_indicator");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->subscribe_count,
+                NAN_REQ_ATTR_SUBSCRIBE_COUNT, request, result, "subscribe:Failed to put msg->subscribe_count");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->service_name_len, msg->service_name_len,
+                NAN_REQ_ATTR_SUBSCRIBE_SERVICE_NAME_LEN, request, result, "subscribe:Failed to put msg->service_name_len");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->service_name_len, msg->service_name, msg->service_name_len,
+                NAN_REQ_ATTR_SUBSCRIBE_SERVICE_NAME, request, result, "subscribe:Failed to put msg->service_name");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info_len,
+                NAN_REQ_ATTR_SUBSCRIBE_SERVICE_INFO_LEN, request, result, "subscribe:Failed to put msg->service_specific_info_len");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info, msg->service_specific_info_len,
+                NAN_REQ_ATTR_SUBSCRIBE_SERVICE_INFO, request, result, "subscribe:Failed to put msg->service_specific_info");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->rx_match_filter_len, msg->rx_match_filter_len,
+                NAN_REQ_ATTR_SUBSCRIBE_RX_MATCH_FILTER_LEN, request, result, "subscribe:Failed to put msg->rx_match_filter_len");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->rx_match_filter_len, msg->rx_match_filter, msg->rx_match_filter_len,
+                NAN_REQ_ATTR_SUBSCRIBE_RX_MATCH_FILTER, request, result, "subscribe:Failed to put msg->rx_match_filter");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->tx_match_filter_len, msg->tx_match_filter_len,
+                NAN_REQ_ATTR_SUBSCRIBE_TX_MATCH_FILTER_LEN, request, result, "subscribe:Failed to put msg->tx_match_filter_len");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->tx_match_filter_len, msg->tx_match_filter, msg->tx_match_filter_len,
+                NAN_REQ_ATTR_SUBSCRIBE_TX_MATCH_FILTER, request, result, "subscribe:Failed to put msg->tx_match_filter");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->rssi_threshold_flag,
+                NAN_REQ_ATTR_SUBSCRIBE_RSSI_THRESHOLD_FLAG, request, result, "subscribe:Failed to put msg->rssi_threshold_flag");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->connmap,
+                NAN_REQ_ATTR_SUBSCRIBE_CONN_MAP, request, result, "subscribe:Failed to put msg->connmap");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(msg->num_intf_addr_present, msg->num_intf_addr_present,
+                NAN_REQ_ATTR_SUBSCRIBE_NUM_INTF_ADDR_PRESENT, request, result, "subscribe:Failed to put msg->num_intf_addr_present");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->num_intf_addr_present, msg->intf_addr, NAN_MAC_ADDR_LEN * msg->num_intf_addr_present,
+                NAN_REQ_ATTR_SUBSCRIBE_INTF_ADDR, request, result, "subscribe:Failed to put msg->intf_addr");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->recv_indication_cfg,
+                NAN_REQ_ATTR_SUBSCRIBE_RECV_IND_CFG, request, result, "subscribe:Failed to put msg->recv_indication_cfg");
+
+        request.attr_end(data);
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to subscribe; result = %d", result);
+        } else {
+            ALOGD("NAN subscribe...success");
+        }
+        return result;
+
+    }
+
+    int subscribeCancel(NanSubscribeCancelRequest *msg) {
+        ALOGD("NAN subscribeCancel...");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBECANCEL);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "subscribeCancel:Failed to create WifiRequest");
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!data) {
+            ALOGE("subscribeCancel: request.attr_start fail");
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        }
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->subscribe_id,
+                NAN_REQ_ATTR_SUBSCRIBE_ID, request, result, "subscribeCancel:Failed to put msg->subscribe_id");
+
+        request.attr_end(data);
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to subscribeCancel; result = %d", result);
+        } else {
+            ALOGD("NAN subscribeCancel...success");
+        }
+        return result;
+    }
+
+    int followup(NanTransmitFollowupRequest *msg) {
+        ALOGD("NAN followup...");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_TXFOLLOWUP);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "followup:Failed to create WifiRequest");
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        if (!data) {
+            ALOGE("followup: request.attr_start fail");
+            return WIFI_ERROR_OUT_OF_MEMORY;
+        }
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(1, msg->publish_subscribe_id,
+                NAN_REQ_ATTR_FOLLOWUP_ID, request, result, "followup:Failed to put msg->publish_subscribe_id");
+
+        CHECK_CONFIG_PUT_32_RETURN_FAIL(1, msg->requestor_instance_id,
+                NAN_REQ_ATTR_FOLLOWUP_REQUESTOR_ID, request, result, "followup:Failed to put msg->requestor_instance_id");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(1, msg->addr, NAN_MAC_ADDR_LEN,
+            NAN_REQ_ATTR_FOLLOWUP_ADDR, request, result, "followup:Failed to put msg->addr");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->priority,
+            NAN_REQ_ATTR_FOLLOWUP_PRIORITY, request, result, "followup:Failed to put msg->priority");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->dw_or_faw,
+            NAN_REQ_ATTR_FOLLOWUP_TX_WINDOW, request, result, "followup:Failed to put msg->dw_or_faw");
+
+        CHECK_CONFIG_PUT_16_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info_len,
+            NAN_REQ_ATTR_FOLLOWUP_SERVICE_NAME_LEN, request, result, "followup:Failed to put msg->service_specific_info_len");
+
+        CHECK_CONFIG_PUT_RETURN_FAIL(msg->service_specific_info_len, msg->service_specific_info, msg->service_specific_info_len,
+            NAN_REQ_ATTR_FOLLOWUP_SERVICE_NAME, request, result, "followup:Failed to put msg->service_specific_info");
+
+        CHECK_CONFIG_PUT_8_RETURN_FAIL(1, msg->recv_indication_cfg,
+            NAN_REQ_ATTR_FOLLOWUP_RECV_IND_CFG, request, result, "followup:Failed to put msg->recv_indication_cfg");
+
+        request.attr_end(data);
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to followup; result = %d", result);
+        } else {
+            ALOGD("NAN followup...success");
+        }
+        return result;
+
+    }
+
+    int getCapabilities(void) {
+        ALOGD("NAN getCapabilities...");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_NAN_CAPABILITIES);
+        CHECK_WIFI_STATUS_RETURN_FAIL(result, "getCapabilities:Failed to create WifiRequest");
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("failed to getCapabilities; result = %d", result);
+        } else {
+            ALOGD("NAN getCapabilities...success");
+        }
+        return result;
+    }
+
+    int handleEvent(WifiEvent &event) {
+        int ret;
+        ALOGD("NAN handleEvent...");
+
+        if (event.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring event with cmd = %d", event.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = event.get_vendor_id();
+        int subcmd = event.get_vendor_subcmd();
+
+        ALOGI("Id = %0x, subcmd = %d", id, subcmd);
+
+        switch(subcmd) {
+        case SLSI_NAN_EVENT_MATCH:
+            ret = processMatchEvent(event);
+            break;
+        case SLSI_NAN_EVENT_MATCH_EXPIRED:
+            ret = processMatchExpiredEvent(event);
+            break;
+        case SLSI_NAN_EVENT_PUBLISH_TERMINATED:
+            ret = processPublishTerminatedEvent(event);
+            break;
+        case SLSI_NAN_EVENT_SUBSCRIBE_TERMINATED:
+            ret = processSubscribeTerminatedEvent(event);
+            break;
+        case SLSI_NAN_EVENT_FOLLOWUP:
+            ret = processFollowupEvent(event);
+            break;
+        case SLSI_NAN_EVENT_DISABLED:
+            ret = processNanDisabledEvent(event);
+            break;
+        case SLSI_NAN_EVENT_DISCOVERY_ENGINE:
+            ret = processNanDiscoveryEvent(event);
+            break;
+
+        }
+
+        return NL_OK;
+    }
+
+    int handleResponse(WifiEvent &reply) {
+        ALOGD("NAN handleResponse...");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        NanResponseMsg response;
+        memset(&response, 0, sizeof(response));
+
+        if (processResponse(reply, &response) == NL_SKIP)
+            return NL_SKIP;
+
+        if (callbackEventHandler.NotifyResponse)
+            callbackEventHandler.NotifyResponse(id(), &response);
+        return NL_OK;
+    }
+};
+
+NanCallbackHandler NanCommand::callbackEventHandler;
+
+NanCommand *nan_get_object(transaction_id id,
+                              wifi_interface_handle iface) {
+    wifi_handle handle = getWifiHandle(iface);
+    NanCommand *nanRequest = (NanCommand *)wifi_get_cmd(handle, id);
+    if (!nanRequest) {
+        nanRequest = new NanCommand(iface, id);
+        if (!nanRequest){
+            ALOGE("Could not alloc NanCommand");
+            return NULL;
+        }
+    }
+    return nanRequest;
+}
+
+wifi_error nan_enable_request(transaction_id id,
+                              wifi_interface_handle iface,
+                              NanEnableRequest *msg) {
+    wifi_handle handle = getWifiHandle(iface);
+    wifi_error ret;
+
+    NanCommand *nanRequest = new NanCommand(iface, id);
+    if (!nanRequest) {
+        ALOGE("nan_enable_request:: Unable to create NanCommand");
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+
+    wifi_register_cmd(handle, id, nanRequest);
+    ret = (wifi_error)nanRequest->enable(msg);
+    if (ret != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        delete nanRequest;
+    }
+    return ret;
+}
+
+/*  Disable NAN functionality. */
+wifi_error nan_disable_request(transaction_id id, wifi_interface_handle iface) {
+    NanCommand *nanRequest = nan_get_object(id, iface);
+    wifi_error ret;
+
+    if (!nanRequest) {
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    ret = (wifi_error)nanRequest->disable();
+    delete nanRequest;
+    return ret;
+}
+
+/*  Publish request to advertize a service. */
+wifi_error nan_publish_request(transaction_id id,
+                               wifi_interface_handle iface,
+                               NanPublishRequest *msg) {
+    NanCommand *nanRequest = nan_get_object(id, iface);
+    if (!nanRequest) {
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    return (wifi_error)nanRequest->publish(msg);
+}
+
+/*  Cancel previous publish requests. */
+wifi_error nan_publish_cancel_request(transaction_id id,
+                                      wifi_interface_handle iface,
+                                      NanPublishCancelRequest *msg) {
+    NanCommand *nanRequest = nan_get_object(id, iface);
+    if (!nanRequest) {
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    return (wifi_error)nanRequest->publishCancel(msg);
+}
+
+/*  Subscribe request to search for a service. */
+wifi_error nan_subscribe_request(transaction_id id,
+                                 wifi_interface_handle iface,
+                                 NanSubscribeRequest *msg) {
+    NanCommand *nanRequest = nan_get_object(id, iface);
+    if (!nanRequest) {
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    return (wifi_error)nanRequest->subscribe(msg);
+}
+
+/*  Cancel previous subscribe requests. */
+wifi_error nan_subscribe_cancel_request(transaction_id id,
+                                        wifi_interface_handle iface,
+                                        NanSubscribeCancelRequest *msg) {
+    NanCommand *nanRequest = nan_get_object(id, iface);
+    if (!nanRequest) {
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    return (wifi_error)nanRequest->subscribeCancel(msg);
+}
+
+/*  NAN transmit follow up request. */
+wifi_error nan_transmit_followup_request(transaction_id id,
+                                         wifi_interface_handle iface,
+                                         NanTransmitFollowupRequest *msg) {
+    NanCommand *nanRequest = nan_get_object(id, iface);
+    if (!nanRequest) {
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    return (wifi_error)nanRequest->followup(msg);
+}
+
+/* NAN configuration request. */
+wifi_error nan_config_request(transaction_id id,
+                              wifi_interface_handle iface,
+                              NanConfigRequest *msg) {
+    NanCommand *nanRequest = nan_get_object(id, iface);
+    if (!nanRequest) {
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    return (wifi_error)nanRequest->config(msg);
+}
+
+/* Register NAN callbacks. */
+wifi_error nan_register_handler(wifi_interface_handle iface,
+                                NanCallbackHandler handlers) {
+    return (wifi_error)NanCommand::setCallbackHandler(handlers);
+}
+
+/*  Get NAN HAL version. */
+wifi_error nan_get_version(wifi_handle handle,
+                           NanVersion *version) {
+    return (wifi_error)NanCommand::getVersion(version);
+}
+
+/*  Get NAN capabilities. */
+wifi_error nan_get_capabilities(transaction_id id,
+                                wifi_interface_handle iface) {
+    NanCommand *nanRequest = nan_get_object(id, iface);
+    if (!nanRequest) {
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    return (wifi_error)nanRequest->getCapabilities();
+}
+
diff --git a/wifi_offload.cpp b/wifi_offload.cpp
new file mode 100644
index 0000000..208afb8
--- /dev/null
+++ b/wifi_offload.cpp
@@ -0,0 +1,227 @@
+#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/types.h>
+
+#include "nl80211_copy.h"
+#include "sync.h"
+
+#define LOG_TAG  "WifiHAL[offload]"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+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(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(iface, 0), mIndex(index), mType(cmdType)
+    {
+        mIpPkt = NULL;
+        mIpPktLen = 0;
+        mSrcMacAddr = NULL;
+        mDstMacAddr = NULL;
+        mPeriodMsec = 0;
+    }
+
+    int createRequest(WifiRequest &request) {
+        int result;
+
+        switch (mType) {
+            case START_MKEEP_ALIVE:
+            {
+                result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_START_KEEP_ALIVE_OFFLOAD);
+                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, SLSI_NL80211_VENDOR_SUBCMD_STOP_KEEP_ALIVE_OFFLOAD);
+                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) {
+
+        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);
+        wifi_error result = (wifi_error)cmd->start();
+        delete cmd;
+        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);
+        wifi_error result = (wifi_error)cmd->start();
+        delete cmd;
+        return result;
+    } else {
+        ALOGE("Invalid mkeep_alive parameters");
+        return  WIFI_ERROR_INVALID_ARGS;
+    }
+}
