summaryrefslogtreecommitdiffstats
path: root/bcmdhd/wifi_hal
diff options
context:
space:
mode:
authorAshwin <ashwin.bhat@broadcom.com>2015-06-12 13:08:45 -0700
committerVinit Deshpande <vinitd@google.com>2015-06-24 10:55:57 -0700
commitfef13c11034313585be68c32322b9a53c43a37b2 (patch)
tree6f54b84d47b7cf8ab895decec6805393a9ce9d7e /bcmdhd/wifi_hal
parent6a4c420bc727655771343331e02850f683f00bbb (diff)
downloadhardware_broadcom_wlan-fef13c11034313585be68c32322b9a53c43a37b2.zip
hardware_broadcom_wlan-fef13c11034313585be68c32322b9a53c43a37b2.tar.gz
hardware_broadcom_wlan-fef13c11034313585be68c32322b9a53c43a37b2.tar.bz2
RSSI monitor changes
RSSI monitor is used to set RSSI thresholds to driver and rx events when thresholds are crossed. also includes some code cleanup Change-Id: Ia55ded489ed5d4232e6fea0ffdcfc824522613b1 Signed-off-by: Ashwin <ashwin.bhat@broadcom.com>
Diffstat (limited to 'bcmdhd/wifi_hal')
-rw-r--r--bcmdhd/wifi_hal/common.cpp29
-rw-r--r--bcmdhd/wifi_hal/common.h6
-rw-r--r--bcmdhd/wifi_hal/gscan.cpp63
-rw-r--r--bcmdhd/wifi_hal/wifi_hal.cpp155
4 files changed, 194 insertions, 59 deletions
diff --git a/bcmdhd/wifi_hal/common.cpp b/bcmdhd/wifi_hal/common.cpp
index 61f4475..fcc93eb 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,18 @@ void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd)
}
}
}
+
+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);
+ 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..5df02fe 100644
--- a/bcmdhd/wifi_hal/common.h
+++ b/bcmdhd/wifi_hal/common.h
@@ -95,6 +95,7 @@ typedef enum {
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 +115,8 @@ typedef enum {
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 +201,7 @@ hal_info *getHalInfo(wifi_handle handle);
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..0e8949b 100644
--- a/bcmdhd/wifi_hal/gscan.cpp
+++ b/bcmdhd/wifi_hal/gscan.cpp
@@ -767,15 +767,7 @@ wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface)
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);
}
@@ -812,14 +804,7 @@ wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_han
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);
}
@@ -1340,16 +1325,7 @@ wifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle ifac
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);
}
@@ -1559,29 +1535,12 @@ wifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interfac
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,
@@ -2158,14 +2117,6 @@ wifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_interface_handle ifa
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/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp
index 6f14a66..22912f9 100644
--- a/bcmdhd/wifi_hal/wifi_hal.cpp
+++ b/bcmdhd/wifi_hal/wifi_hal.cpp
@@ -53,6 +53,9 @@ static int internal_valid_message_handler(nl_msg *msg, void *arg);
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 @@ typedef enum wifi_attr {
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)
@@ -145,6 +154,8 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
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;
return WIFI_SUCCESS;
}
@@ -624,6 +635,121 @@ public:
}
};
+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 +977,33 @@ wifi_error wifi_set_country_code(wifi_interface_handle handle, const char *count
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);
+}
+
/////////////////////////////////////////////////////////////////////////////