diff options
author | Ashwin <ashwin.bhat@broadcom.com> | 2015-06-12 13:08:45 -0700 |
---|---|---|
committer | Vinit Deshpande <vinitd@google.com> | 2015-06-24 10:55:57 -0700 |
commit | fef13c11034313585be68c32322b9a53c43a37b2 (patch) | |
tree | 6f54b84d47b7cf8ab895decec6805393a9ce9d7e /bcmdhd | |
parent | 6a4c420bc727655771343331e02850f683f00bbb (diff) | |
download | hardware_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')
-rw-r--r-- | bcmdhd/wifi_hal/common.cpp | 29 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/common.h | 6 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/gscan.cpp | 63 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/wifi_hal.cpp | 155 |
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); +} + ///////////////////////////////////////////////////////////////////////////// |