merge in mnc-dr-release history after reset to mnc-dr-dev
diff --git a/bcmdhd/config/wpa_supplicant_overlay.conf b/bcmdhd/config/wpa_supplicant_overlay.conf
index 84d19d8..740792b 100644
--- a/bcmdhd/config/wpa_supplicant_overlay.conf
+++ b/bcmdhd/config/wpa_supplicant_overlay.conf
@@ -1,4 +1,5 @@
disable_scan_offload=1
wowlan_triggers=any
p2p_disabled=1
+filter_rssi=-75
no_ctrl_interface=
\ No newline at end of file
diff --git a/bcmdhd/firmware/bcm4354/fw_bcm4354.bin b/bcmdhd/firmware/bcm4354/fw_bcm4354.bin
old mode 100755
new mode 100644
index 3952589..fd7b0ca
--- 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
old mode 100755
new mode 100644
index dcc2f11..27fd7cc
--- 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
old mode 100755
new mode 100644
index 7ebe5ed..37b4776
--- 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
old mode 100755
new mode 100644
index 26fbe54..a6e5cdd
--- a/bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.bin
+++ b/bcmdhd/firmware/bcm4356/fw_bcm4356_pcie.bin
Binary files differ
diff --git a/bcmdhd/wifi_hal/Android.mk b/bcmdhd/wifi_hal/Android.mk
index bb8514a..ea19efd 100644
--- a/bcmdhd/wifi_hal/Android.mk
+++ b/bcmdhd/wifi_hal/Android.mk
@@ -32,7 +32,8 @@
cpp_bindings.cpp \
gscan.cpp \
link_layer_stats.cpp \
- wifi_logger.cpp
+ wifi_logger.cpp \
+ wifi_offload.cpp
LOCAL_MODULE := libwifi-hal-bcm
diff --git a/bcmdhd/wifi_hal/common.cpp b/bcmdhd/wifi_hal/common.cpp
index 61f4475..9182114 100644
--- a/bcmdhd/wifi_hal/common.cpp
+++ b/bcmdhd/wifi_hal/common.cpp
@@ -1,11 +1,23 @@
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
-#include <stdlib.h>
#include <linux/pkt_sched.h>
#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
#include <netlink/handlers.h>
#include "wifi_hal.h"
#include "common.h"
+#include "cpp_bindings.h"
interface_info *getIfaceInfo(wifi_interface_handle handle)
{
@@ -208,3 +220,19 @@
}
}
}
+
+wifi_error wifi_cancel_cmd(wifi_request_id id, wifi_interface_handle iface)
+{
+ wifi_handle handle = getWifiHandle(iface);
+
+ WifiCommand *cmd = wifi_unregister_cmd(handle, id);
+ ALOGV("Cancel WifiCommand = %p", cmd);
+ if (cmd) {
+ cmd->cancel();
+ cmd->releaseRef();
+ return WIFI_SUCCESS;
+ }
+
+ return WIFI_ERROR_INVALID_ARGS;
+}
+
diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h
index 26bb9a6..8c09c16 100644
--- a/bcmdhd/wifi_hal/common.h
+++ b/bcmdhd/wifi_hal/common.h
@@ -59,6 +59,10 @@
ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400,
ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF,
+ /* define all wifi offload related commands between 0x1600 and 0x16FF */
+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600,
+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF,
+
/* This is reserved for future usage */
} ANDROID_VENDOR_SUB_COMMAND;
@@ -95,6 +99,7 @@
WIFI_SUBCMD_SET_BSSID_BLACKLIST, /* 0x1014 */
GSCAN_SUBCMD_ANQPO_CONFIG, /* 0x1015 */
+ WIFI_SUBCMD_SET_RSSI_MONITOR, /* 0x1016 */
/* Add more sub commands here */
GSCAN_SUBCMD_MAX
@@ -114,7 +119,8 @@
GSCAN_EVENT_EPNO_EVENT,
GOOGLE_DEBUG_RING_EVENT,
GOOGLE_DEBUG_MEM_DUMP_EVENT,
- GSCAN_EVENT_ANQPO_HOTSPOT_MATCH
+ GSCAN_EVENT_ANQPO_HOTSPOT_MATCH,
+ GOOGLE_RSSI_MONITOR_EVENT
} WIFI_EVENT;
typedef void (*wifi_internal_event_handler) (wifi_handle handle, int events);
@@ -199,7 +205,7 @@
hal_info *getHalInfo(wifi_interface_handle handle);
wifi_handle getWifiHandle(hal_info *info);
wifi_interface_handle getIfaceHandle(interface_info *info);
-
+wifi_error wifi_cancel_cmd(wifi_request_id id, wifi_interface_handle iface);
// some common macros
diff --git a/bcmdhd/wifi_hal/gscan.cpp b/bcmdhd/wifi_hal/gscan.cpp
index d513f28..21ec30d 100644
--- a/bcmdhd/wifi_hal/gscan.cpp
+++ b/bcmdhd/wifi_hal/gscan.cpp
@@ -19,6 +19,7 @@
#include "sync.h"
#define LOG_TAG "WifiHAL"
+//#define LOG_NDEBUG 1 //uncomment to enable verbose logging
#include <utils/Log.h>
@@ -155,7 +156,7 @@
}
virtual int create() {
- ALOGD("Creating message to get scan capablities; iface = %d", mIfaceInfo->id);
+ ALOGV("Creating message to get scan capablities; iface = %d", mIfaceInfo->id);
int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CAPABILITIES);
if (ret < 0) {
@@ -168,7 +169,7 @@
protected:
virtual int handleResponse(WifiEvent& reply) {
- ALOGD("In GetCapabilities::handleResponse");
+ ALOGV("In GetCapabilities::handleResponse");
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
@@ -181,7 +182,7 @@
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,
+ ALOGV("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
sizeof(*mCapabilities));
memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities)));
@@ -213,7 +214,7 @@
memset(channels, 0, sizeof(wifi_channel) * max_channels);
}
virtual int create() {
- ALOGD("Creating message to get channel list; iface = %d", mIfaceInfo->id);
+ ALOGV("Creating message to get channel list; iface = %d", mIfaceInfo->id);
int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CHANNEL_LIST);
if (ret < 0) {
@@ -234,7 +235,7 @@
protected:
virtual int handleResponse(WifiEvent& reply) {
- ALOGD("In GetChannelList::handleResponse");
+ ALOGV("In GetChannelList::handleResponse");
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
@@ -248,7 +249,7 @@
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);
+ ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
if (vendor_data == NULL || len == 0) {
ALOGE("no vendor data in GetChannelList response; ignoring it");
return NL_SKIP;
@@ -371,7 +372,7 @@
}
int start() {
- // ALOGD("Enabling Full scan results");
+ ALOGV("Enabling Full scan results");
WifiRequest request(familyId(), ifaceId());
int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 1);
if (result != WIFI_SUCCESS) {
@@ -392,7 +393,7 @@
}
virtual int cancel() {
- // ALOGD("Disabling Full scan results");
+ ALOGV("Disabling Full scan results");
WifiRequest request(familyId(), ifaceId());
int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 0);
@@ -416,9 +417,8 @@
}
virtual int handleEvent(WifiEvent& event) {
- //ALOGI("Full scan results: Got an event");
-
- // event.log();
+ 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();
@@ -578,20 +578,20 @@
nBuckets++;
}
}
-
- // ALOGI("enableFullScanResultsIfRequired num %u needed %u global %u",
- // mParams->num_buckets, nBuckets, mGlobalFullScanBuckets);
+
+ 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) {
- ALOGI("failed to enable full scan results");
+ ALOGE("failed to enable full scan results");
return result;
} else {
- // ALOGI("successfully enabled full scan results");
+ ALOGV("successfully enabled full scan results");
}
} else {
- // ALOGI("mGlobalFullScanBuckets = %d, nBuckets = %d", mGlobalFullScanBuckets, nBuckets);
+ ALOGV("mGlobalFullScanBuckets = %d, nBuckets = %d", mGlobalFullScanBuckets, nBuckets);
}
mLocalFullScanBuckets = nBuckets;
@@ -610,9 +610,9 @@
if (mGlobalFullScanBuckets == 0) {
int result = wifi_disable_full_scan_results(0x1000, ifaceHandle());
if (result != WIFI_SUCCESS) {
- ALOGI("failed to disable full scan results");
+ ALOGE("failed to disable full scan results");
} else {
- // ALOGI("successfully disable full scan results");
+ ALOGV("successfully disable full scan results");
}
}
@@ -620,7 +620,7 @@
}
int start() {
- // ALOGD("GSCAN start");
+ ALOGV("GSCAN start");
WifiRequest request(familyId(), ifaceId());
int result = createSetupRequest(request);
if (result != WIFI_SUCCESS) {
@@ -648,7 +648,7 @@
return result;
}
- // ALOGD(" ....starting scan");
+ ALOGV(" ....starting scan");
result = createStartRequest(request);
if (result != WIFI_SUCCESS) {
@@ -672,7 +672,7 @@
}
virtual int cancel() {
- // ALOGD("Stopping scan");
+ ALOGV("Stopping scan");
WifiRequest request(familyId(), ifaceId());
int result = createStopRequest(request);
@@ -698,9 +698,8 @@
}
virtual int handleEvent(WifiEvent& event) {
- // ALOGI("Got a scan results event");
-
- // event.log();
+ ALOGV("Got a scan results event");
+ event.log();
nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
int len = event.get_vendor_data_len();
@@ -714,7 +713,7 @@
wifi_scan_event evt_type;
evt_type = (wifi_scan_event) event.get_u32(NL80211_ATTR_VENDOR_DATA);
- // ALOGI("Scan complete: Received event type %d", evt_type);
+ ALOGV("Scan complete: Received event type %d", evt_type);
if(*mHandler.on_scan_event)
(*mHandler.on_scan_event)(evt_type, evt_type);
} else {
@@ -725,7 +724,7 @@
}
int num = event.get_u32(NL80211_ATTR_VENDOR_DATA);
- // ALOGI("Found %d scan results", num);
+ ALOGV("Found %d scan results", num);
if(*mHandler.on_scan_results_available)
(*mHandler.on_scan_results_available)(id(), num);
}
@@ -743,17 +742,21 @@
{
wifi_handle handle = getWifiHandle(iface);
- // ALOGD("Starting GScan, halHandle = %p", handle);
+ ALOGV("Starting GScan, halHandle = %p", handle);
ScanCommand *cmd = new ScanCommand(iface, id, ¶ms, handler);
wifi_register_cmd(handle, id, cmd);
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface)
{
- // ALOGD("Stopping GScan");
wifi_handle handle = getWifiHandle(iface);
+ ALOGV("Stopping GScan, wifi_request_id = %d, halHandle = %p", id, handle);
if(id == -1) {
wifi_scan_result_handler handler;
@@ -767,15 +770,7 @@
return WIFI_SUCCESS;
}
-
- WifiCommand *cmd = wifi_unregister_cmd(handle, id);
- if (cmd) {
- cmd->cancel();
- cmd->releaseRef();
- return WIFI_SUCCESS;
- }
-
- return WIFI_ERROR_INVALID_ARGS;
+ return wifi_cancel_cmd(id, iface);
}
@@ -786,18 +781,22 @@
{
wifi_handle handle = getWifiHandle(iface);
int params_dummy;
-
- // ALOGD("Enabling full scan results, halHandle = %p", handle);
+
+ ALOGV("Enabling full scan results, halHandle = %p", handle);
FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, id, ¶ms_dummy, handler);
wifi_register_cmd(handle, id, cmd);
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface)
{
- // ALOGD("Disabling full scan results");
+ ALOGV("Disabling full scan results");
wifi_handle handle = getWifiHandle(iface);
if(id == -1) {
@@ -812,14 +811,7 @@
return WIFI_SUCCESS;
}
- WifiCommand *cmd = wifi_unregister_cmd(handle, id);
- if (cmd) {
- cmd->cancel();
- cmd->releaseRef();
- return WIFI_SUCCESS;
- }
-
- return WIFI_ERROR_INVALID_ARGS;
+ return wifi_cancel_cmd(id, iface);
}
@@ -865,7 +857,7 @@
int execute() {
WifiRequest request(familyId(), ifaceId());
- // ALOGI("retrieving %d scan results", mMax);
+ ALOGV("retrieving %d scan results", mMax);
for (int i = 0; i < 10 && mRetrieved < mMax; i++) {
int num_to_retrieve = mMax - mRetrieved;
@@ -899,7 +891,7 @@
}
virtual int handleResponse(WifiEvent& reply) {
- // ALOGD("In GetScanResultsCommand::handleResponse");
+ ALOGV("In GetScanResultsCommand::handleResponse");
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
@@ -909,7 +901,7 @@
int id = reply.get_vendor_id();
int subcmd = reply.get_vendor_subcmd();
- // ALOGD("Id = %0x, subcmd = %d", id, subcmd);
+ ALOGV("Id = %0x, subcmd = %d", id, subcmd);
/*
if (subcmd != GSCAN_SUBCMD_SCAN_RESULTS) {
@@ -984,8 +976,7 @@
wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, byte flush,
int max, wifi_cached_scan_results *results, int *num) {
-
- // ALOGD("Getting cached scan results, iface handle = %p, num = %d", iface, *num);
+ 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();
@@ -1335,21 +1326,16 @@
BssidHotlistCommand *cmd = new BssidHotlistCommand(iface, id, params, handler);
wifi_register_cmd(handle, id, cmd);
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface)
{
- wifi_handle handle = getWifiHandle(iface);
-
- WifiCommand *cmd = wifi_unregister_cmd(handle, id);
- if (cmd) {
- cmd->cancel();
- cmd->releaseRef();
- return WIFI_SUCCESS;
- }
-
- return WIFI_ERROR_INVALID_ARGS;
+ return wifi_cancel_cmd(id, iface);
}
@@ -1505,7 +1491,7 @@
}
virtual int handleEvent(WifiEvent& event) {
- ALOGI("Got a significant wifi change event");
+ ALOGV("Got a significant wifi change event");
nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
int len = event.get_vendor_data_len();
@@ -1534,7 +1520,7 @@
mResults[i] = reinterpret_cast<wifi_significant_change_result *>(&(mResultsBuffer[i]));
}
- ALOGI("Retrieved %d scan results", num);
+ ALOGV("Retrieved %d scan results", num);
if (num != 0) {
(*mHandler.on_significant_change)(id(), num, mResults);
@@ -1554,34 +1540,21 @@
SignificantWifiChangeCommand *cmd = new SignificantWifiChangeCommand(
iface, id, params, handler);
wifi_register_cmd(handle, id, cmd);
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface)
{
- wifi_handle handle = getWifiHandle(iface);
-
- WifiCommand *cmd = wifi_unregister_cmd(handle, id);
- if (cmd) {
- cmd->cancel();
- cmd->releaseRef();
- return WIFI_SUCCESS;
- }
-
- return WIFI_ERROR_INVALID_ARGS;
+ return wifi_cancel_cmd(id, iface);
}
wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface)
{
- wifi_handle handle = getWifiHandle(iface);
-
- WifiCommand *cmd = wifi_unregister_cmd(handle, id);
- if (cmd) {
- cmd->cancel();
- cmd->releaseRef();
- return WIFI_SUCCESS;
- }
- return WIFI_ERROR_INVALID_ARGS;
+ return wifi_cancel_cmd(id, iface);
}
wifi_error wifi_set_epno_list(wifi_request_id id, wifi_interface_handle iface,
@@ -1594,7 +1567,11 @@
if (num_networks == 0 || networks == NULL) {
return wifi_reset_epno_list(id, iface);
}
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
class SSIDWhitelistCommand : public WifiCommand
@@ -1680,7 +1657,11 @@
SSIDWhitelistCommand *cmd = new SSIDWhitelistCommand(iface, id, num_networks, ssids);
wifi_register_cmd(handle, id, cmd);
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
@@ -1734,7 +1715,7 @@
}
int start() {
- ALOGI("Executing roam params set request");
+ ALOGV("Executing roam params set request");
WifiRequest request(familyId(), ifaceId());
int result = createRequest(request);
if (result < 0) {
@@ -1743,7 +1724,7 @@
result = requestResponse(request);
if (result < 0) {
- ALOGI("Failed to execute Roam params set request, result = %d", result);
+ ALOGE("Failed to execute Roam params set request, result = %d", result);
return result;
}
@@ -1769,7 +1750,11 @@
RoamParamsCommand *cmd = new RoamParamsCommand(iface, id, params);
wifi_register_cmd(handle, id, cmd);
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
class LazyRoamCommand : public WifiCommand
@@ -1830,7 +1815,11 @@
LazyRoamCommand *cmd = new LazyRoamCommand(iface, id, enable);
wifi_register_cmd(handle, id, cmd);
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
class BssidBlacklistCommand : public WifiCommand
@@ -1870,7 +1859,7 @@
}
int start() {
- ALOGI("Executing bssid blacklist request, num = %d", mParams->num_bssid);
+ ALOGV("Executing bssid blacklist request, num = %d", mParams->num_bssid);
WifiRequest request(familyId(), ifaceId());
int result = createRequest(request);
if (result < 0) {
@@ -1879,7 +1868,7 @@
result = requestResponse(request);
if (result < 0) {
- ALOGI("Failed to execute bssid blacklist request, result = %d", result);
+ ALOGE("Failed to execute bssid blacklist request, result = %d", result);
return result;
}
@@ -1904,7 +1893,11 @@
BssidBlacklistCommand *cmd = new BssidBlacklistCommand(iface, id, ¶ms);
wifi_register_cmd(handle, id, cmd);
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
class BssidPreferenceCommand : public WifiCommand
@@ -1963,7 +1956,7 @@
}
int start() {
- ALOGI("Executing bssid prefernce change request, num = %d", mNumBssid);
+ ALOGV("Executing bssid prefernce change request, num = %d", mNumBssid);
WifiRequest request(familyId(), ifaceId());
int result = createRequest(request);
if (result < 0) {
@@ -1972,7 +1965,7 @@
result = requestResponse(request);
if (result < 0) {
- ALOGI("Failed to execute bssid preference change request, result = %d", result);
+ ALOGE("Failed to execute bssid preference change request, result = %d", result);
return result;
}
@@ -1998,7 +1991,11 @@
BssidPreferenceCommand *cmd = new BssidPreferenceCommand(iface, id, num_bssid, prefs);
wifi_register_cmd(handle, id, cmd);
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
////////////////////////////////////////////////////////////////////////////////
@@ -2153,19 +2150,15 @@
AnqpoConfigureCommand *cmd = new AnqpoConfigureCommand(id, iface, num, networks, handler);
wifi_register_cmd(handle, id, cmd);
- return (wifi_error)cmd->start();
+ wifi_error result = (wifi_error)cmd->start();
+ if (result != WIFI_SUCCESS) {
+ wifi_unregister_cmd(handle, id);
+ }
+ return result;
}
wifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle iface)
{
- wifi_handle handle = getWifiHandle(iface);
-
- WifiCommand *cmd = wifi_unregister_cmd(handle, id);
- if (cmd) {
- cmd->cancel();
- cmd->releaseRef();
- return WIFI_SUCCESS;
- }
-
- return WIFI_ERROR_INVALID_ARGS;
+ 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 3226da8..25502af 100644
--- a/bcmdhd/wifi_hal/link_layer_stats.cpp
+++ b/bcmdhd/wifi_hal/link_layer_stats.cpp
@@ -68,9 +68,19 @@
void *data = reply.get_vendor_data();
int len = reply.get_vendor_data_len();
- int num_chan = ((wifi_radio_stat *)data)->num_channels;
- if (num_chan > 32) {
+ 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;
}
(*mHandler.on_link_stats_results)(id,
diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp
index 6f14a66..1d02b7b 100644
--- a/bcmdhd/wifi_hal/wifi_hal.cpp
+++ b/bcmdhd/wifi_hal/wifi_hal.cpp
@@ -53,6 +53,9 @@
static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group);
static int wifi_add_membership(wifi_handle handle, const char *group);
static wifi_error wifi_init_interfaces(wifi_handle handle);
+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);
typedef enum wifi_attr {
ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
@@ -60,6 +63,12 @@
ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI
} wifi_attr_t;
+enum wifi_rssi_monitor_attr {
+ RSSI_MONITOR_ATTRIBUTE_MAX_RSSI,
+ RSSI_MONITOR_ATTRIBUTE_MIN_RSSI,
+ RSSI_MONITOR_ATTRIBUTE_START,
+};
+
/* Initialize/Cleanup */
void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
@@ -134,6 +143,7 @@
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;
+ fn->wifi_reset_log_handler = wifi_reset_log_handler;
fn->wifi_set_alert_handler = wifi_set_alert_handler;
fn->wifi_get_firmware_version = wifi_get_firmware_version;
fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status;
@@ -145,6 +155,10 @@
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_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet;
+ fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet;
return WIFI_SUCCESS;
}
@@ -624,6 +638,121 @@
}
};
+class SetRSSIMonitorCommand : public WifiCommand {
+private:
+ s8 mMax_rssi;
+ s8 mMin_rssi;
+ wifi_rssi_event_handler mHandler;
+public:
+ SetRSSIMonitorCommand(wifi_request_id id, wifi_interface_handle handle,
+ s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
+ : WifiCommand(handle, id), mMax_rssi(max_rssi), mMin_rssi(min_rssi), mHandler(eh)
+ {
+ }
+ int createRequest(WifiRequest& request, int enable) {
+ int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR);
+ if (result < 0) {
+ return result;
+ }
+
+ nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+ result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0));
+ if (result < 0) {
+ return result;
+ }
+ ALOGD("create request");
+ result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0));
+ if (result < 0) {
+ return result;
+ }
+ result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_START, enable);
+ if (result < 0) {
+ return result;
+ }
+ request.attr_end(data);
+ return result;
+ }
+
+ int start() {
+ WifiRequest request(familyId(), ifaceId());
+ int result = createRequest(request, 1);
+ if (result < 0) {
+ return result;
+ }
+ result = requestResponse(request);
+ if (result < 0) {
+ ALOGI("Failed to set RSSI Monitor, result = %d", result);
+ return result;
+ }
+ ALOGI("Successfully set RSSI monitoring");
+ registerVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
+
+
+ if (result < 0) {
+ unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
+ return result;
+ }
+ ALOGI("Done!");
+ return result;
+ }
+
+ virtual int cancel() {
+
+ WifiRequest request(familyId(), ifaceId());
+ int result = createRequest(request, 0);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("failed to create request; result = %d", result);
+ } else {
+ result = requestResponse(request);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("failed to stop RSSI monitoring = %d", result);
+ }
+ }
+ unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
+ return WIFI_SUCCESS;
+ }
+
+ virtual int handleResponse(WifiEvent& reply) {
+ /* Nothing to do on response! */
+ return NL_SKIP;
+ }
+
+ virtual int handleEvent(WifiEvent& event) {
+ ALOGI("Got a RSSI monitor event");
+
+ nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+ int len = event.get_vendor_data_len();
+
+ if (vendor_data == NULL || len == 0) {
+ ALOGI("RSSI monitor: No data");
+ return NL_SKIP;
+ }
+ /* driver<->HAL event structure */
+ #define RSSI_MONITOR_EVT_VERSION 1
+ typedef struct {
+ u8 version;
+ s8 cur_rssi;
+ mac_addr BSSID;
+ } rssi_monitor_evt;
+
+ rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data();
+
+ if (data->version != RSSI_MONITOR_EVT_VERSION) {
+ ALOGI("Event version mismatch %d, expected %d", data->version, RSSI_MONITOR_EVT_VERSION);
+ return NL_SKIP;
+ }
+
+ if (*mHandler.on_rssi_threshold_breached) {
+ (*mHandler.on_rssi_threshold_breached)(id(), data->BSSID, data->cur_rssi);
+ } else {
+ ALOGW("No RSSI monitor handler registered");
+ }
+
+ return NL_SKIP;
+ }
+
+};
+
class GetFeatureSetCommand : public WifiCommand {
private:
@@ -851,4 +980,33 @@
return (wifi_error) command.requestResponse();
}
+static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
+ iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
+{
+ ALOGD("Start RSSI monitor %d", id);
+ wifi_handle handle = getWifiHandle(iface);
+ SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, max_rssi, min_rssi, eh);
+ wifi_register_cmd(handle, id, cmd);
+ return (wifi_error)cmd->start();
+}
+
+
+static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface)
+{
+ ALOGD("Stopping RSSI monitor");
+
+ if(id == -1) {
+ wifi_rssi_event_handler handler;
+ s8 max_rssi = 0, min_rssi = 0;
+ wifi_handle handle = getWifiHandle(iface);
+ memset(&handler, 0, sizeof(handler));
+ SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface,
+ max_rssi, min_rssi, handler);
+ cmd->cancel();
+ cmd->releaseRef();
+ return WIFI_SUCCESS;
+ }
+ return wifi_cancel_cmd(id, iface);
+}
+
/////////////////////////////////////////////////////////////////////////////
diff --git a/bcmdhd/wifi_hal/wifi_logger.cpp b/bcmdhd/wifi_hal/wifi_logger.cpp
index e93ae97..1ef307c 100644
--- a/bcmdhd/wifi_hal/wifi_logger.cpp
+++ b/bcmdhd/wifi_hal/wifi_logger.cpp
@@ -36,6 +36,7 @@
LOGGER_GET_RING_STATUS,
LOGGER_GET_RING_DATA,
LOGGER_GET_FEATURE,
+ LOGGER_RESET_LOGGING,
} DEBUG_SUB_COMMAND;
typedef enum {
@@ -260,7 +261,7 @@
}
int start() {
- ALOGD("Start debug command");
+ // ALOGD("Start debug command");
WifiRequest request(familyId(), ifaceId());
int result = createRequest(request);
if (result != WIFI_SUCCESS) {
@@ -445,6 +446,9 @@
SetLogHandler(wifi_interface_handle iface, int id, wifi_ring_buffer_data_handler handler)
: WifiCommand(iface, id), mHandler(handler)
{ }
+ SetLogHandler(wifi_interface_handle iface, int id)
+ : WifiCommand(iface, id)
+ { }
int start() {
ALOGD("Register log handler");
@@ -453,10 +457,26 @@
}
virtual int cancel() {
- /* TODO: send a command to driver to stop generating logging events */
+ /* Send a command to driver to stop generating logging events */
+ ALOGD("Reset event handler");
+
+ WifiRequest request(familyId(), ifaceId());
+ int result = request.create(GOOGLE_OUI, LOGGER_RESET_LOGGING);
+
+ if (result != WIFI_SUCCESS) {
+ ALOGE("failed to create reset request; result = %d", result);
+ return result;
+ }
+
+ result = requestResponse(request);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("failed to request reset; result = %d", result);
+ return result;
+ }
/* unregister event handler */
unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
+ ALOGD("Success to reset event handler");
return WIFI_SUCCESS;
}
@@ -464,11 +484,11 @@
char *buffer = NULL;
int buffer_size = 0;
- ALOGD("In SetLogHandler::handleEvent");
+ // ALOGD("In SetLogHandler::handleEvent");
nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
int len = event.get_vendor_data_len();
int event_id = event.get_vendor_subcmd();
- ALOGI("Got Logger event: %d", event_id);
+ // ALOGI("Got Logger event: %d", event_id);
if (vendor_data == NULL || len == 0) {
ALOGE("No Debug data found");
@@ -491,7 +511,7 @@
}
}
- ALOGI("Retrieved Debug data");
+ // ALOGI("Retrieved Debug data");
if (mHandler.on_ring_buffer_data) {
(*mHandler.on_ring_buffer_data)((char *)status.name, buffer, buffer_size,
&status);
@@ -520,6 +540,20 @@
}
}
+wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface)
+{
+ wifi_handle handle = getWifiHandle(iface);
+ SetLogHandler *cmd = new SetLogHandler(iface, id);
+
+ ALOGI("Logger reset, handle = %p", handle);
+ if (cmd) {
+ cmd->cancel();
+ cmd->releaseRef();
+ return WIFI_SUCCESS;
+ }
+ return WIFI_ERROR_INVALID_ARGS;
+}
+
///////////////////////////////////////////////////////////////////////////////
class SetAlertHandler : public WifiCommand
{
diff --git a/bcmdhd/wifi_hal/wifi_offload.cpp b/bcmdhd/wifi_hal/wifi_offload.cpp
new file mode 100644
index 0000000..936ca40
--- /dev/null
+++ b/bcmdhd/wifi_hal/wifi_offload.cpp
@@ -0,0 +1,229 @@
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink-types.h>
+
+#include "nl80211_copy.h"
+#include "sync.h"
+
+#define LOG_TAG "WifiHAL"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+using namespace android;
+
+typedef enum {
+ WIFI_OFFLOAD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
+ WIFI_OFFLOAD_STOP_MKEEP_ALIVE,
+} WIFI_OFFLOAD_SUB_COMMAND;
+
+typedef enum {
+ MKEEP_ALIVE_ATTRIBUTE_ID,
+ MKEEP_ALIVE_ATTRIBUTE_IP_PKT,
+ MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN,
+ MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR,
+ MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR,
+ MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
+} WIFI_MKEEP_ALIVE_ATTRIBUTE;
+
+typedef enum {
+ START_MKEEP_ALIVE,
+ STOP_MKEEP_ALIVE,
+} GetCmdType;
+
+///////////////////////////////////////////////////////////////////////////////
+class MKeepAliveCommand : public WifiCommand
+{
+ u8 mIndex;
+ u8 *mIpPkt;
+ u16 mIpPktLen;
+ u8 *mSrcMacAddr;
+ u8 *mDstMacAddr;
+ u32 mPeriodMsec;
+ GetCmdType mType;
+
+public:
+
+ // constructor for start sending
+ MKeepAliveCommand(wifi_interface_handle iface, u8 index, u8 *ip_packet, u16 ip_packet_len,
+ u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec, GetCmdType cmdType)
+ : WifiCommand(iface, 0), mIndex(index), mIpPkt(ip_packet), mIpPktLen(ip_packet_len),
+ mSrcMacAddr(src_mac_addr), mDstMacAddr(dst_mac_addr), mPeriodMsec(period_msec),
+ mType(cmdType)
+ { }
+
+ // constructor for stop sending
+ MKeepAliveCommand(wifi_interface_handle iface, u8 index, GetCmdType cmdType)
+ : WifiCommand(iface, 0), mIndex(index), mType(cmdType)
+ { }
+
+ int createRequest(WifiRequest &request) {
+ int result;
+
+ switch (mType) {
+ case START_MKEEP_ALIVE:
+ {
+ result = request.create(GOOGLE_OUI, WIFI_OFFLOAD_START_MKEEP_ALIVE);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("Failed to create start keep alive request; result = %d", result);
+ return result;
+ }
+
+ nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+ result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
+ if (result < 0) {
+ ALOGE("Failed to put id request; result = %d", result);
+ return result;
+ }
+
+ result = request.put_u16(MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, mIpPktLen);
+ if (result < 0) {
+ ALOGE("Failed to put ip pkt len request; result = %d", result);
+ return result;
+ }
+
+ result = request.put(MKEEP_ALIVE_ATTRIBUTE_IP_PKT, (u8*)mIpPkt, mIpPktLen);
+ if (result < 0) {
+ ALOGE("Failed to put ip pkt request; result = %d", result);
+ return result;
+ }
+
+ result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, mSrcMacAddr);
+ if (result < 0) {
+ ALOGE("Failed to put src mac address request; result = %d", result);
+ return result;
+ }
+
+ result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, mDstMacAddr);
+ if (result < 0) {
+ ALOGE("Failed to put dst mac address request; result = %d", result);
+ return result;
+ }
+
+ result = request.put_u32(MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, mPeriodMsec);
+ if (result < 0) {
+ ALOGE("Failed to put period request; result = %d", result);
+ return result;
+ }
+
+ request.attr_end(data);
+ break;
+ }
+
+ case STOP_MKEEP_ALIVE:
+ {
+ result = request.create(GOOGLE_OUI, WIFI_OFFLOAD_STOP_MKEEP_ALIVE);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("Failed to create stop keep alive request; result = %d", result);
+ return result;
+ }
+
+ nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+ result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
+ if (result < 0) {
+ ALOGE("Failed to put id request; result = %d", result);
+ return result;
+ }
+
+ request.attr_end(data);
+ break;
+ }
+
+ default:
+ ALOGE("Unknown wifi keep alive command");
+ result = WIFI_ERROR_UNKNOWN;
+ }
+ return result;
+ }
+
+ int start() {
+ ALOGD("Start mkeep_alive command");
+ WifiRequest request(familyId(), ifaceId());
+ int result = createRequest(request);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("Failed to create keep alive request; result = %d", result);
+ return result;
+ }
+
+ result = requestResponse(request);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("Failed to register keep alive response; result = %d", result);
+ }
+ return result;
+ }
+
+ virtual int handleResponse(WifiEvent& reply) {
+ ALOGD("In MKeepAliveCommand::handleResponse");
+
+ if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+ ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+ return NL_SKIP;
+ }
+
+ switch (mType) {
+ case START_MKEEP_ALIVE:
+ case STOP_MKEEP_ALIVE:
+ break;
+
+ default:
+ ALOGW("Unknown mkeep_alive command");
+ }
+ return NL_OK;
+ }
+
+ virtual int handleEvent(WifiEvent& event) {
+ /* NO events! */
+ return NL_SKIP;
+ }
+};
+
+
+/* API to send specified mkeep_alive packet periodically. */
+wifi_error wifi_start_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface,
+ u8 *ip_packet, u16 ip_packet_len, u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec)
+{
+ if ((index > 0 && index <= N_AVAIL_ID) && (ip_packet != NULL) && (src_mac_addr != NULL)
+ && (dst_mac_addr != NULL) && (period_msec > 0)
+ && (ip_packet_len <= MKEEP_ALIVE_IP_PKT_MAX)) {
+ MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, ip_packet, ip_packet_len,
+ src_mac_addr, dst_mac_addr, period_msec, START_MKEEP_ALIVE);
+ wifi_error result = (wifi_error)cmd->start();
+ delete cmd;
+ return result;
+ } else {
+ ALOGE("Invalid mkeep_alive parameters");
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+}
+
+/* API to stop sending mkeep_alive packet. */
+wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface)
+{
+ if (index > 0 && index <= N_AVAIL_ID) {
+ MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, STOP_MKEEP_ALIVE);
+ wifi_error result = (wifi_error)cmd->start();
+ delete cmd;
+ return result;
+ } else {
+ ALOGE("Invalid mkeep_alive parameters");
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+}