From 349e638904fe7433a051312cfa0b76fe44d39f34 Mon Sep 17 00:00:00 2001 From: Ajay Davanageri Date: Fri, 23 Dec 2022 11:10:20 +0530 Subject: Add vendor hal support for get cached scan results Bug:232030878 Test: Verified using the halutil Change-Id: I0996329159da1a864df035b56ea4b004ebdf9860 Signed-off-by: Ajay Davanageri --- bcmdhd/wifi_hal/Android.bp | 1 + bcmdhd/wifi_hal/common.h | 5 ++ bcmdhd/wifi_hal/scan.cpp | 166 +++++++++++++++++++++++++++++++++++++++++++ bcmdhd/wifi_hal/wifi_hal.cpp | 4 +- 4 files changed, 175 insertions(+), 1 deletion(-) mode change 100755 => 100644 bcmdhd/wifi_hal/common.h create mode 100644 bcmdhd/wifi_hal/scan.cpp mode change 100755 => 100644 bcmdhd/wifi_hal/wifi_hal.cpp diff --git a/bcmdhd/wifi_hal/Android.bp b/bcmdhd/wifi_hal/Android.bp index 92498f3..4994828 100644 --- a/bcmdhd/wifi_hal/Android.bp +++ b/bcmdhd/wifi_hal/Android.bp @@ -84,6 +84,7 @@ cc_library_static { "wifi_logger.cpp", "wifi_offload.cpp", "twt.cpp", + "scan.cpp", ], proprietary: true, diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h old mode 100755 new mode 100644 index 4c7973b..bf992b8 --- a/bcmdhd/wifi_hal/common.h +++ b/bcmdhd/wifi_hal/common.h @@ -33,6 +33,7 @@ #define DEFAULT_CMD_SIZE (64) #define DOT11_OUI_LEN 3 #define DOT11_MAX_SSID_LEN 32 +#define MAX_CACHED_SCAN_RESULT 32 #define ETHERTYPE_IP 0x0800 /* IP */ #define ETHERTYPE_IPV6 0x86dd /* IP protocol version 6 */ @@ -142,6 +143,9 @@ typedef enum { ANDROID_NL80211_SUBCMD_INIT_DEINIT_RANGE_START = 0x2160, ANDROID_NL80211_SUBCMD_INIT_DEINIT_RANGE_END = 0x216F, + /* define scan related commands between 0x2170 and 0x2175 */ + ANDROID_NL80211_SUBCMD_SCAN_START = 0x2170, + ANDROID_NL80211_SUBCMD_SCAN_END = 0x2175, /* This is reserved for future usage */ } ANDROID_VENDOR_SUB_COMMAND; @@ -234,6 +238,7 @@ typedef enum { WIFI_SUBCMD_TRIGGER_SSR = ANDROID_NL80211_SUBCMD_INIT_DEINIT_RANGE_START, WIFI_SUBCMD_GET_RADIO_COMBO_MATRIX, WIFI_SUBCMD_ENABLE_TX_POWER_LIMIT, + WIFI_SUBCMD_GET_CACHED_SCAN_RESULTS = ANDROID_NL80211_SUBCMD_SCAN_START, } WIFI_SUB_COMMAND; typedef enum { diff --git a/bcmdhd/wifi_hal/scan.cpp b/bcmdhd/wifi_hal/scan.cpp new file mode 100644 index 0000000..d8ab4e0 --- /dev/null +++ b/bcmdhd/wifi_hal/scan.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Portions copyright (C) 2022 Broadcom Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "sync.h" + +#define LOG_TAG "WifiHAL" + +#include +#include +#include "common.h" +#include "cpp_bindings.h" + +#define CACHE_SCAN_RESULT_SIZE sizeof(wifi_cached_scan_result) +#define MAX_CACHE_SCAN_RESULT_SIZE (MAX_CACHED_SCAN_RESULT*CACHE_SCAN_RESULT_SIZE) +typedef enum { + WIFI_ATTRIBUTE_CACHED_SCAN_INVALID = 0, + WIFI_ATTRIBUTE_CACHED_SCAN_BOOT_TIMESTAMP = 1, + WIFI_ATTRIBUTE_CACHED_SCANNED_FREQ_NUM = 2, + WIFI_ATTRIBUTE_CACHED_SCANNED_FREQ_LIST = 3, + WIFI_ATTRIBUTE_CACHED_SCAN_RESULT_CNT = 4, + WIFI_ATTRIBUTE_CACHED_SCAN_RESULTS = 5, + WIFI_ATTRIBUTE_CACHED_SCAN_MAX +} SCAN_ATTRIBUTE; +///////////////////////////////////////////////////////////////////////////// + +class GetCachedScanResultsCommand : public WifiCommand { + wifi_cached_scan_result_handler mHandler; + wifi_cached_scan_report *mReport; + +public: + GetCachedScanResultsCommand(wifi_interface_handle iface, int id, + wifi_cached_scan_result_handler handler) + : WifiCommand("GetCachedScanResultsCommand", iface, id), mHandler(handler) + { + mReport = NULL; + } + + virtual int create() { + ALOGE("Creating message to get cached scan results"); + + int ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_CACHED_SCAN_RESULTS); + if (ret < 0) { + return ret; + } + + return ret; + } + + protected: + virtual int handleResponse(WifiEvent& reply) { + ALOGI("In GetCachedScanResultsCommand::handleResponse"); + + if (reply.get_cmd() != NL80211_CMD_VENDOR) { + ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); + return NL_SKIP; + } + + int id = reply.get_vendor_id(); + int subcmd = reply.get_vendor_subcmd(); + int valid_entries = 0; + int result_size = 0; + wifi_timestamp timestamp = 0; + int size = 0; + + ALOGV("Id = %0x, subcmd = %d", id, subcmd); + + nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); + int len = reply.get_vendor_data_len(); + + if (vendor_data == NULL || len == 0) { + ALOGE("no vendor data in GetCachedScanResults response; ignoring it"); + return NL_SKIP; + } + + mReport = (wifi_cached_scan_report *)malloc(sizeof(wifi_cached_scan_report)); + if (mReport == NULL) { + ALOGE("Failed to allocate!!\n"); + return NL_SKIP; + } + memset(mReport, 0, sizeof(wifi_cached_scan_report)); + + ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); + for (nl_iterator it(vendor_data); it.has_next(); it.next()) { + if (it.get_type() == WIFI_ATTRIBUTE_CACHED_SCAN_BOOT_TIMESTAMP) { + timestamp = it.get_u32(); + ALOGV("Time since boot_ms: %ld\n", timestamp); + } else if (it.get_type() == WIFI_ATTRIBUTE_CACHED_SCAN_RESULT_CNT) { + valid_entries = min(it.get_u16(), MAX_CACHED_SCAN_RESULT); + ALOGV("cached scan result cnt: %d", valid_entries); + } else if ((it.get_type() == WIFI_ATTRIBUTE_CACHED_SCAN_RESULTS) && + valid_entries && timestamp) { + size = min(it.get_len(), MAX_CACHE_SCAN_RESULT_SIZE); + if (size > (valid_entries*CACHE_SCAN_RESULT_SIZE)) { + ALOGE("Not enough space to copy!!\n"); + return NL_SKIP; + } + result_size = valid_entries * CACHE_SCAN_RESULT_SIZE; + mReport->results = (wifi_cached_scan_result *)malloc(result_size); + if (mReport->results == NULL) { + ALOGE("Failed to allocate!!\n"); + return NL_SKIP; + } + memcpy((void *)mReport->results, (void *)it.get_data(), size); + } else { + ALOGW("Ignoring invalid attribute type = %d, size = %d", + it.get_type(), it.get_len()); + } + } + + mReport->ts = timestamp; + mReport->result_cnt = valid_entries; + + if (*mHandler.on_cached_scan_results && mReport) { + (*mHandler.on_cached_scan_results)(mReport); + ALOGV("Notified cache scan report!!"); + } + + if (mReport) { + if (mReport->results) { + free((void *)mReport->results); + } + free(mReport); + } + return NL_OK; + } +}; + +wifi_error wifi_get_cached_scan_results(wifi_interface_handle iface, + wifi_cached_scan_result_handler handler) +{ + ALOGI("Getting cached scan results, iface handle = %p", iface); + GetCachedScanResultsCommand command(iface, 0, handler); + return (wifi_error) command.requestResponse(); +} diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp old mode 100755 new mode 100644 index e6a14e7..2f2caa9 --- a/bcmdhd/wifi_hal/wifi_hal.cpp +++ b/bcmdhd/wifi_hal/wifi_hal.cpp @@ -100,6 +100,8 @@ static wifi_error wifi_get_supported_radio_combinations_matrix(wifi_handle handl static void wifi_cleanup_dynamic_ifaces(wifi_handle handle); static wifi_error wifi_enable_tx_power_limits(wifi_interface_handle iface, bool isEnable); +wifi_error wifi_get_cached_scan_results(wifi_interface_handle iface, + wifi_cached_scan_result_handler handler); typedef enum wifi_attr { ANDR_WIFI_ATTRIBUTE_INVALID = 0, @@ -355,7 +357,7 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) fn->wifi_nan_rtt_chre_disable_request = nan_chre_disable_request; fn->wifi_chre_register_handler = nan_chre_register_handler; fn->wifi_enable_tx_power_limits = wifi_enable_tx_power_limits; - + fn->wifi_get_cached_scan_results = wifi_get_cached_scan_results; return WIFI_SUCCESS; } #ifdef GOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER -- cgit v1.2.3