diff options
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 Binary files differindex af2c885..bc8316d 100644 --- a/bcmdhd/firmware/bcm4339/fw_bcmdhd.bin +++ b/bcmdhd/firmware/bcm4339/fw_bcmdhd.bin diff --git a/bcmdhd/firmware/bcm4339/fw_bcmdhd_apsta.bin b/bcmdhd/firmware/bcm4339/fw_bcmdhd_apsta.bin Binary files differindex 4f5f105..11cf14b 100644 --- a/bcmdhd/firmware/bcm4339/fw_bcmdhd_apsta.bin +++ b/bcmdhd/firmware/bcm4339/fw_bcmdhd_apsta.bin diff --git a/bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.bin b/bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.bin Binary files differdeleted file mode 100644 index b40cd8a..0000000 --- a/bcmdhd/firmware/bcm4339/fw_bcmdhd_fp.bin +++ /dev/null diff --git a/bcmdhd/firmware/bcm4354/fw_bcm4354.bin b/bcmdhd/firmware/bcm4354/fw_bcm4354.bin Binary files differindex 8a766f7..79492a5 100755..100644 --- a/bcmdhd/firmware/bcm4354/fw_bcm4354.bin +++ b/bcmdhd/firmware/bcm4354/fw_bcm4354.bin diff --git a/bcmdhd/firmware/bcm4354/fw_bcm4354_ap.bin b/bcmdhd/firmware/bcm4354/fw_bcm4354_ap.bin Binary files differindex 43efaaa..1208a09 100755..100644 --- a/bcmdhd/firmware/bcm4354/fw_bcm4354_ap.bin +++ b/bcmdhd/firmware/bcm4354/fw_bcm4354_ap.bin diff --git a/bcmdhd/firmware/bcm4356/fw_bcm4356_ap_pcie.bin b/bcmdhd/firmware/bcm4356/fw_bcm4356_ap_pcie.bin Binary files differindex 6404d65..f41c2ed 100644 --- a/bcmdhd/firmware/bcm4356/fw_bcm4356_ap_pcie.bin +++ b/bcmdhd/firmware/bcm4356/fw_bcm4356_ap_pcie.bin diff --git a/bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.bin b/bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.bin Binary files differindex 59d7663..a8a3717 100644 --- a/bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.bin +++ b/bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.bin diff --git a/bcmdhd/firmware/bcm4358/fw_bcm4358.bin b/bcmdhd/firmware/bcm4358/fw_bcm4358.bin Binary files differindex fff02ad..76d15bb 100644 --- a/bcmdhd/firmware/bcm4358/fw_bcm4358.bin +++ b/bcmdhd/firmware/bcm4358/fw_bcm4358.bin diff --git a/bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin b/bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin Binary files differindex 379eca6..98f889e 100644 --- a/bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin +++ b/bcmdhd/firmware/bcm4358/fw_bcm4358_ap.bin 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, ¶ms, 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, ¶ms_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, ¶ms_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, ¶ms); - 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"); |