net: wireless: bcmdhd: Update bcm4358 FW (7.112.100.48) [DO NOT MERGE]
Jerry Lee [Fri, 27 May 2016 01:22:30 +0000 (01:22 +0000)]
am: e2ab70d94a  -s ours

* commit 'e2ab70d94a8571dd428280f8d3ed2ba806945df2':
  net: wireless: bcmdhd: Update bcm4358 FW (7.112.100.48) [DO NOT MERGE]

Change-Id: Ic43732def6d3fd9f6255efe32d2f46205710c69d

15 files changed:
bcmdhd/config/Android.mk
bcmdhd/config/android_dhcpcd.conf [deleted file]
bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.bin [deleted file]
bcmdhd/firmware/bcm4354/fw_bcm4354.bin [changed mode: 0755->0644]
bcmdhd/firmware/bcm4354/fw_bcm4354_ap.bin [changed mode: 0755->0644]
bcmdhd/firmware/bcm4358/fw_bcm4358.bin
bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin
bcmdhd/wifi_hal/common.cpp
bcmdhd/wifi_hal/common.h
bcmdhd/wifi_hal/gscan.cpp
bcmdhd/wifi_hal/link_layer_stats.cpp
bcmdhd/wifi_hal/rtt.cpp
bcmdhd/wifi_hal/wifi_hal.cpp
bcmdhd/wifi_hal/wifi_logger.cpp
bcmdhd/wifi_hal/wifi_offload.cpp

index b125897..8c3b13f 100644 (file)
@@ -17,15 +17,6 @@ LOCAL_PATH := $(call my-dir)
 
 ########################
 
-include $(CLEAR_VARS)
-LOCAL_MODULE := dhcpcd.conf
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/dhcpcd
-LOCAL_SRC_FILES := android_dhcpcd.conf
-include $(BUILD_PREBUILT)
-
-#########################
-
 WIFI_DRIVER_SOCKET_IFACE := wlan0
 ifeq ($(strip $(WPA_SUPPLICANT_VERSION)),VER_0_8_X)
   include external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant_conf.mk
diff --git a/bcmdhd/config/android_dhcpcd.conf b/bcmdhd/config/android_dhcpcd.conf
deleted file mode 100644 (file)
index 0fe3996..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# dhcpcd configuration for Android Wi-Fi interface
-# See dhcpcd.conf(5) for details.
-
-# Disable solicitation of IPv6 Router Advertisements
-noipv6rs
-
-interface wlan0
-# dhcpcd-run-hooks uses these options.
-option subnet_mask, routers, domain_name_servers, interface_mtu
diff --git a/bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.bin b/bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.bin
deleted file mode 100644 (file)
index b40cd8a..0000000
Binary files a/bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.bin and /dev/null differ
index fff02ad96e7a442fc57eaac5ee44eb5d9b04f9af..76d15bb65cfa1d60d5b946636afe2f3907bb7274 100644 (file)
Binary files a/bcmdhd/firmware/bcm4358/fw_bcm4358.bin and b/bcmdhd/firmware/bcm4358/fw_bcm4358.bin differ
index 379eca6fc69471ba8565b2dad986c22eab74742c..98f889ebba301b404fd836a046ebd8a929aee1f1 100644 (file)
Binary files a/bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin and b/bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin differ
index f0184d6f7062652cee00c72ce6050f35ef14467d..69ed256b9d80d4f20515e3ae557e8b42139e9496 100644 (file)
@@ -164,6 +164,9 @@ wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd)
         ALOGV("Successfully added command %d: %p at %d", id, cmd, info->num_cmd);
         info->num_cmd++;
         result = WIFI_SUCCESS;
+    } else {
+        ALOGE("Failed to add command %d: %p at %d, reached max limit %d",
+                id, cmd, info->num_cmd, info->alloc_cmd);
     }
 
     return result;
@@ -187,6 +190,10 @@ WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id)
         }
     }
 
+    if (!cmd) {
+        ALOGI("Failed to remove command %d: %p", id, cmd);
+    }
+
     return cmd;
 }
 
index 118e0fc060f8a3fa24827f178913151d036cbad3..2967c9747014fe3b97eafc2586f09a4c2cdab8be 100644 (file)
@@ -15,7 +15,9 @@
 #define DEFAULT_EVENT_CB_SIZE   (64)
 #define DEFAULT_CMD_SIZE        (64)
 #define DOT11_OUI_LEN             3
+#define DOT11_MAX_SSID_LEN        32
 
+#define MAX_PROBE_RESP_IE_LEN      2048
 /*
  Vendor OUI - This is a unique identifier that identifies organization. Lets
  code Android specific functions with Google OUI; although vendors can do more
@@ -63,6 +65,14 @@ typedef enum {
     ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600,
     ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END   = 0x16FF,
 
+    /* define all NAN related commands between 0x1700 and 0x17FF */
+    ANDROID_NL80211_SUBCMD_NAN_RANGE_START = 0x1700,
+    ANDROID_NL80211_SUBCMD_NAN_RANGE_END   = 0x17FF,
+
+    /* define all Android Packet Filter related commands between 0x1800 and 0x18FF */
+    ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START = 0x1800,
+    ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_END   = 0x18FF,
+
     /* This is reserved for future usage */
 
 } ANDROID_VENDOR_SUB_COMMAND;
@@ -100,10 +110,13 @@ typedef enum {
 
     GSCAN_SUBCMD_ANQPO_CONFIG,                          /* 0x1015 */
     WIFI_SUBCMD_SET_RSSI_MONITOR,                       /* 0x1016 */
+    WIFI_SUBCMD_CONFIG_ND_OFFLOAD,                      /* 0x1017 */
     /* Add more sub commands here */
 
-    GSCAN_SUBCMD_MAX
+    GSCAN_SUBCMD_MAX,
 
+    APF_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START,
+    APF_SUBCMD_SET_FILTER,
 } WIFI_SUB_COMMAND;
 
 typedef enum {
@@ -142,7 +155,7 @@ typedef struct {
 
 typedef struct {
     wifi_handle handle;                             // handle to wifi data
-    char name[8+1];                                 // interface name + trailing null
+    char name[IFNAMSIZ+1];                          // interface name + trailing null
     int  id;                                        // id to use when talking to driver
 } interface_info;
 
@@ -179,7 +192,7 @@ typedef struct {
 #define PNO_SSID_LOST    0x2
 
 typedef struct wifi_pno_result {
-    unsigned char ssid[32];
+    unsigned char ssid[DOT11_MAX_SSID_LEN];
     unsigned char ssid_len;
     signed char rssi;
     u16 channel;
@@ -187,6 +200,26 @@ typedef struct wifi_pno_result {
     mac_addr  bssid;
 } wifi_pno_result_t;
 
+typedef struct wifi_gscan_result {
+    u64 ts;                           // Time of discovery
+    u8 ssid[DOT11_MAX_SSID_LEN+1];    // null terminated
+    mac_addr bssid;                   // BSSID
+    u32 channel;                      // channel frequency in MHz
+    s32 rssi;                         // in db
+    u64 rtt;                          // in nanoseconds
+    u64 rtt_sd;                       // standard deviation in rtt
+    u16 beacon_period;                // units are Kusec
+    u16 capability;                   // Capability information
+    u32 pad;
+} wifi_gscan_result_t;
+
+typedef struct wifi_gscan_full_result {
+    wifi_gscan_result_t fixed;
+    u32 scan_ch_bucket;              // scan chbucket bitmask
+    u32 ie_length;                   // byte length of Information Elements
+    u8  ie_data[1];                  // IE data to follow
+} wifi_gscan_full_result_t;
+
 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);
@@ -212,5 +245,13 @@ wifi_error wifi_cancel_cmd(wifi_request_id id, wifi_interface_handle iface);
 #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
 
index 418537b5a0f8eac87498e2d6fdced9df561fad14..52ec284d66fbbeae4f880a77fcfe364fd033ce82 100644 (file)
@@ -56,7 +56,7 @@ typedef enum {
     GSCAN_ATTRIBUTE_AP_FLAGS,                           /* flags on significant change event */
     GSCAN_ATTRIBUTE_NUM_CHANNELS,
     GSCAN_ATTRIBUTE_CHANNEL_LIST,
-
+    GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK,
     /* remaining reserved for additional attributes */
 
     GSCAN_ATTRIBUTE_SSID = 40,
@@ -132,6 +132,15 @@ typedef enum {
     GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT = 120,
     GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD,
 
+    /* ePNO cfg */
+    GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR = 130,
+    GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR,
+    GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX,
+    GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS,
+    GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS,
+    GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS,
+    GSCAN_ATTRIBUTE_EPNO_5G_BONUS,
+
     GSCAN_ATTRIBUTE_MAX
 
 } GSCAN_ATTRIBUTE;
@@ -141,8 +150,24 @@ typedef enum {
 wifi_error wifi_enable_full_scan_results(wifi_request_id id, wifi_interface_handle iface,
          wifi_scan_result_handler handler);
 wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface);
+int wifi_handle_full_scan_event(wifi_request_id id, WifiEvent& event,
+         wifi_scan_result_handler handler);
+void convert_to_hal_result(wifi_scan_result *to, wifi_gscan_result_t *from);
 
 
+void convert_to_hal_result(wifi_scan_result *to, wifi_gscan_result_t *from)
+{
+    to->ts = from->ts;
+    to->channel = from->channel;
+    to->rssi = from->rssi;
+    to->rtt = from->rtt;
+    to->rtt_sd = from->rtt_sd;
+    to->beacon_period = from->beacon_period;
+    to->capability = from->capability;
+    memcpy(to->ssid, from->ssid, (DOT11_MAX_SSID_LEN+1));
+    memcpy(&to->bssid, &from->bssid, sizeof(mac_addr));
+}
+
 /////////////////////////////////////////////////////////////////////////////
 
 class GetCapabilitiesCommand : public WifiCommand
@@ -418,27 +443,7 @@ public:
 
     virtual int handleEvent(WifiEvent& event) {
         ALOGV("Full scan results:  Got an event");
-        //event.log();
-
-        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
-        unsigned int len = event.get_vendor_data_len();
-
-        if (vendor_data == NULL || len < sizeof(wifi_scan_result)) {
-            ALOGI("Full scan results: No scan results found");
-            return NL_SKIP;
-        }
-
-        wifi_scan_result *result = (wifi_scan_result *)event.get_vendor_data();
-
-        if(*mHandler.on_full_scan_result)
-            (*mHandler.on_full_scan_result)(id(), result);
-
-        ALOGV("Full scan result: %-32s %02x:%02x:%02x:%02x:%02x:%02x %d %d %lld %lld %lld\n",
-            result->ssid, result->bssid[0], result->bssid[1], result->bssid[2], result->bssid[3],
-            result->bssid[4], result->bssid[5], result->rssi, result->channel, result->ts,
-            result->rtt, result->rtt_sd);
-
-        return NL_SKIP;
+        return wifi_handle_full_scan_event(id(), event, mHandler);
     }
 
 };
@@ -448,13 +453,10 @@ class ScanCommand : public WifiCommand
 {
     wifi_scan_cmd_params *mParams;
     wifi_scan_result_handler mHandler;
-    static unsigned mGlobalFullScanBuckets;
-    bool mLocalFullScanBuckets;
 public:
     ScanCommand(wifi_interface_handle iface, int id, wifi_scan_cmd_params *params,
                 wifi_scan_result_handler handler)
-        : WifiCommand("ScanCommand", iface, id), mParams(params), mHandler(handler),
-          mLocalFullScanBuckets(0)
+        : WifiCommand("ScanCommand", iface, id), mParams(params), mHandler(handler)
     { }
 
     int createSetupRequest(WifiRequest& request) {
@@ -569,56 +571,6 @@ public:
         return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 0);
     }
 
-    int enableFullScanResultsIfRequired() {
-        /* temporary workaround till we have full support for per bucket scans */
-
-        int nBuckets = 0;
-        for (int i = 0; i < mParams->num_buckets; i++) {
-            if (mParams->buckets[i].report_events == 2) {
-                nBuckets++;
-            }
-        }
-
-        ALOGV("enableFullScanResultsIfRequired num %u needed %u global %u",
-            mParams->num_buckets, nBuckets, mGlobalFullScanBuckets);
-
-        if (mGlobalFullScanBuckets == 0 && nBuckets != 0) {
-            int result = wifi_enable_full_scan_results(0x1000, ifaceHandle(), mHandler);
-            if (result != WIFI_SUCCESS) {
-                ALOGE("failed to enable full scan results");
-                return result;
-            } else {
-                ALOGV("successfully enabled full scan results");
-            }
-        } else {
-            ALOGV("mGlobalFullScanBuckets = %d, nBuckets = %d", mGlobalFullScanBuckets, nBuckets);
-        }
-
-        mLocalFullScanBuckets = nBuckets;
-        mGlobalFullScanBuckets += nBuckets;
-        return WIFI_SUCCESS;
-    }
-
-    int disableFullScanResultsIfRequired() {
-        /* temporary workaround till we have full support for per bucket scans */
-
-        if (mLocalFullScanBuckets == 0) {
-            return WIFI_SUCCESS;
-        }
-
-        mGlobalFullScanBuckets -= mLocalFullScanBuckets;
-        if (mGlobalFullScanBuckets == 0) {
-            int result = wifi_disable_full_scan_results(0x1000, ifaceHandle());
-            if (result != WIFI_SUCCESS) {
-                ALOGE("failed to disable full scan results");
-            } else {
-                ALOGV("successfully disable full scan results");
-            }
-        }
-
-        return WIFI_SUCCESS;
-    }
-
     int start() {
         ALOGV("GSCAN start");
         WifiRequest request(familyId(), ifaceId());
@@ -658,16 +610,16 @@ public:
 
         registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
         registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
 
         result = requestResponse(request);
         if (result != WIFI_SUCCESS) {
             ALOGE("failed to start scan; result = %d", result);
             unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
             unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
+            unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
             return result;
         }
-
-        result = enableFullScanResultsIfRequired();
         return result;
     }
 
@@ -687,8 +639,7 @@ public:
 
         unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
         unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
-        disableFullScanResultsIfRequired();
-
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
         return WIFI_SUCCESS;
     }
 
@@ -705,35 +656,24 @@ public:
         int len = event.get_vendor_data_len();
         int event_id = event.get_vendor_subcmd();
 
-        if(event_id == GSCAN_EVENT_COMPLETE_SCAN) {
+        if ((event_id == GSCAN_EVENT_COMPLETE_SCAN) ||
+            (event_id == GSCAN_EVENT_SCAN_RESULTS_AVAILABLE)) {
             if (vendor_data == NULL || len != 4) {
-                ALOGI("Scan complete type not mentioned!");
+                ALOGI("Bad event data!");
                 return NL_SKIP;
             }
             wifi_scan_event evt_type;
-
             evt_type = (wifi_scan_event) event.get_u32(NL80211_ATTR_VENDOR_DATA);
-            ALOGV("Scan complete: Received event type %d", evt_type);
+            ALOGV("Received event type %d", evt_type);
             if(*mHandler.on_scan_event)
-                (*mHandler.on_scan_event)(evt_type, evt_type);
-        } else {
-
-            if (vendor_data == NULL || len != 4) {
-                ALOGI("No scan results found");
-                return NL_SKIP;
-            }
-
-            int num = event.get_u32(NL80211_ATTR_VENDOR_DATA);
-            ALOGV("Found %d scan results", num);
-            if(*mHandler.on_scan_results_available)
-                (*mHandler.on_scan_results_available)(id(), num);
+                (*mHandler.on_scan_event)(id(), evt_type);
+        } else if (event_id == GSCAN_EVENT_FULL_SCAN_RESULTS) {
+            wifi_handle_full_scan_event(id(), event, mHandler);
         }
         return NL_SKIP;
     }
 };
 
-unsigned ScanCommand::mGlobalFullScanBuckets = 0;
-
 wifi_error wifi_start_gscan(
         wifi_request_id id,
         wifi_interface_handle iface,
@@ -745,10 +685,17 @@ wifi_error wifi_start_gscan(
     ALOGV("Starting GScan, halHandle = %p", handle);
 
     ScanCommand *cmd = new ScanCommand(iface, id, &params, handler);
-    wifi_register_cmd(handle, id, cmd);
-    wifi_error result = (wifi_error)cmd->start();
+    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;
 }
@@ -765,6 +712,7 @@ wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface)
         memset(&handler, 0, sizeof(handler));
 
         ScanCommand *cmd = new ScanCommand(iface, id, &dummy_params, handler);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
         cmd->cancel();
         cmd->releaseRef();
         return WIFI_SUCCESS;
@@ -773,7 +721,6 @@ wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface)
     return wifi_cancel_cmd(id, iface);
 }
 
-
 wifi_error wifi_enable_full_scan_results(
         wifi_request_id id,
         wifi_interface_handle iface,
@@ -785,15 +732,65 @@ wifi_error wifi_enable_full_scan_results(
     ALOGV("Enabling full scan results, halHandle = %p", handle);
 
     FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, id, &params_dummy, handler);
-    wifi_register_cmd(handle, id, cmd);
-
-    wifi_error result = (wifi_error)cmd->start();
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
     if (result != WIFI_SUCCESS) {
         wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
     }
     return result;
 }
 
+int wifi_handle_full_scan_event(
+        wifi_request_id id,
+        WifiEvent& event,
+        wifi_scan_result_handler handler)
+{
+    nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+    unsigned int len = event.get_vendor_data_len();
+
+    if (vendor_data == NULL || len < sizeof(wifi_gscan_full_result_t)) {
+        ALOGI("Full scan results: No scan results found");
+        return NL_SKIP;
+    }
+
+    wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data();
+    /* To protect against corrupted data, put a ceiling */
+    int ie_len = min(MAX_PROBE_RESP_IE_LEN, drv_res->ie_length);
+    wifi_scan_result *full_scan_result;
+    wifi_gscan_result_t *fixed = &drv_res->fixed;
+
+    if ((ie_len + offsetof(wifi_gscan_full_result_t, ie_data)) > len) {
+        ALOGE("BAD event data, len %d ie_len %d fixed length %d!\n", len,
+            ie_len, offsetof(wifi_gscan_full_result_t, ie_data));
+        return NL_SKIP;
+    }
+    full_scan_result = (wifi_scan_result *) malloc((ie_len + offsetof(wifi_scan_result, ie_data)));
+    if (!full_scan_result) {
+        ALOGE("Full scan results: Can't malloc!\n");
+        return NL_SKIP;
+    }
+    convert_to_hal_result(full_scan_result, fixed);
+    full_scan_result->ie_length = ie_len;
+    memcpy(full_scan_result->ie_data, drv_res->ie_data, ie_len);
+    if(handler.on_full_scan_result)
+        handler.on_full_scan_result(id, full_scan_result, drv_res->scan_ch_bucket);
+
+    ALOGV("Full scan result: %-32s %02x:%02x:%02x:%02x:%02x:%02x %d %d %lld %lld %lld %x %d\n",
+        fixed->ssid, fixed->bssid[0], fixed->bssid[1], fixed->bssid[2], fixed->bssid[3],
+        fixed->bssid[4], fixed->bssid[5], fixed->rssi, fixed->channel, fixed->ts,
+        fixed->rtt, fixed->rtt_sd, drv_res->scan_ch_bucket, drv_res->ie_length);
+    free(full_scan_result);
+    return NL_SKIP;
+}
+
+
 wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface)
 {
     ALOGV("Disabling full scan results");
@@ -806,6 +803,7 @@ wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_han
 
         memset(&handler, 0, sizeof(handler));
         FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, 0, &params_dummy, handler);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
         cmd->cancel();
         cmd->releaseRef();
         return WIFI_SUCCESS;
@@ -824,14 +822,11 @@ class GetScanResultsCommand : public WifiCommand {
     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("GetScanResultsCommand", iface, -1), mScans(results), mMax(max), mNum(num),
-                mRetrieved(0), mFlush(flush), mCompleted(0), mNextScanResult(0)
+                mRetrieved(0), mFlush(flush), mCompleted(0)
     { }
 
     int createRequest(WifiRequest& request, int num, byte flush) {
@@ -923,7 +918,7 @@ public:
                 mCompleted = it.get_u8();
                 ALOGV("retrieved mCompleted flag : %d", mCompleted);
             } else if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS || it.get_type() == 0) {
-                int scan_id = 0, flags = 0, num = 0;
+                int scan_id = 0, flags = 0, num = 0, scan_ch_bucket_mask = 0;
                 for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
                     if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_ID) {
                         scan_id = it2.get_u32();
@@ -934,20 +929,24 @@ public:
                     } else if (it2.get_type() == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) {
                         num = it2.get_u32();
                         ALOGV("retrieved num_results: %d", num);
-                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS) {
+                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK) {
+                        scan_ch_bucket_mask = it2.get_u32();
+                        ALOGD("retrieved scan_ch_bucket_mask: %x", scan_ch_bucket_mask);
+                    } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS && num) {
                         if (mRetrieved >= mMax) {
                             ALOGW("Stored %d scans, ignoring excess results", mRetrieved);
                             break;
                         }
-                        num = 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);
-                        ALOGV("Retrieved %d scan results", num);
-                        wifi_scan_result *results = (wifi_scan_result *)it2.get_data();
+                        num = min(num, (int)(it2.get_len()/sizeof(wifi_scan_result)));
+                        num = min(num, (int)MAX_AP_CACHE_PER_SCAN);
+                        ALOGV("Copying %d scan results", num);
+                        wifi_gscan_result_t *results = (wifi_gscan_result_t *)it2.get_data();
+                        wifi_scan_result *mScanResults = mScans[mRetrieved].results;
+
                         for (int i = 0; i < num; i++) {
-                            wifi_scan_result *result = results + i;
+                            wifi_gscan_result_t *result = &results[i];
+                            convert_to_hal_result(&mScanResults[i], result);
+                            mScanResults[i].ie_length = 0;
                             ALOGV("%02d  %-32s  %02x:%02x:%02x:%02x:%02x:%02x  %04d", i,
                                 result->ssid, result->bssid[0], result->bssid[1], result->bssid[2],
                                 result->bssid[3], result->bssid[4], result->bssid[5],
@@ -956,10 +955,8 @@ public:
                         mScans[mRetrieved].scan_id = scan_id;
                         mScans[mRetrieved].flags = flags;
                         mScans[mRetrieved].num_results = num;
+                        mScans[mRetrieved].buckets_scanned = scan_ch_bucket_mask;
                         ALOGV("Setting result of scan_id : 0x%0x", mScans[mRetrieved].scan_id);
-                        memcpy(mScans[mRetrieved].results,
-                                &(mScanResults[mNextScanResult]), num * sizeof(wifi_scan_result));
-                        mNextScanResult += num;
                         mRetrieved++;
                     } else {
                         ALOGW("Ignoring invalid attribute type = %d, size = %d",
@@ -981,8 +978,9 @@ wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, byte flush
     ALOGV("Getting cached scan results, iface handle = %p, num = %d", iface, *num);
 
     GetScanResultsCommand *cmd = new GetScanResultsCommand(iface, flush, results, max, num);
-    wifi_error err = (wifi_error) cmd->execute();
-    delete cmd;
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error err = (wifi_error)cmd->execute();
+    cmd->releaseRef();
     return err;
 }
 
@@ -1138,9 +1136,12 @@ public:
 
         memset(mResults, 0, sizeof(wifi_scan_result) * MAX_RESULTS);
 
-        int num = len / sizeof(wifi_scan_result);
+        int num = len / sizeof(wifi_gscan_result_t);
+        wifi_gscan_result_t *inp = (wifi_gscan_result_t *)event.get_vendor_data();
         num = min(MAX_RESULTS, num);
-        memcpy(mResults, event.get_vendor_data(), num * sizeof(wifi_scan_result));
+        for (int i = 0; i < num; i++, inp++) {
+            convert_to_hal_result(&(mResults[i]), inp);
+        }
 
         if (event_id == GSCAN_EVENT_HOTLIST_RESULTS_FOUND) {
             ALOGI("FOUND %d hotlist APs", num);
@@ -1158,69 +1159,99 @@ public:
 class ePNOCommand : public WifiCommand
 {
 private:
-    wifi_epno_network *ssid_list;
-    int num_ssid;
+    wifi_epno_params epno_params;
     wifi_epno_handler mHandler;
-    static const int MAX_RESULTS = 32;
-    wifi_scan_result mResults[MAX_RESULTS];
+    wifi_scan_result mResults[MAX_EPNO_NETWORKS];
 public:
     ePNOCommand(wifi_interface_handle handle, int id,
-            int num_networks, wifi_epno_network *networks, wifi_epno_handler handler)
+            const wifi_epno_params *params, wifi_epno_handler handler)
         : WifiCommand("ePNOCommand", handle, id), mHandler(handler)
     {
-        ssid_list = networks;
-        num_ssid = num_networks;
+        if (params != NULL) {
+            memcpy(&epno_params, params, sizeof(wifi_epno_params));
+        } else {
+            memset(&epno_params, 0, sizeof(wifi_epno_params));
+        }
     }
-
     int createSetupRequest(WifiRequest& request) {
         int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_EPNO_SSID);
         if (result < 0) {
             return result;
         }
-
         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
         result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_FLUSH, 1);
         if (result < 0) {
             return result;
         }
 
-        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_SSID_NUM, num_ssid);
+        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR,
+                            (u8)epno_params.min5GHz_rssi);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR,
+                            (u8)epno_params.min24GHz_rssi);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX,
+                            epno_params.initial_score_max);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS,
+                            epno_params.current_connection_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS,
+                            epno_params.same_network_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS,
+                            epno_params.secure_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_5G_BONUS,
+                            epno_params.band5GHz_bonus);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_SSID_NUM,
+                        epno_params.num_networks);
         if (result < 0) {
             return result;
         }
-
         struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_EPNO_SSID_LIST);
-        for (int i = 0; i < num_ssid; i++) {
+        wifi_epno_network *ssid_list = epno_params.networks;
+        for (int i = 0; i < epno_params.num_networks; i++) {
             nlattr *attr2 = request.attr_start(i);
             if (attr2 == NULL) {
                 return WIFI_ERROR_OUT_OF_MEMORY;
             }
-            result = request.put(GSCAN_ATTRIBUTE_EPNO_SSID, ssid_list[i].ssid, 32);
-            ALOGI("PNO network: SSID %s rssi_thresh %d flags %d auth %d", ssid_list[i].ssid,
-                (signed char)ssid_list[i].rssi_threshold, ssid_list[i].flags,
+            result = request.put(GSCAN_ATTRIBUTE_EPNO_SSID, ssid_list[i].ssid, DOT11_MAX_SSID_LEN);
+            ALOGI("PNO network: SSID %s flags %x auth %x", ssid_list[i].ssid,
+                ssid_list[i].flags,
                 ssid_list[i].auth_bit_field);
             if (result < 0) {
                 return result;
             }
-            result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_SSID_LEN, strlen(ssid_list[i].ssid));
+            result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_SSID_LEN, strlen(ssid_list[i].ssid));
             if (result < 0) {
                 return result;
             }
-            result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_RSSI, ssid_list[i].rssi_threshold);
+            result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_FLAGS, ssid_list[i].flags);
             if (result < 0) {
                 return result;
             }
-            result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_FLAGS, ssid_list[i].flags);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_AUTH, ssid_list[i].auth_bit_field);
+            result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_AUTH, ssid_list[i].auth_bit_field);
             if (result < 0) {
                 return result;
             }
             request.attr_end(attr2);
         }
-
         request.attr_end(attr);
         request.attr_end(data);
         return result;
@@ -1242,7 +1273,7 @@ public:
     }
 
     int start() {
-        ALOGI("Executing ePNO setup request, num = %d", num_ssid);
+        ALOGI("Executing ePNO setup request, num = %d", epno_params.num_networks);
         WifiRequest request(familyId(), ifaceId());
         int result = createSetupRequest(request);
         if (result < 0) {
@@ -1256,7 +1287,7 @@ public:
             return result;
         }
 
-        ALOGI("Successfully set %d SSIDs for ePNO", num_ssid);
+        ALOGI("Successfully set %d SSIDs for ePNO", epno_params.num_networks);
         registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT);
         ALOGI("successfully restarted the scan");
         return result;
@@ -1299,11 +1330,11 @@ public:
             return NL_SKIP;
         }
 
-        memset(mResults, 0, sizeof(wifi_scan_result) * MAX_RESULTS);
+        memset(mResults, 0, sizeof(wifi_scan_result) * MAX_EPNO_NETWORKS);
 
-        int num = len / sizeof(wifi_pno_result_t);
-        int i;
-        num = min(MAX_RESULTS, num);
+        unsigned int num = len / sizeof(wifi_pno_result_t);
+        unsigned int i;
+        num = min(MAX_EPNO_NETWORKS, num);
         wifi_pno_result_t *res = (wifi_pno_result_t *) event.get_vendor_data();
         for (i = 0; i < num; i++) {
             if (res[i].flags == PNO_SSID_FOUND) {
@@ -1327,10 +1358,17 @@ wifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle ifac
     wifi_handle handle = getWifiHandle(iface);
 
     BssidHotlistCommand *cmd = new BssidHotlistCommand(iface, id, params, handler);
-    wifi_register_cmd(handle, id, cmd);
-    wifi_error result = (wifi_error)cmd->start();
+    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;
 }
@@ -1542,10 +1580,17 @@ wifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interfac
 
     SignificantWifiChangeCommand *cmd = new SignificantWifiChangeCommand(
             iface, id, params, handler);
-    wifi_register_cmd(handle, id, cmd);
-    wifi_error result = (wifi_error)cmd->start();
+    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;
 }
@@ -1557,271 +1602,38 @@ wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interf
 
 wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface)
 {
+    if (id == -1) {
+        wifi_epno_handler handler;
+        wifi_handle handle = getWifiHandle(iface);
+
+        memset(&handler, 0, sizeof(handler));
+        ePNOCommand *cmd = new ePNOCommand(iface, id, NULL, handler);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        cmd->cancel();
+        cmd->releaseRef();
+        return WIFI_SUCCESS;
+    }
     return wifi_cancel_cmd(id, iface);
 }
 
 wifi_error wifi_set_epno_list(wifi_request_id id, wifi_interface_handle iface,
-        int num_networks, wifi_epno_network *networks, wifi_epno_handler handler)
-{
-     wifi_handle handle = getWifiHandle(iface);
-
-     ePNOCommand *cmd = new ePNOCommand(iface, id, num_networks, networks, handler);
-     wifi_register_cmd(handle, id, cmd);
-     if (num_networks == 0 || networks == NULL) {
-         return wifi_reset_epno_list(id, iface);
-     }
-     wifi_error result = (wifi_error)cmd->start();
-     if (result != WIFI_SUCCESS) {
-         wifi_unregister_cmd(handle, id);
-     }
-     return result;
-}
-
-class SSIDWhitelistCommand : public WifiCommand
-{
-private:
-    int mNumNetworks;
-    wifi_ssid *mSSIDs;
-public:
-    SSIDWhitelistCommand(wifi_interface_handle handle, int id,
-            int num_networks, wifi_ssid *ssids)
-        : WifiCommand("SSIDWhitelistCommand", handle, id), mNumNetworks(num_networks), mSSIDs(ssids)
-    { }
-
-    int createRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_SSID_WHITE_LIST);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_WL_SSID, mNumNetworks);
-        if (result < 0) {
-            return result;
-        }
-        if (!mNumNetworks) {
-            result = request.put_u32(GSCAN_ATTRIBUTE_WL_SSID_FLUSH, 1);
-            if (result < 0) {
-                return result;
-            }
-        }
-        for (int i = 0; i < mNumNetworks; i++) {
-            nlattr *attr = request.attr_start(GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM);
-            if (attr == NULL) {
-                return WIFI_ERROR_OUT_OF_MEMORY;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_WL_SSID_LEN, strlen(mSSIDs[i].ssid));
-            if (result < 0) {
-                return result;
-            }
-            result = request.put(GSCAN_ATTRIBUTE_WHITELIST_SSID, mSSIDs[i].ssid, 32);
-            if (result < 0) {
-                return result;
-            }
-            request.attr_end(attr);
-        }
-        request.attr_end(data);
-        return result;
-    }
-
-    int start() {
-        ALOGI("Executing whitelist ssid request, num = %d", mNumNetworks);
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request);
-        if (result < 0) {
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result < 0) {
-            ALOGI("Failed to execute whitelist ssid request, result = %d", result);
-            return result;
-        }
-
-        ALOGI("Successfully whitlisted %d ssids", mNumNetworks);
-        if (result < 0) {
-            return result;
-        }
-        return result;
-    }
-
-
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-};
-
-wifi_error wifi_set_ssid_white_list(wifi_request_id id, wifi_interface_handle iface,
-        int num_networks, wifi_ssid *ssids)
+        const wifi_epno_params *params, wifi_epno_handler handler)
 {
     wifi_handle handle = getWifiHandle(iface);
 
-    SSIDWhitelistCommand *cmd = new SSIDWhitelistCommand(iface, id, num_networks, ssids);
-    wifi_register_cmd(handle, id, cmd);
-    wifi_error result = (wifi_error)cmd->start();
+    ePNOCommand *cmd = new ePNOCommand(iface, id, params, handler);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
     if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-    }
-    return result;
-}
-
-
-class RoamParamsCommand : public WifiCommand
-{
-private:
-    wifi_roam_params *mParams;
-public:
-    RoamParamsCommand(wifi_interface_handle handle, int id, wifi_roam_params *params)
-        : WifiCommand("RoamParamsCommand", handle, id), mParams(params)
-    { }
-
-    int createRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_ROAM_PARAMS);
-        if (result < 0) {
-            return result;
-        }
-
-    nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-
-    result = request.put_u32(GSCAN_ATTRIBUTE_A_BAND_BOOST_THRESHOLD, mParams->A_band_boost_threshold);
-    if (result < 0) {
-        return result;
-    }
-    result = request.put_u32(GSCAN_ATTRIBUTE_A_BAND_PENALTY_THRESHOLD, mParams->A_band_penalty_threshold);
-    if (result < 0) {
-        return result;
-    }
-    result = request.put_u32(GSCAN_ATTRIBUTE_A_BAND_BOOST_FACTOR, mParams->A_band_boost_factor);
-    if (result < 0) {
-        return result;
-    }
-    result = request.put_u32(GSCAN_ATTRIBUTE_A_BAND_PENALTY_FACTOR, mParams->A_band_penalty_factor);
-    if (result < 0) {
-        return result;
-    }
-    result = request.put_u32(GSCAN_ATTRIBUTE_A_BAND_MAX_BOOST, mParams->A_band_max_boost);
-    if (result < 0) {
-        return result;
-    }
-    result = request.put_u32(GSCAN_ATTRIBUTE_LAZY_ROAM_HYSTERESIS, mParams->lazy_roam_hysteresis);
-    if (result < 0) {
-        return result;
-    }
-    result = request.put_u32(GSCAN_ATTRIBUTE_ALERT_ROAM_RSSI_TRIGGER, mParams->alert_roam_rssi_trigger);
-    if (result < 0) {
-        return result;
-    }
-        request.attr_end(data);
-        return result;
-    }
-
-    int start() {
-        ALOGV("Executing roam params set request");
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request);
-        if (result < 0) {
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result < 0) {
-            ALOGE("Failed to execute Roam params set request, result = %d", result);
-            return result;
-        }
-
-        ALOGI("Successfully set roam params");
-        if (result < 0) {
-            return result;
-        }
+        cmd->releaseRef();
         return result;
     }
-
-
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-};
-
-wifi_error wifi_set_gscan_roam_params(wifi_request_id id, wifi_interface_handle iface,
-                                        wifi_roam_params * params)
-{
-    wifi_handle handle = getWifiHandle(iface);
-
-    RoamParamsCommand *cmd = new RoamParamsCommand(iface, id, params);
-    wifi_register_cmd(handle, id, cmd);
-    wifi_error result = (wifi_error)cmd->start();
+    result = (wifi_error)cmd->start();
     if (result != WIFI_SUCCESS) {
         wifi_unregister_cmd(handle, id);
-    }
-    return result;
-}
-
-class LazyRoamCommand : public WifiCommand
-{
-private:
-    int mEnable;
-public:
-    LazyRoamCommand(wifi_interface_handle handle, int id, int enable)
-        : WifiCommand("LazyRoamCommand", handle, id), mEnable(enable)
-    { }
-
-    int createRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_ENABLE_LAZY_ROAM);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-
-        result = request.put_u32(GSCAN_ATTRIBUTE_LAZY_ROAM_ENABLE, mEnable);
-        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) {
-            ALOGI("Failed to enable lazy roam, result = %d", result);
-            return result;
-        }
-
-        ALOGI("Successfully enabled lazy roam");
-        if (result < 0) {
-            return result;
-        }
+        cmd->releaseRef();
         return result;
     }
-
-
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-};
-wifi_error wifi_enable_lazy_roam(wifi_request_id id, wifi_interface_handle iface, int enable)
-{
-    wifi_handle handle = getWifiHandle(iface);
-
-    LazyRoamCommand *cmd = new LazyRoamCommand(iface, id, enable);
-    wifi_register_cmd(handle, id, cmd);
-    wifi_error result = (wifi_error)cmd->start();
-    if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle, id);
-    }
     return result;
 }
 
@@ -1895,102 +1707,7 @@ wifi_error wifi_set_bssid_blacklist(wifi_request_id id, wifi_interface_handle if
     wifi_handle handle = getWifiHandle(iface);
 
     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 BssidPreferenceCommand : public WifiCommand
-{
-private:
-    int mNumBssid;
-    wifi_bssid_preference *mPrefs;
-public:
-    BssidPreferenceCommand(wifi_interface_handle handle, int id,
-            int num_bssid, wifi_bssid_preference *prefs)
-        : WifiCommand("BssidPreferenceCommand", handle, id), mNumBssid(num_bssid), mPrefs(prefs)
-    { }
-
-    int createRequest(WifiRequest& request) {
-        int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_BSSID_PREF);
-        if (result < 0) {
-            return result;
-        }
-
-        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-
-        result = request.put_u32(GSCAN_ATTRIBUTE_NUM_BSSID, mNumBssid);
-        if (result < 0) {
-            return result;
-        }
-        if (!mNumBssid) {
-            result = request.put_u32(GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH, 1);
-            if (result < 0) {
-                return result;
-            }
-        }
-       struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_BSSID_PREF_LIST);
-        if (attr == NULL) {
-            return WIFI_ERROR_OUT_OF_MEMORY;
-        }
-        for (int i = 0; i < mNumBssid; i++) {
-
-            nlattr *attr1 = request.attr_start(i);
-            if (attr == NULL) {
-                return WIFI_ERROR_OUT_OF_MEMORY;
-            }
-            result = request.put_addr(GSCAN_ATTRIBUTE_BSSID_PREF, mPrefs[i].bssid);
-            if (result < 0) {
-                return result;
-            }
-            result = request.put_u32(GSCAN_ATTRIBUTE_RSSI_MODIFIER, mPrefs[i].rssi_modifier);
-            if (result < 0) {
-                return result;
-            }
-            request.attr_end(attr1);
-        }
-        request.attr_end(attr);
-        request.attr_end(data);
-
-        return result;
-    }
-
-    int start() {
-        ALOGV("Executing bssid prefernce change request, num = %d", mNumBssid);
-        WifiRequest request(familyId(), ifaceId());
-        int result = createRequest(request);
-        if (result < 0) {
-            return result;
-        }
-
-        result = requestResponse(request);
-        if (result < 0) {
-            ALOGE("Failed to execute bssid preference change request, result = %d", result);
-            return result;
-        }
-
-        ALOGI("Successfully changed %d bssid preferences", mNumBssid);
-        if (result < 0) {
-            return result;
-        }
-        return result;
-    }
-
-
-    virtual int handleResponse(WifiEvent& reply) {
-        /* Nothing to do on response! */
-        return NL_SKIP;
-    }
-
-};
-
-wifi_error wifi_set_bssid_preference(wifi_request_id id, wifi_interface_handle iface,
-                                    int num_bssid, wifi_bssid_preference *prefs)
-{
-    wifi_handle handle = getWifiHandle(iface);
-
-    BssidPreferenceCommand *cmd = new BssidPreferenceCommand(iface, id, num_bssid, prefs);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
     wifi_error result = (wifi_error)cmd->start();
     //release the reference of command as well
     cmd->releaseRef();
@@ -2004,12 +1721,14 @@ class AnqpoConfigureCommand : public WifiCommand
     int num_hs;
     wifi_passpoint_network *mNetworks;
     wifi_passpoint_event_handler mHandler;
+    wifi_scan_result *mResult;
 public:
     AnqpoConfigureCommand(wifi_request_id id, wifi_interface_handle iface,
         int num, wifi_passpoint_network *hs_list, wifi_passpoint_event_handler handler)
         : WifiCommand("AnqpoConfigureCommand", iface, id), num_hs(num), mNetworks(hs_list),
             mHandler(handler)
     {
+        mResult = NULL;
     }
 
     int createRequest(WifiRequest& request, int val) {
@@ -2118,27 +1837,33 @@ public:
             ALOGI("No scan results found");
             return NL_SKIP;
         }
+        mResult = (wifi_scan_result *)malloc(sizeof(wifi_scan_result));
+        if (!mResult) {
+            return NL_SKIP;
+        }
+        wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data();
+        wifi_gscan_result_t *fixed = &drv_res->fixed;
+        convert_to_hal_result(mResult, fixed);
 
-        wifi_scan_result *result = (wifi_scan_result *)event.get_vendor_data();
-        byte *anqp = (byte *)result + offsetof(wifi_scan_result, ie_data) + result->ie_length;
+        byte *anqp = (byte *)drv_res + offsetof(wifi_gscan_full_result_t, ie_data) + drv_res->ie_length;
         wifi_anqp_gas_resp *gas = (wifi_anqp_gas_resp *)anqp;
         int anqp_len = offsetof(wifi_anqp_gas_resp, data) + gas->data_len;
         int networkId = *(int *)((byte *)anqp + anqp_len);
 
-        ALOGI("%-32s\t", result->ssid);
+        ALOGI("%-32s\t", mResult->ssid);
 
-        ALOGI("%02x:%02x:%02x:%02x:%02x:%02x ", result->bssid[0], result->bssid[1],
-                result->bssid[2], result->bssid[3], result->bssid[4], result->bssid[5]);
+        ALOGI("%02x:%02x:%02x:%02x:%02x:%02x ", mResult->bssid[0], mResult->bssid[1],
+                mResult->bssid[2], mResult->bssid[3], mResult->bssid[4], mResult->bssid[5]);
 
-        ALOGI("%d\t", result->rssi);
-        ALOGI("%d\t", result->channel);
-        ALOGI("%lld\t", result->ts);
-        ALOGI("%lld\t", result->rtt);
-        ALOGI("%lld\n", result->rtt_sd);
+        ALOGI("%d\t", mResult->rssi);
+        ALOGI("%d\t", mResult->channel);
+        ALOGI("%lld\t", mResult->ts);
+        ALOGI("%lld\t", mResult->rtt);
+        ALOGI("%lld\n", mResult->rtt_sd);
 
         if(*mHandler.on_passpoint_network_found)
-            (*mHandler.on_passpoint_network_found)(id(), networkId, result, anqp_len, anqp);
-
+            (*mHandler.on_passpoint_network_found)(id(), networkId, mResult, anqp_len, anqp);
+        free(mResult);
         return NL_SKIP;
     }
 };
@@ -2149,10 +1874,17 @@ wifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_interface_handle ifa
     wifi_handle handle = getWifiHandle(iface);
 
     AnqpoConfigureCommand *cmd = new AnqpoConfigureCommand(id, iface, num, networks, handler);
-    wifi_register_cmd(handle, id, cmd);
-    wifi_error result = (wifi_error)cmd->start();
+    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;
 }
@@ -2161,4 +1893,3 @@ wifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle i
 {
     return wifi_cancel_cmd(id, iface);
 }
-
index 170c7912ec0e9ecca17d192a3168f501600c9535..1ef85161a6c9e4f99497f31d009cab24a81ebc88 100644 (file)
 #include "common.h"
 #include "cpp_bindings.h"
 
+/* Internal radio statistics structure in the driver */
+typedef struct {
+       wifi_radio radio;
+       uint32_t on_time;
+       uint32_t tx_time;
+       uint32_t rx_time;
+       uint32_t on_time_scan;
+       uint32_t on_time_nbd;
+       uint32_t on_time_gscan;
+       uint32_t on_time_roam_scan;
+       uint32_t on_time_pno_scan;
+       uint32_t on_time_hs20;
+       uint32_t num_channels;
+       wifi_channel_stat channels[];
+} wifi_radio_stat_internal;
 
 enum {
     LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START,
@@ -68,28 +83,64 @@ protected:
 
         void *data = reply.get_vendor_data();
         int len = reply.get_vendor_data_len();
-       unsigned int num_chan = ((wifi_radio_stat *)data)->num_channels;
-        if (num_chan > 11) {
-           ALOGE("Incorrect number of channels = %d", num_chan);
-           // dump data before num_channels
-           ALOGE("radio: = %d", ((wifi_radio_stat *)data)->radio);
-           ALOGE("on_time: = %d", ((wifi_radio_stat *)data)->on_time);
-           ALOGE("tx_time: = %d", ((wifi_radio_stat *)data)->tx_time);
-           ALOGE("rx_time: = %d", ((wifi_radio_stat *)data)->rx_time);
-           ALOGE("on_time_scan: = %d", ((wifi_radio_stat *)data)->on_time_scan);
-           ALOGE("on_time_nbd: = %d", ((wifi_radio_stat *)data)->on_time_nbd);
-           ALOGE("on_time_gscan: = %d", ((wifi_radio_stat *)data)->on_time_gscan);
-           ALOGE("on_time_pno_scan: = %d", ((wifi_radio_stat *)data)->on_time_pno_scan);
-           ALOGE("on_time_hs20: = %d", ((wifi_radio_stat *)data)->on_time_hs20);
-           return NL_SKIP;
+        wifi_radio_stat *radio_stat =
+            convertToExternalRadioStatStructure((wifi_radio_stat_internal *)data);
+        if (!radio_stat) {
+            ALOGE("Invalid stats pointer received");
+            return NL_SKIP;
         }
-       (*mHandler.on_link_stats_results)(id,
-               (wifi_iface_stat *)((char *)&((wifi_radio_stat *)data)->channels
-               + num_chan*sizeof(wifi_channel_stat)),
-               1, (wifi_radio_stat *)data);
-
+        if (radio_stat->num_channels > 11) {
+            ALOGE("Incorrect number of channels = %d", radio_stat->num_channels);
+            // dump data before num_channels
+            ALOGE("radio: = %d", radio_stat->radio);
+            ALOGE("on_time: = %d", radio_stat->on_time);
+            ALOGE("tx_time: = %d", radio_stat->tx_time);
+            ALOGE("rx_time: = %d", radio_stat->rx_time);
+            ALOGE("on_time_scan: = %d", radio_stat->on_time_scan);
+            ALOGE("on_time_nbd: = %d", radio_stat->on_time_nbd);
+            ALOGE("on_time_gscan: = %d", radio_stat->on_time_gscan);
+            ALOGE("on_time_pno_scan: = %d", radio_stat->on_time_pno_scan);
+            ALOGE("on_time_hs20: = %d", radio_stat->on_time_hs20);
+            free(radio_stat);
+            return NL_SKIP;
+        }
+        wifi_iface_stat *iface_stat =
+            (wifi_iface_stat *)((char *)&((wifi_radio_stat_internal *)data)->channels
+                + radio_stat->num_channels * sizeof(wifi_channel_stat));
+        (*mHandler.on_link_stats_results)(id, iface_stat, 1, radio_stat);
+        free(radio_stat);
         return NL_OK;
     }
+
+private:
+    wifi_radio_stat *convertToExternalRadioStatStructure(wifi_radio_stat_internal *internal_stat_ptr) {
+        wifi_radio_stat *external_stat_ptr = NULL;
+        if (internal_stat_ptr) {
+            uint32_t channel_size = internal_stat_ptr->num_channels * sizeof(wifi_channel_stat);
+            uint32_t total_size = sizeof(wifi_radio_stat) + channel_size;
+            external_stat_ptr = (wifi_radio_stat *)malloc(total_size);
+            if (external_stat_ptr) {
+                external_stat_ptr->radio = internal_stat_ptr->radio;
+                external_stat_ptr->on_time = internal_stat_ptr->on_time;
+                external_stat_ptr->tx_time = internal_stat_ptr->tx_time;
+                external_stat_ptr->rx_time = internal_stat_ptr->rx_time;
+                external_stat_ptr->tx_time_per_levels = NULL;
+                external_stat_ptr->num_tx_levels = 0;
+                external_stat_ptr->on_time_scan = internal_stat_ptr->on_time_scan;
+                external_stat_ptr->on_time_nbd = internal_stat_ptr->on_time_nbd;
+                external_stat_ptr->on_time_gscan = internal_stat_ptr->on_time_gscan;
+                external_stat_ptr->on_time_roam_scan = internal_stat_ptr->on_time_roam_scan;
+                external_stat_ptr->on_time_pno_scan = internal_stat_ptr->on_time_pno_scan;
+                external_stat_ptr->on_time_hs20 = internal_stat_ptr->on_time_hs20;
+                external_stat_ptr->num_channels = internal_stat_ptr->num_channels;
+                if (internal_stat_ptr->num_channels) {
+                    memcpy(&(external_stat_ptr->channels), &(internal_stat_ptr->channels),
+                        channel_size);
+                }
+            }
+        }
+        return external_stat_ptr;
+    }
 };
 
 wifi_error wifi_get_link_stats(wifi_request_id id,
index f77fdb00535ed976f93f3c20f16a454c4522c79a..410196b71df0368ec38a165a5389004d94aa3094 100644 (file)
@@ -35,6 +35,9 @@ typedef enum {
     RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
     RTT_SUBCMD_CANCEL_CONFIG,
     RTT_SUBCMD_GETCAPABILITY,
+    RTT_SUBCMD_GETAVAILCHANNEL,
+    RTT_SUBCMD_SET_RESPONDER,
+    RTT_SUBCMD_CANCEL_RESPONDER,
 } RTT_SUB_COMMAND;
 
 typedef enum {
@@ -157,6 +160,135 @@ protected:
 };
 
 
+class GetRttResponderInfoCommand : public WifiCommand
+{
+    wifi_rtt_responder* mResponderInfo;
+public:
+    GetRttResponderInfoCommand(wifi_interface_handle iface, wifi_rtt_responder *responderInfo)
+        : WifiCommand("GetRttResponderInfoCommand", iface, 0), mResponderInfo(responderInfo)
+    {
+        memset(mResponderInfo, 0 , sizeof(*mResponderInfo));
+
+    }
+
+    virtual int create() {
+        ALOGD("Creating message to get responder info ; iface = %d", mIfaceInfo->id);
+
+        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETAVAILCHANNEL);
+        if (ret < 0) {
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        ALOGD("In GetRttResponderInfoCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        void *data = reply.get_vendor_data();
+        int len = reply.get_vendor_data_len();
+
+        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
+                sizeof(*mResponderInfo));
+
+        memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
+
+        return NL_OK;
+    }
+};
+
+
+class EnableResponderCommand : public WifiCommand
+{
+    wifi_channel_info  mChannelInfo;
+    wifi_rtt_responder* mResponderInfo;
+    unsigned m_max_duration_sec;
+public:
+    EnableResponderCommand(wifi_interface_handle iface, int id, wifi_channel_info channel_hint,
+            unsigned max_duration_seconds, wifi_rtt_responder *responderInfo)
+            : WifiCommand("EnableResponderCommand", iface, 0), mChannelInfo(channel_hint),
+            m_max_duration_sec(max_duration_seconds), mResponderInfo(responderInfo)
+    {
+        memset(mResponderInfo, 0, sizeof(*mResponderInfo));
+    }
+
+    virtual int create() {
+        ALOGD("Creating message to set responder ; iface = %d", mIfaceInfo->id);
+
+        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_SET_RESPONDER);
+        if (ret < 0) {
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        ALOGD("In EnableResponderCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        void *data = reply.get_vendor_data();
+        int len = reply.get_vendor_data_len();
+
+        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
+                sizeof(*mResponderInfo));
+
+        memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
+
+        return NL_OK;
+    }
+};
+
+
+class CancelResponderCommand : public WifiCommand
+{
+
+public:
+    CancelResponderCommand(wifi_interface_handle iface, int id)
+        : WifiCommand("CancelResponderCommand", iface, 0)/*, mChannelInfo(channel)*/
+    {
+
+    }
+
+    virtual int create() {
+        ALOGD("Creating message to cancel responder ; iface = %d", mIfaceInfo->id);
+
+        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_RESPONDER);
+        if (ret < 0) {
+            return ret;
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+        /* Nothing to do on response! */
+        return NL_SKIP;
+    }
+
+};
+
+
 class RttCommand : public WifiCommand
 {
     unsigned numRttParams;
@@ -450,7 +582,7 @@ public:
                                 rtt_result->success_number, rtt_result->number_per_burst_peer,
                                 get_err_info(rtt_result->status), rtt_result->retry_after_duration,
                                 rtt_result->rssi, rtt_result->rx_rate.bitrate * 100,
-                                rtt_result->rtt/10, rtt_result->rtt_sd, rtt_result->distance,
+                                rtt_result->rtt/10, rtt_result->rtt_sd, rtt_result->distance_mm / 10,
                                 rtt_result->burst_duration, rtt_result->negotiated_burst_num);
                         currentIdx++;
                     }
@@ -480,10 +612,20 @@ wifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle ifac
         unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
 {
     wifi_handle handle = getWifiHandle(iface);
-
     RttCommand *cmd = new RttCommand(iface, id, num_rtt_config, rtt_config, handler);
-    wifi_register_cmd(handle, id, cmd);
-    return (wifi_error)cmd->start();
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
+    if (result != WIFI_SUCCESS) {
+        wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
+    }
+    return result;
 }
 
 /* API to cancel RTT measurements */
@@ -492,12 +634,10 @@ wifi_error wifi_rtt_range_cancel(wifi_request_id id,  wifi_interface_handle ifac
 {
     wifi_handle handle = getWifiHandle(iface);
     RttCommand *cmd = new RttCommand(iface, id);
-    if (cmd) {
-        cmd->cancel_specific(num_devices, addr);
-        cmd->releaseRef();
-        return WIFI_SUCCESS;
-    }
-    return WIFI_ERROR_INVALID_ARGS;
+    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 */
@@ -507,3 +647,36 @@ wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
     GetRttCapabilitiesCommand command(iface, capabilities);
     return (wifi_error) command.requestResponse();
 }
+
+/* API to get the responder information */
+wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
+        wifi_rtt_responder* responderInfo)
+{
+    GetRttResponderInfoCommand command(iface, responderInfo);
+    return (wifi_error) command.requestResponse();
+
+}
+
+/**
+ * Enable RTT responder mode.
+ * channel_hint - hint of the channel information where RTT responder should be enabled on.
+ * max_duration_seconds - timeout of responder mode.
+ * wifi_rtt_responder - information for RTT responder e.g. channel used and preamble supported.
+ */
+wifi_error wifi_enable_responder(wifi_request_id id, wifi_interface_handle iface,
+                                wifi_channel_info channel_hint, unsigned max_duration_seconds,
+                                wifi_rtt_responder* responderInfo)
+{
+    EnableResponderCommand command(iface, id, channel_hint, max_duration_seconds, responderInfo);
+    return (wifi_error) command.requestResponse();
+}
+
+/**
+ * Disable RTT responder mode.
+ */
+wifi_error wifi_disable_responder(wifi_request_id id, wifi_interface_handle iface)
+{
+    CancelResponderCommand command(iface, id);
+    return (wifi_error) command.requestResponse();
+}
+
index fdb7d7b7b36ebb155aa5f0b88165323c89e285d3..251414b5018bd152119340c36a8e49d2bf02adbe 100644 (file)
 #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 void internal_event_handler(wifi_handle handle, int events);
 static int internal_no_seq_check(nl_msg *msg, void *arg);
 static int internal_valid_message_handler(nl_msg *msg, void *arg);
@@ -56,11 +51,20 @@ static wifi_error wifi_init_interfaces(wifi_handle handle);
 static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
                         iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh);
 static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface);
+static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
+                            const u8 *program, u32 len);
+static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
+                u32 *version, u32 *max_len);
+static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, u8 enable);
 
 typedef enum wifi_attr {
     ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
     ANDR_WIFI_ATTRIBUTE_FEATURE_SET,
-    ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI
+    ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI,
+    ANDR_WIFI_ATTRIBUTE_NODFS_SET,
+    ANDR_WIFI_ATTRIBUTE_COUNTRY,
+    ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE
+    // Add more attribute here
 } wifi_attr_t;
 
 enum wifi_rssi_monitor_attr {
@@ -69,6 +73,18 @@ enum wifi_rssi_monitor_attr {
     RSSI_MONITOR_ATTRIBUTE_START,
 };
 
+enum wifi_apf_attr {
+    APF_ATTRIBUTE_VERSION,
+    APF_ATTRIBUTE_MAX_LEN,
+    APF_ATTRIBUTE_PROGRAM,
+    APF_ATTRIBUTE_PROGRAM_LEN
+};
+
+enum apf_request_type {
+    GET_APF_CAPABILITIES,
+    SET_APF_PROGRAM
+};
+
 /* Initialize/Cleanup */
 
 void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
@@ -137,9 +153,13 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
     fn->wifi_rtt_range_request = wifi_rtt_range_request;
     fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel;
     fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities;
+    fn->wifi_rtt_get_responder_info = wifi_rtt_get_responder_info;
+    fn->wifi_enable_responder = wifi_enable_responder;
+    fn->wifi_disable_responder = wifi_disable_responder;
     fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag;
     fn->wifi_start_logging = wifi_start_logging;
     fn->wifi_set_epno_list = wifi_set_epno_list;
+    fn->wifi_reset_epno_list = wifi_reset_epno_list;
     fn->wifi_set_country_code = wifi_set_country_code;
     fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump;
     fn->wifi_set_log_handler = wifi_set_log_handler;
@@ -151,15 +171,17 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
     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_set_ssid_white_list = wifi_set_ssid_white_list;
-    fn->wifi_set_gscan_roam_params = wifi_set_gscan_roam_params;
-    fn->wifi_set_bssid_preference = wifi_set_bssid_preference;
     fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist;
-    fn->wifi_enable_lazy_roam = wifi_enable_lazy_roam;
     fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring;
     fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring;
+    fn->wifi_configure_nd_offload = wifi_configure_nd_offload;
     fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet;
     fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet;
+    fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring;
+    fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates;
+    fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates;
+    fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities;
+    fn->wifi_set_packet_filter = wifi_set_packet_filter;
     return WIFI_SUCCESS;
 }
 
@@ -645,7 +667,7 @@ public:
         }
 
         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
-        ret = mMsg.put_u32(ATTR_NODFS_VALUE, mNoDfs);
+        ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_NODFS_SET, mNoDfs);
         if (ret < 0) {
              return ret;
         }
@@ -673,7 +695,7 @@ public:
         }
 
         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
-        ret = mMsg.put_string(ATTR_COUNTRY_CODE, mCountryCode);
+        ret = mMsg.put_string(ANDR_WIFI_ATTRIBUTE_COUNTRY, mCountryCode);
         if (ret < 0) {
             return ret;
         }
@@ -800,6 +822,173 @@ public:
 
 };
 
+class AndroidPktFilterCommand : public WifiCommand {
+    private:
+        const u8* mProgram;
+        u32 mProgramLen;
+        u32* mVersion;
+        u32* mMaxLen;
+        int mReqType;
+    public:
+        AndroidPktFilterCommand(wifi_interface_handle handle,
+                u32* version, u32* max_len)
+            : WifiCommand("AndroidPktFilterCommand", handle, 0),
+                    mVersion(version), mMaxLen(max_len),
+                    mReqType(GET_APF_CAPABILITIES)
+        {
+        }
+
+        AndroidPktFilterCommand(wifi_interface_handle handle,
+                const u8* program, u32 len)
+            : WifiCommand("AndroidPktFilterCommand", handle, 0),
+                    mProgram(program), mProgramLen(len),
+                    mReqType(SET_APF_PROGRAM)
+        {
+        }
+
+    int createRequest(WifiRequest& request) {
+        if (mReqType == SET_APF_PROGRAM) {
+            ALOGI("\n%s: APF set program request\n", __FUNCTION__);
+            return createSetPktFilterRequest(request);
+        } else if (mReqType == GET_APF_CAPABILITIES) {
+            ALOGI("\n%s: APF get capabilities request\n", __FUNCTION__);
+            return createGetPktFilterCapabilitesRequest(request);
+        } else {
+            ALOGE("\n%s Unknown APF request\n", __FUNCTION__);
+            return WIFI_ERROR_NOT_SUPPORTED;
+        }
+        return WIFI_SUCCESS;
+    }
+
+    int createSetPktFilterRequest(WifiRequest& request) {
+        u8 *program = new u8[mProgramLen];
+        NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+        int result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(APF_ATTRIBUTE_PROGRAM_LEN, mProgramLen);
+        if (result < 0) {
+            return result;
+        }
+        memcpy(program, mProgram, mProgramLen);
+        result = request.put(APF_ATTRIBUTE_PROGRAM, program, mProgramLen);
+        if (result < 0) {
+            return result;
+        }
+        request.attr_end(data);
+        delete[] program;
+        return result;
+    }
+
+    int createGetPktFilterCapabilitesRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, APF_SUBCMD_GET_CAPABILITIES);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        WifiRequest request(familyId(), ifaceId());
+        int result = createRequest(request);
+        if (result < 0) {
+            return result;
+        }
+        result = requestResponse(request);
+        if (result < 0) {
+            ALOGI("Request Response failed for APF, result = %d", result);
+            return result;
+        }
+        ALOGI("Done!");
+        return result;
+    }
+
+    int cancel() {
+        return WIFI_SUCCESS;
+    }
+
+    int handleResponse(WifiEvent& reply) {
+        ALOGD("In SetAPFCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = reply.get_vendor_data_len();
+
+        ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("no vendor data in SetAPFCommand response; ignoring it");
+            return NL_SKIP;
+        }
+        if( mReqType == SET_APF_PROGRAM) {
+            ALOGD("Response recieved for set packet filter command\n");
+        } else if (mReqType == GET_APF_CAPABILITIES) {
+            *mVersion = 0;
+            *mMaxLen = 0;
+            ALOGD("Response recieved for get packet filter capabilities command\n");
+            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                if (it.get_type() == APF_ATTRIBUTE_VERSION) {
+                    *mVersion = it.get_u32();
+                    ALOGI("APF version is %d\n", *mVersion);
+                } else if (it.get_type() == APF_ATTRIBUTE_MAX_LEN) {
+                    *mMaxLen = it.get_u32();
+                    ALOGI("APF max len is %d\n", *mMaxLen);
+                } else {
+                    ALOGE("Ignoring invalid attribute type = %d, size = %d",
+                            it.get_type(), it.get_len());
+                }
+            }
+        }
+        return NL_OK;
+    }
+
+    int handleEvent(WifiEvent& event) {
+        /* No Event to recieve for APF commands */
+        return NL_SKIP;
+    }
+};
+
+class SetNdoffloadCommand : public WifiCommand {
+
+private:
+    u8 mEnable;
+public:
+    SetNdoffloadCommand(wifi_interface_handle handle, u8 enable)
+        : WifiCommand("SetNdoffloadCommand", handle, 0) {
+        mEnable = enable;
+    }
+    virtual int create() {
+        int ret;
+
+        ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_ND_OFFLOAD);
+        if (ret < 0) {
+            ALOGE("Can't create message to send to driver - %d", ret);
+            return ret;
+        }
+
+        nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
+        ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE, mEnable);
+        if (ret < 0) {
+             return ret;
+        }
+
+        mMsg.attr_end(data);
+        return WIFI_SUCCESS;
+    }
+};
+
 class GetFeatureSetCommand : public WifiCommand {
 
 private:
@@ -823,9 +1012,9 @@ public:
     virtual int create() {
         int ret;
 
-        if(feature_type == FEATURE_SET) {
+        if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
             ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET);
-        } else if (feature_type == FEATURE_SET_MATRIX) {
+        } else if (feature_type == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) {
             ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET_MATRIX);
         } else {
             ALOGE("Unknown feature type %d", feature_type);
@@ -860,7 +1049,7 @@ protected:
             ALOGE("no vendor data in GetFeatureSetCommand response; ignoring it");
             return NL_SKIP;
         }
-        if(feature_type == FEATURE_SET) {
+        if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
             void *data = reply.get_vendor_data();
             if(!fset) {
                 ALOGE("Buffers pointers not set");
@@ -997,14 +1186,15 @@ wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t
 
 wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
 {
-    GetFeatureSetCommand command(handle, FEATURE_SET, set, NULL, NULL, 1);
+    GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, set, NULL, NULL, 1);
     return (wifi_error) command.requestResponse();
 }
 
 wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
        feature_set set[], int *set_size)
 {
-    GetFeatureSetCommand command(handle, FEATURE_SET_MATRIX, NULL, set, set_size, set_size_max);
+    GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, NULL,
+            set, set_size, set_size_max);
     return (wifi_error) command.requestResponse();
 }
 
@@ -1033,16 +1223,21 @@ static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_
     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();
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = wifi_register_cmd(handle, id, cmd);
+    if (result != WIFI_SUCCESS) {
+        cmd->releaseRef();
+        return result;
+    }
+    result = (wifi_error)cmd->start();
     if (result != WIFI_SUCCESS) {
         wifi_unregister_cmd(handle, id);
+        cmd->releaseRef();
+        return result;
     }
     return result;
 }
 
-
 static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface)
 {
     ALOGD("Stopping RSSI monitor");
@@ -1054,6 +1249,7 @@ static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_h
         memset(&handler, 0, sizeof(handler));
         SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface,
                                                     max_rssi, min_rssi, handler);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
         cmd->cancel();
         cmd->releaseRef();
         return WIFI_SUCCESS;
@@ -1061,4 +1257,35 @@ static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_h
     return wifi_cancel_cmd(id, iface);
 }
 
+static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
+        u32 *version, u32 *max_len)
+{
+    ALOGD("Getting APF capabilities, halHandle = %p\n", handle);
+    AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, version, max_len);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    if (result == WIFI_SUCCESS) {
+        ALOGD("Getting APF capability, version = %d, max_len = %d\n", *version, *max_len);
+    }
+    cmd->releaseRef();
+    return result;
+}
+
+static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
+        const u8 *program, u32 len)
+{
+    ALOGD("Setting APF program, halHandle = %p\n", handle);
+    AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, program, len);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
+
+static wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable)
+{
+    SetNdoffloadCommand command(handle, enable);
+    return (wifi_error) command.requestResponse();
+}
+
 /////////////////////////////////////////////////////////////////////////////
index be1467f9e107e02e015ace254543d270f64798ce..f0dc3263c618d0f4053a84eb758f576f41286a89 100644 (file)
@@ -37,6 +37,11 @@ typedef enum {
     LOGGER_GET_RING_DATA,
     LOGGER_GET_FEATURE,
     LOGGER_RESET_LOGGING,
+    LOGGER_TRIGGER_DRIVER_MEM_DUMP,
+    LOGGER_GET_DRIVER_MEM_DUMP,
+    LOGGER_START_PKT_FATE_MONITORING,
+    LOGGER_GET_TX_PKT_FATES,
+    LOGGER_GET_RX_PKT_FATES,
 } DEBUG_SUB_COMMAND;
 
 typedef enum {
@@ -54,6 +59,10 @@ typedef enum {
     LOGGER_ATTRIBUTE_RING_DATA,
     LOGGER_ATTRIBUTE_RING_STATUS,
     LOGGER_ATTRIBUTE_RING_NUM,
+    LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN,
+    LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA,
+    LOGGER_ATTRIBUTE_PKT_FATE_NUM,
+    LOGGER_ATTRIBUTE_PKT_FATE_DATA,
 } LOGGER_ATTRIBUTE;
 
 typedef enum {
@@ -73,6 +82,12 @@ typedef enum {
     START_RING_LOG,
 } GetCmdType;
 
+typedef enum {
+    PACKET_MONITOR_START,
+    TX_PACKET_FATE,
+    RX_PACKET_FATE,
+} PktFateReqType;
+
 
 ///////////////////////////////////////////////////////////////////////////////
 class DebugCommand : public WifiCommand
@@ -372,7 +387,10 @@ wifi_error wifi_get_firmware_version(wifi_interface_handle iface, char *buffer,
 {
     if (buffer && (buffer_size > 0)) {
         DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_FW_VER);
-        return (wifi_error)cmd->start();
+        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;
@@ -384,7 +402,10 @@ wifi_error wifi_get_driver_version(wifi_interface_handle iface, char *buffer, in
 {
     if (buffer && (buffer_size > 0)) {
         DebugCommand *cmd = new DebugCommand(iface, buffer, &buffer_size, GET_DRV_VER);
-        return (wifi_error)cmd->start();
+        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;
@@ -395,7 +416,10 @@ wifi_error wifi_get_driver_version(wifi_interface_handle iface, char *buffer, in
 wifi_error wifi_get_ring_data(wifi_interface_handle iface, char *ring_name)
 {
     DebugCommand *cmd = new DebugCommand(iface, ring_name, GET_RING_DATA);
-    return (wifi_error)cmd->start();
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
 }
 
 /* API to get the status of all ring buffers supported by driver */
@@ -404,7 +428,10 @@ wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface,
 {
     if (status && num_rings) {
         DebugCommand *cmd = new DebugCommand(iface, num_rings, status, GET_RING_STATUS);
-        return (wifi_error)cmd->start();
+        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;
@@ -417,7 +444,10 @@ wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,
 {
     if (support) {
         DebugCommand *cmd = new DebugCommand(iface, support, GET_FEATURE);
-        return (wifi_error)cmd->start();
+        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;
@@ -428,9 +458,12 @@ 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);
-        return (wifi_error)cmd->start();
+        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;
@@ -529,16 +562,19 @@ wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface,
     ALOGV("Loghandler start, handle = %p", handle);
 
     SetLogHandler *cmd = new SetLogHandler(iface, id, handler);
-    if (cmd) {
-        wifi_register_cmd(handle, id, cmd);
-        wifi_error result = (wifi_error)cmd->start();
-        if (result != WIFI_SUCCESS)
-            wifi_unregister_cmd(handle, id);
+    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;
-    } else {
-        ALOGD("Out of memory");
-        return WIFI_ERROR_OUT_OF_MEMORY;
     }
+    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)
@@ -551,6 +587,7 @@ wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle ifac
         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;
@@ -708,17 +745,19 @@ wifi_error wifi_set_alert_handler(wifi_request_id id, wifi_interface_handle ifac
     ALOGV("Alerthandler start, handle = %p", handle);
 
     SetAlertHandler *cmd = new SetAlertHandler(iface, id, handler);
-
-    if (cmd) {
-        wifi_register_cmd(handle, id, cmd);
-        wifi_error result = (wifi_error)cmd->start();
-        if (result != WIFI_SUCCESS)
-            wifi_unregister_cmd(handle, id);
+    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;
-    } else {
-        ALOGE("Out of memory");
-        return WIFI_ERROR_OUT_OF_MEMORY;
     }
+    return result;
 }
 
 wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle iface)
@@ -731,6 +770,7 @@ wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle if
         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;
@@ -850,6 +890,203 @@ wifi_error wifi_get_firmware_memory_dump( wifi_interface_handle iface,
         wifi_firmware_memory_dump_handler handler)
 {
     MemoryDumpCommand *cmd = new MemoryDumpCommand(iface, handler);
-    return (wifi_error)cmd->start();
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
 }
 
+class PacketFateCommand: public WifiCommand
+{
+    void *mReportBufs;
+    size_t mNoReqFates;
+    size_t *mNoProvidedFates;
+    PktFateReqType mReqType;
+
+public:
+    PacketFateCommand(wifi_interface_handle handle)
+        : WifiCommand("PacketFateCommand", handle, 0), mReqType(PACKET_MONITOR_START)
+    { }
+
+    PacketFateCommand(wifi_interface_handle handle, wifi_tx_report *tx_report_bufs,
+            size_t n_requested_fates, size_t *n_provided_fates)
+        : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(tx_report_bufs),
+                  mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates),
+                  mReqType(TX_PACKET_FATE)
+    { }
+
+    PacketFateCommand(wifi_interface_handle handle, wifi_rx_report *rx_report_bufs,
+            size_t n_requested_fates, size_t *n_provided_fates)
+        : WifiCommand("PacketFateCommand", handle, 0), mReportBufs(rx_report_bufs),
+                  mNoReqFates(n_requested_fates), mNoProvidedFates(n_provided_fates),
+                  mReqType(RX_PACKET_FATE)
+    { }
+
+    int createRequest(WifiRequest& request) {
+        if (mReqType == TX_PACKET_FATE) {
+            ALOGD("%s Get Tx packet fate request\n", __FUNCTION__);
+            return createTxPktFateRequest(request);
+        } else if (mReqType == RX_PACKET_FATE) {
+            ALOGD("%s Get Rx packet fate request\n", __FUNCTION__);
+            return createRxPktFateRequest(request);
+        } else if (mReqType == PACKET_MONITOR_START) {
+            ALOGD("%s Monitor packet fate request\n", __FUNCTION__);
+            return createMonitorPktFateRequest(request);
+        } else {
+            ALOGE("%s Unknown packet fate request\n", __FUNCTION__);
+            return WIFI_ERROR_NOT_SUPPORTED;
+        }
+        return WIFI_SUCCESS;
+    }
+
+    int createMonitorPktFateRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, LOGGER_START_PKT_FATE_MONITORING);
+        if (result < 0) {
+            return result;
+        }
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        request.attr_end(data);
+        return result;
+    }
+
+    int createTxPktFateRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, LOGGER_GET_TX_PKT_FATES);
+        if (result < 0) {
+            return result;
+        }
+
+        memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_tx_report)));
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs);
+        if (result < 0) {
+            return result;
+        }
+        request.attr_end(data);
+        return result;
+    }
+
+    int createRxPktFateRequest(WifiRequest& request) {
+        int result = request.create(GOOGLE_OUI, LOGGER_GET_RX_PKT_FATES);
+        if (result < 0) {
+            return result;
+        }
+
+        memset(mReportBufs, 0, (mNoReqFates * sizeof(wifi_rx_report)));
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        result = request.put_u32(LOGGER_ATTRIBUTE_PKT_FATE_NUM, mNoReqFates);
+        if (result < 0) {
+            return result;
+        }
+        result = request.put_u64(LOGGER_ATTRIBUTE_PKT_FATE_DATA, (uint64_t)mReportBufs);
+        if (result < 0) {
+            return result;
+        }
+        request.attr_end(data);
+        return result;
+    }
+
+    int start() {
+        ALOGD("Start get packet fate command\n");
+        WifiRequest request(familyId(), ifaceId());
+
+        int result = createRequest(request);
+        if (result < 0) {
+            ALOGE("Failed to create get pkt fate request; result = %d\n", result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("Failed to register get pkt fate response; result = %d\n", result);
+        }
+        return result;
+    }
+
+    int handleResponse(WifiEvent& reply) {
+        ALOGD("In GetPktFateCommand::handleResponse\n");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGI("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = reply.get_vendor_data_len();
+
+        ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
+
+        if (mReqType == TX_PACKET_FATE) {
+            ALOGI("Response recieved for get TX pkt fate command\n");
+        } else if (mReqType == RX_PACKET_FATE) {
+            ALOGI("Response recieved for get RX pkt fate command\n");
+        } else if (mReqType == PACKET_MONITOR_START) {
+            ALOGI("Response recieved for monitor pkt fate command\n");
+            return NL_OK;
+        } else {
+            ALOGE("Response recieved for unknown pkt fate command\n");
+            return NL_SKIP;
+        }
+
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("no vendor data in GetPktFateCommand response; ignoring it\n");
+            return NL_SKIP;
+        }
+
+        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+            if (it.get_type() == LOGGER_ATTRIBUTE_PKT_FATE_NUM) {
+                *mNoProvidedFates = it.get_u32();
+                ALOGI("No: of pkt fates provided is %d\n", *mNoProvidedFates);
+            } else {
+                ALOGE("Ignoring invalid attribute type = %d, size = %d\n",
+                        it.get_type(), it.get_len());
+            }
+        }
+
+        return NL_OK;
+    }
+
+    int handleEvent(WifiEvent& event) {
+        /* NO events to handle here! */
+        return NL_SKIP;
+    }
+};
+
+wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle)
+{
+    PacketFateCommand *cmd = new PacketFateCommand(handle);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
+
+wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle,
+        wifi_tx_report *tx_report_bufs, size_t n_requested_fates,
+        size_t *n_provided_fates)
+{
+    PacketFateCommand *cmd = new PacketFateCommand(handle, tx_report_bufs,
+                n_requested_fates, n_provided_fates);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
+
+wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle,
+        wifi_rx_report *rx_report_bufs, size_t n_requested_fates,
+        size_t *n_provided_fates)
+{
+    PacketFateCommand *cmd = new PacketFateCommand(handle, rx_report_bufs,
+                n_requested_fates, n_provided_fates);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    wifi_error result = (wifi_error)cmd->start();
+    cmd->releaseRef();
+    return result;
+}
index 41cc13f154556bcb704e8ad09307b78044e89bb3..2dc92287f3385bd751104ae932e5a473f057d195 100644 (file)
@@ -205,8 +205,9 @@ wifi_error wifi_start_sending_offloaded_packet(wifi_request_id index, wifi_inter
             && (ip_packet_len <= MKEEP_ALIVE_IP_PKT_MAX)) {
         MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, ip_packet, ip_packet_len,
                 src_mac_addr, dst_mac_addr, period_msec, START_MKEEP_ALIVE);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
         wifi_error result = (wifi_error)cmd->start();
-        delete cmd;
+        cmd->releaseRef();
         return result;
     } else {
         ALOGE("Invalid mkeep_alive parameters");
@@ -219,8 +220,9 @@ wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id index, wifi_interf
 {
     if (index > 0 && index <= N_AVAIL_ID) {
         MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, STOP_MKEEP_ALIVE);
+        NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
         wifi_error result = (wifi_error)cmd->start();
-        delete cmd;
+        cmd->releaseRef();
         return result;
     } else {
         ALOGE("Invalid mkeep_alive parameters");
Simple merge
Simple merge