summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bcmdhd/config/Android.mk9
-rw-r--r--bcmdhd/config/android_dhcpcd.conf9
-rw-r--r--bcmdhd/firmware/bcm4339/fw_bcmdhd.binbin562195 -> 562183 bytes
-rw-r--r--bcmdhd/firmware/bcm4339/fw_bcmdhd_apsta.binbin500036 -> 500032 bytes
-rw-r--r--bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.binbin553980 -> 0 bytes
-rw-r--r--[-rwxr-xr-x]bcmdhd/firmware/bcm4354/fw_bcm4354.binbin625635 -> 625474 bytes
-rw-r--r--[-rwxr-xr-x]bcmdhd/firmware/bcm4354/fw_bcm4354_ap.binbin548322 -> 548145 bytes
-rw-r--r--bcmdhd/firmware/bcm4356/fw_bcm4356_ap_pcie.binbin588340 -> 588159 bytes
-rw-r--r--bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.binbin661509 -> 660969 bytes
-rw-r--r--bcmdhd/firmware/bcm4358/fw_bcm4358.binbin624655 -> 628487 bytes
-rw-r--r--bcmdhd/firmware/bcm4358/fw_bcm4358_ap.binbin559737 -> 560304 bytes
-rw-r--r--bcmdhd/wifi_hal/common.cpp7
-rw-r--r--bcmdhd/wifi_hal/common.h47
-rw-r--r--bcmdhd/wifi_hal/gscan.cpp771
-rw-r--r--bcmdhd/wifi_hal/link_layer_stats.cpp89
-rw-r--r--bcmdhd/wifi_hal/rtt.cpp193
-rw-r--r--bcmdhd/wifi_hal/wifi_hal.cpp269
-rw-r--r--bcmdhd/wifi_hal/wifi_logger.cpp289
-rw-r--r--bcmdhd/wifi_hal/wifi_offload.cpp6
19 files changed, 1070 insertions, 619 deletions
diff --git a/bcmdhd/config/Android.mk b/bcmdhd/config/Android.mk
index b125897..8c3b13f 100644
--- a/bcmdhd/config/Android.mk
+++ b/bcmdhd/config/Android.mk
@@ -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
index 0fe3996..0000000
--- a/bcmdhd/config/android_dhcpcd.conf
+++ /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.bin b/bcmdhd/firmware/bcm4339/fw_bcmdhd.bin
index af2c885..bc8316d 100644
--- a/bcmdhd/firmware/bcm4339/fw_bcmdhd.bin
+++ b/bcmdhd/firmware/bcm4339/fw_bcmdhd.bin
Binary files differ
diff --git a/bcmdhd/firmware/bcm4339/fw_bcmdhd_apsta.bin b/bcmdhd/firmware/bcm4339/fw_bcmdhd_apsta.bin
index 4f5f105..11cf14b 100644
--- a/bcmdhd/firmware/bcm4339/fw_bcmdhd_apsta.bin
+++ b/bcmdhd/firmware/bcm4339/fw_bcmdhd_apsta.bin
Binary files differ
diff --git a/bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.bin b/bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.bin
deleted file mode 100644
index b40cd8a..0000000
--- a/bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.bin
+++ /dev/null
Binary files differ
diff --git a/bcmdhd/firmware/bcm4354/fw_bcm4354.bin b/bcmdhd/firmware/bcm4354/fw_bcm4354.bin
index 8a766f7..79492a5 100755..100644
--- a/bcmdhd/firmware/bcm4354/fw_bcm4354.bin
+++ b/bcmdhd/firmware/bcm4354/fw_bcm4354.bin
Binary files differ
diff --git a/bcmdhd/firmware/bcm4354/fw_bcm4354_ap.bin b/bcmdhd/firmware/bcm4354/fw_bcm4354_ap.bin
index 43efaaa..1208a09 100755..100644
--- a/bcmdhd/firmware/bcm4354/fw_bcm4354_ap.bin
+++ b/bcmdhd/firmware/bcm4354/fw_bcm4354_ap.bin
Binary files differ
diff --git a/bcmdhd/firmware/bcm4356/fw_bcm4356_ap_pcie.bin b/bcmdhd/firmware/bcm4356/fw_bcm4356_ap_pcie.bin
index 6404d65..f41c2ed 100644
--- a/bcmdhd/firmware/bcm4356/fw_bcm4356_ap_pcie.bin
+++ b/bcmdhd/firmware/bcm4356/fw_bcm4356_ap_pcie.bin
Binary files differ
diff --git a/bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.bin b/bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.bin
index 59d7663..a8a3717 100644
--- a/bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.bin
+++ b/bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.bin
Binary files differ
diff --git a/bcmdhd/firmware/bcm4358/fw_bcm4358.bin b/bcmdhd/firmware/bcm4358/fw_bcm4358.bin
index fff02ad..76d15bb 100644
--- a/bcmdhd/firmware/bcm4358/fw_bcm4358.bin
+++ b/bcmdhd/firmware/bcm4358/fw_bcm4358.bin
Binary files differ
diff --git a/bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin b/bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin
index 379eca6..98f889e 100644
--- a/bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin
+++ b/bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin
Binary files differ
diff --git a/bcmdhd/wifi_hal/common.cpp b/bcmdhd/wifi_hal/common.cpp
index f0184d6..69ed256 100644
--- a/bcmdhd/wifi_hal/common.cpp
+++ b/bcmdhd/wifi_hal/common.cpp
@@ -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;
}
diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h
index 118e0fc..2967c97 100644
--- a/bcmdhd/wifi_hal/common.h
+++ b/bcmdhd/wifi_hal/common.h
@@ -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
diff --git a/bcmdhd/wifi_hal/gscan.cpp b/bcmdhd/wifi_hal/gscan.cpp
index 418537b..52ec284 100644
--- a/bcmdhd/wifi_hal/gscan.cpp
+++ b/bcmdhd/wifi_hal/gscan.cpp
@@ -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);
}
-
diff --git a/bcmdhd/wifi_hal/link_layer_stats.cpp b/bcmdhd/wifi_hal/link_layer_stats.cpp
index 170c791..1ef8516 100644
--- a/bcmdhd/wifi_hal/link_layer_stats.cpp
+++ b/bcmdhd/wifi_hal/link_layer_stats.cpp
@@ -26,6 +26,21 @@
#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,
diff --git a/bcmdhd/wifi_hal/rtt.cpp b/bcmdhd/wifi_hal/rtt.cpp
index f77fdb0..410196b 100644
--- a/bcmdhd/wifi_hal/rtt.cpp
+++ b/bcmdhd/wifi_hal/rtt.cpp
@@ -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();
+}
+
diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp
index fdb7d7b..251414b 100644
--- a/bcmdhd/wifi_hal/wifi_hal.cpp
+++ b/bcmdhd/wifi_hal/wifi_hal.cpp
@@ -42,11 +42,6 @@
#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();
+}
+
/////////////////////////////////////////////////////////////////////////////
diff --git a/bcmdhd/wifi_hal/wifi_logger.cpp b/bcmdhd/wifi_hal/wifi_logger.cpp
index be1467f..f0dc326 100644
--- a/bcmdhd/wifi_hal/wifi_logger.cpp
+++ b/bcmdhd/wifi_hal/wifi_logger.cpp
@@ -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;
+}
diff --git a/bcmdhd/wifi_hal/wifi_offload.cpp b/bcmdhd/wifi_hal/wifi_offload.cpp
index 41cc13f..2dc9228 100644
--- a/bcmdhd/wifi_hal/wifi_offload.cpp
+++ b/bcmdhd/wifi_hal/wifi_offload.cpp
@@ -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");