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/wifi_hal/wifi_hal.cpp | |
parent | 6a4c420bc727655771343331e02850f683f00bbb (diff) | |
download | hardware_broadcom_wlan-fef13c11034313585be68c32322b9a53c43a37b2.tar.gz hardware_broadcom_wlan-fef13c11034313585be68c32322b9a53c43a37b2.tar.bz2 hardware_broadcom_wlan-fef13c11034313585be68c32322b9a53c43a37b2.zip |
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/wifi_hal.cpp')
-rw-r--r-- | bcmdhd/wifi_hal/wifi_hal.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
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); +} + ///////////////////////////////////////////////////////////////////////////// |