More GScan feature tweaks
Ashwin [Wed, 25 Jun 2014 23:33:35 +0000 (16:33 -0700)]
1. Scan complete event
2. get feature list
3. get channel list

 Changes to be committed:
modified:   bcmdhd/firmware/bcm4339/fw_bcmdhd.bin
modified:   bcmdhd/wifi_hal/common.h
modified:   bcmdhd/wifi_hal/gscan.cpp
modified:   bcmdhd/wifi_hal/wifi_hal.cpp

Change-Id: I98383f8aca1a486dbe16560e0e65a6764556cca3

bcmdhd/firmware/bcm4339/fw_bcmdhd.bin
bcmdhd/wifi_hal/common.h
bcmdhd/wifi_hal/gscan.cpp
bcmdhd/wifi_hal/wifi_hal.cpp

index f3a6ca0..3f4ebd3 100755 (executable)
Binary files a/bcmdhd/firmware/bcm4339/fw_bcmdhd.bin and b/bcmdhd/firmware/bcm4339/fw_bcmdhd.bin differ
index a06c75d..e617e4e 100644 (file)
@@ -59,13 +59,39 @@ typedef enum {
 } ANDROID_VENDOR_SUB_COMMAND;
 
 typedef enum {
+
+    GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
+
+    GSCAN_SUBCMD_SET_CONFIG,                            /* 0x1001 */
+
+    GSCAN_SUBCMD_SET_SCAN_CONFIG,                       /* 0x1002 */
+    GSCAN_SUBCMD_ENABLE_GSCAN,                          /* 0x1003 */
+    GSCAN_SUBCMD_GET_SCAN_RESULTS,                      /* 0x1004 */
+    GSCAN_SUBCMD_SCAN_RESULTS,                          /* 0x1005 */
+
+    GSCAN_SUBCMD_SET_HOTLIST,                           /* 0x1006 */
+
+    GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG,         /* 0x1007 */
+    GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS,              /* 0x1008 */
+    GSCAN_SUBCMD_GET_CHANNEL_LIST,                       /* 0x1009 */
+
+    WIFI_SUBCMD_GET_FEATURE_SET,                         /* 0x100A */
+    WIFI_SUBCMD_GET_FEATURE_SET_MATRIX,                  /* 0x100B */
+    /* Add more sub commands here */
+
+    GSCAN_SUBCMD_MAX                                    /* 0x100C */
+
+} WIFI_SUB_COMMAND;
+
+typedef enum {
     BRCM_RESERVED1,
     BRCM_RESERVED2,
     GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS ,
     GSCAN_EVENT_HOTLIST_RESULTS,
     GSCAN_EVENT_SCAN_RESULTS_AVAILABLE,
     GSCAN_EVENT_FULL_SCAN_RESULTS,
-       RTT_EVENT_COMPLETE
+    RTT_EVENT_COMPLETE,
+    GSCAN_EVENT_COMPLETE_SCAN
 
 } WIFI_EVENT;
 
index 93c030e..a130bd9 100644 (file)
 
 typedef enum {
 
-    GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
-
-    GSCAN_SUBCMD_SET_CONFIG,                            /* 0x1001 */
-
-    GSCAN_SUBCMD_SET_SCAN_CONFIG,                       /* 0x1002 */
-    GSCAN_SUBCMD_ENABLE_GSCAN,                          /* 0x1003 */
-    GSCAN_SUBCMD_GET_SCAN_RESULTS,                      /* 0x1004 */
-    GSCAN_SUBCMD_SCAN_RESULTS,                          /* 0x1005 */
-
-    GSCAN_SUBCMD_SET_HOTLIST,                           /* 0x1006 */
-
-    GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG,         /* 0x1007 */
-    GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS,              /* 0x1008 */
-    GSCAN_SUBCMD_GET_CHANNEL_LIST,                       /* 0x1009 */
-
-    /* Add more sub commands here */
-
-    GSCAN_SUBCMD_MAX                                    /* 0x100A */
-
-} GSCAN_SUB_COMMAND;
-
-typedef enum {
-
     GSCAN_ATTRIBUTE_NUM_BUCKETS = 10,
     GSCAN_ATTRIBUTE_BASE_PERIOD,
     GSCAN_ATTRIBUTE_BUCKETS_BAND,
@@ -518,13 +495,6 @@ public:
         }
 
         int num_scans = 20;
-        for (int i = 0; i < mParams->num_buckets; i++) {
-            if (mParams->buckets[i].report_events == 1) {
-                ALOGD("Setting num_scans to 1");
-                num_scans = 1;
-                break;
-            }
-        }
 
         result = request.put_u32(GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, num_scans);
         if (result < 0) {
@@ -629,6 +599,8 @@ public:
         }
 
         registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
+        registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
+
 
         result = requestResponse(request);
         if (result != WIFI_SUCCESS) {
@@ -673,15 +645,31 @@ public:
 
         nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
         int len = event.get_vendor_data_len();
+        int event_id = event.get_vendor_subcmd();
 
-        if (vendor_data == NULL || len != 4) {
-            ALOGI("No scan results found");
-            return NL_SKIP;
-        }
+        if(event_id == GSCAN_EVENT_COMPLETE_SCAN) {
+            if (vendor_data == NULL || len != 4) {
+                ALOGI("Scan complete type not mentioned!");
+                return NL_SKIP;
+            }
+            wifi_scan_event evt_type;
+
+            evt_type = (wifi_scan_event) event.get_u32(NL80211_ATTR_VENDOR_DATA);
+            ALOGI("Scan complete: Received event type %d", evt_type);
+            if(*mHandler.on_scan_event)
+                (*mHandler.on_scan_event)(evt_type, evt_type);
+        } else {
 
-        int num = event.get_u32(NL80211_ATTR_VENDOR_DATA);
-        ALOGI("Found %d scan results", num);
-        (*mHandler.on_scan_results_available)(id(), num);
+            if (vendor_data == NULL || len != 4) {
+                ALOGI("No scan results found");
+                return NL_SKIP;
+            }
+
+            int num = event.get_u32(NL80211_ATTR_VENDOR_DATA);
+            ALOGI("Found %d scan results", num);
+            if(*mHandler.on_scan_results_available)
+                (*mHandler.on_scan_results_available)(id(), num);
+        }
         return NL_SKIP;
     }
 };
@@ -1271,7 +1259,7 @@ public:
             uint16_t flags;
             uint16_t channel;
             mac_addr bssid;
-            byte rssi_history[8];
+            s8 rssi_history[8];
         } ChangeInfo;
 
         int num = min(len / sizeof(ChangeInfo), MAX_RESULTS);
@@ -1281,7 +1269,8 @@ public:
             memcpy(mResultsBuffer[i].bssid, ci[i].bssid, sizeof(mac_addr));
             mResultsBuffer[i].channel = ci[i].channel;
             mResultsBuffer[i].num_rssi = 8;
-            memcpy(mResultsBuffer[i].rssi, ci[i].rssi_history, 8);
+            for (int j = 0; j < mResultsBuffer[i].num_rssi; j++)
+                mResultsBuffer[i].rssi[j] = (int) ci[i].rssi_history[j];
             mResults[i] = reinterpret_cast<wifi_significant_change_result *>(&(mResultsBuffer[i]));
         }
 
index 640c5e2..345da3c 100644 (file)
@@ -42,6 +42,9 @@
 #define WIFI_HAL_CMD_SOCK_PORT       644
 #define WIFI_HAL_EVENT_SOCK_PORT     645
 
+#define FEATURE_SET                  0
+#define FEATURE_SET_MATRIX           1
+
 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);
@@ -49,6 +52,11 @@ static int wifi_get_multicast_id(wifi_handle handle, const char *name, const cha
 static int wifi_add_membership(wifi_handle handle, const char *group);
 static wifi_error wifi_init_interfaces(wifi_handle handle);
 
+typedef enum wifi_feature_set_attr {
+    ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
+    ANDR_WIFI_ATTRIBUTE_FEATURE_SET
+} wifi_feature_set_attr_t;
+
 /* Initialize/Cleanup */
 
 void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
@@ -98,7 +106,7 @@ wifi_error wifi_initialize(wifi_handle *handle)
     hal_info *info = (hal_info *)malloc(sizeof(hal_info));
     if (info == NULL) {
         ALOGE("Could not allocate hal_info");
-               return WIFI_ERROR_UNKNOWN;
+        return WIFI_ERROR_UNKNOWN;
     }
 
     memset(info, 0, sizeof(*info));
@@ -147,7 +155,7 @@ wifi_error wifi_initialize(wifi_handle *handle)
         nl_socket_free(cmd_sock);
         nl_socket_free(event_sock);
         free(info);
-               return WIFI_ERROR_UNKNOWN;
+        return WIFI_ERROR_UNKNOWN;
     }
 
     pthread_mutex_init(&info->cb_lock, NULL);
@@ -411,6 +419,105 @@ public:
 
 };
 
+class GetFeatureSetCommand : public WifiCommand {
+
+private:
+    int feature_type;
+    feature_set *fset;
+    feature_set *feature_matrix;
+    int *fm_size;
+    int set_size_max;
+public:
+    GetFeatureSetCommand(wifi_interface_handle handle, int feature, feature_set *set,
+         feature_set set_matrix[], int *size, int max_size)
+        : WifiCommand(handle, 0)
+    {
+        feature_type = feature;
+        fset = set;
+        feature_matrix = set_matrix;
+        fm_size = size;
+        set_size_max = max_size;
+    }
+
+    virtual int create() {
+        int ret;
+
+        if(feature_type == FEATURE_SET) {
+            ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET);
+        } else if (feature_type == FEATURE_SET_MATRIX){
+            ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET_MATRIX);
+        } else {
+            ALOGE("Unknown feature type %d", feature_type);
+            return -1;
+        }
+
+        if (ret < 0) {
+            ALOGE("Can't create message to send to driver - %d", ret);
+        }
+
+        return ret;
+    }
+
+protected:
+    virtual int handleResponse(WifiEvent& reply) {
+
+        ALOGD("In GetFeatureSetCommand::handleResponse");
+
+        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+
+        int id = reply.get_vendor_id();
+        int subcmd = reply.get_vendor_subcmd();
+
+        nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+        int len = reply.get_vendor_data_len();
+
+        ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
+        if (vendor_data == NULL || len == 0) {
+            ALOGE("no vendor data in GetFeatureSetCommand response; ignoring it");
+            return NL_SKIP;
+        }
+        if(feature_type == FEATURE_SET) {
+            void *data = reply.get_vendor_data();
+            if(!fset) {
+                ALOGE("Buffers pointers not set");
+                return NL_SKIP;
+            }
+            memcpy(fset, data, min(len, (int) sizeof(*fset)));
+        } else {
+            int num_features_set = 0;
+            int i = 0;
+
+            if(!feature_matrix || !fm_size) {
+                ALOGE("Buffers pointers not set");
+                return NL_SKIP;
+            }
+
+            for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                if (it.get_type() == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
+                    num_features_set = it.get_u32();
+                    ALOGI("Got feature list with %d concurrent sets", num_features_set);
+                    if(set_size_max && (num_features_set > set_size_max))
+                        num_features_set = set_size_max;
+                    *fm_size = num_features_set;
+                } else if ((it.get_type() == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) &&
+                             i < num_features_set) {
+                    feature_matrix[i] = it.get_u32();
+                    i++;
+                } else {
+                    ALOGW("Ignoring invalid attribute type = %d, size = %d",
+                            it.get_type(), it.get_len());
+                }
+            }
+
+        }
+        return NL_OK;
+    }
+
+};
+
 static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group)
 {
     GetMulticastIdCommand cmd(handle, name, group);
@@ -507,5 +614,18 @@ wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t
     return WIFI_SUCCESS;
 }
 
+wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
+{
+    GetFeatureSetCommand command(handle, 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);
+    return (wifi_error) command.requestResponse();
+}
+
 /////////////////////////////////////////////////////////////////////////////