From f425b4a80e0668c779bb27749d8cb11e6e787a8f Mon Sep 17 00:00:00 2001 From: Pragya Gupta Date: Thu, 4 Aug 2016 11:06:48 +0530 Subject: [PATCH] [7570] wlbt : Host changes for Android Feature RSSI monitor HAL changes for Android Feature RSSI monitor Change-Id: I4f1bb40731686fff75b4b73133c6397c60e27c62 SCSC-Bug-Id : SSB-19744 Signed-off-by: Pragya Gupta --- common.cpp | 31 +++++++++- common.h | 8 ++- wifi_hal.cpp | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 192 insertions(+), 4 deletions(-) diff --git a/common.cpp b/common.cpp index 1a72425..6a4ea1a 100755 --- a/common.cpp +++ b/common.cpp @@ -1,10 +1,24 @@ -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include +#include +#include #include #include "wifi_hal.h" #include "common.h" +#include "cpp_bindings.h" interface_info *getIfaceInfo(wifi_interface_handle handle) { @@ -210,3 +224,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); + ALOGD("Cancel WifiCommand = %p", cmd); + if (cmd) { + cmd->cancel(); + cmd->releaseRef(); + return WIFI_SUCCESS; + } + + return WIFI_ERROR_INVALID_ARGS; +} diff --git a/common.h b/common.h index 24176a2..6e3fc07 100755 --- a/common.h +++ b/common.h @@ -82,7 +82,8 @@ typedef enum { SLSI_NL80211_VENDOR_SUBCMD_SET_BSSID_BLACKLIST, SLSI_NL80211_VENDOR_SUBCMD_SET_EPNO_LIST, SLSI_NL80211_VENDOR_SUBCMD_SET_HS_LIST, - SLSI_NL80211_VENDOR_SUBCMD_RESET_HS_LIST + SLSI_NL80211_VENDOR_SUBCMD_RESET_HS_LIST, + SLSI_NL80211_VENDOR_SUBCMD_SET_RSSI_MONITOR } WIFI_SUB_COMMAND; typedef enum { @@ -95,7 +96,9 @@ typedef enum { WIFI_SUBCMD_KEY_MGMT_ROAM_AUTH, /* Handled by supplicant. not in Wifi-HAL */ WIFI_HANGED_EVENT, WIFI_EPNO_EVENT, - WIFI_HOTSPOT_MATCH + WIFI_HOTSPOT_MATCH, + WIFI_RSSI_REPORT_EVENT + } WIFI_EVENT; typedef void (*wifi_internal_event_handler) (wifi_handle handle, int events); @@ -161,6 +164,7 @@ wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd); WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id); WifiCommand *wifi_get_cmd(wifi_handle handle, int id); void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd); +wifi_error wifi_cancel_cmd(wifi_request_id id, wifi_interface_handle iface); interface_info *getIfaceInfo(wifi_interface_handle); wifi_handle getWifiHandle(wifi_interface_handle handle); diff --git a/wifi_hal.cpp b/wifi_hal.cpp index 18dfe3a..5764a27 100755 --- a/wifi_hal.cpp +++ b/wifi_hal.cpp @@ -26,7 +26,6 @@ #define LOG_TAG "WifiHAL" #include - #include "wifi_hal.h" #include "common.h" #include "cpp_bindings.h" @@ -52,6 +51,16 @@ 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, +}; + +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); + /* Initialize/Cleanup */ void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port) @@ -117,6 +126,8 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) fn->wifi_reset_passpoint_list = wifi_reset_passpoint_list; #endif fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist; + fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring; + fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring; return WIFI_SUCCESS; } @@ -605,6 +616,117 @@ 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, SLSI_NL80211_VENDOR_SUBCMD_SET_RSSI_MONITOR); + if (result < 0) { + return result; + } + + nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); + result = request.put_u8(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0)); + if (result < 0) { + return result; + } + ALOGD("create request"); + result = request.put_u8(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0)); + if (result < 0) { + return result; + } + result = request.put_u8(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, WIFI_RSSI_REPORT_EVENT); + + + if (result < 0) { + unregisterVendorHandler(GOOGLE_OUI, WIFI_RSSI_REPORT_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, WIFI_RSSI_REPORT_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; + } + + typedef struct { + s8 cur_rssi; + mac_addr BSSID; + } rssi_monitor_evt; + + rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data(); + + 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; + } + +}; + + + static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group) { GetMulticastIdCommand cmd(handle, name, group); @@ -726,4 +848,37 @@ wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs) 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); + + wifi_error result = (wifi_error)cmd->start(); + if (result != WIFI_SUCCESS) { + wifi_unregister_cmd(handle, id); + } + return result; +} + + +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; + wifi_handle handle = getWifiHandle(iface); + memset(&handler, 0, sizeof(handler)); + SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, + 0, 0, handler); + cmd->cancel(); + cmd->releaseRef(); + return WIFI_SUCCESS; + } + return wifi_cancel_cmd(id, iface); +} + ///////////////////////////////////////////////////////////////////////////// -- 2.20.1