diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-10-16 21:27:29 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2023-10-16 21:27:29 +0000 |
commit | eae62b98409be855ff25142bafea5468fcd0d35c (patch) | |
tree | e85a39a8d72b962035b725bf8e947c6119c82cac | |
parent | 9ad696cade24229e8c541f20e6ae853e75b0067c (diff) | |
parent | cf585f68ac0121f807c642b3757f37873fd4f88b (diff) | |
download | wlan-eae62b98409be855ff25142bafea5468fcd0d35c.tar.gz |
Merge "Snap for 10957012 from 2ae324a109af6109c9e832604b1b1d3a099fd02a to simpleperf-release" into simpleperf-release
-rw-r--r-- | OWNERS | 1 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/Android.bp | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | bcmdhd/wifi_hal/common.h | 6 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/link_layer_stats.cpp | 20 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/nan.cpp | 30 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/rtt.cpp | 173 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/scan.cpp | 166 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/twt.cpp | 4 | ||||
-rw-r--r--[-rwxr-xr-x] | bcmdhd/wifi_hal/wifi_hal.cpp | 52 |
9 files changed, 395 insertions, 58 deletions
@@ -1,3 +1,4 @@ arabawy@google.com etancohen@google.com kumachang@google.com +wangroger@google.com 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 index 4c7973b..b54fbb1 100755..100644 --- 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; @@ -187,6 +191,7 @@ typedef enum { WIFI_SUBCMD_SET_MULTISTA_PRIMARY_CONNECTION, /* 0x101c */ WIFI_SUBCMD_SET_MULTISTA_USE_CASE, /* 0x101d */ WIFI_SUBCMD_SET_DTIM_CONFIG, /* 0x101e */ + WIFI_SUBCMD_CHANNEL_POLICY, /* 0x101f */ GSCAN_SUBCMD_MAX, @@ -234,6 +239,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/link_layer_stats.cpp b/bcmdhd/wifi_hal/link_layer_stats.cpp index 04b89b5..05ab438 100644 --- a/bcmdhd/wifi_hal/link_layer_stats.cpp +++ b/bcmdhd/wifi_hal/link_layer_stats.cpp @@ -131,6 +131,11 @@ protected: } if (num_radios) { + if (!data || !data_len) { + ALOGE("%s: null data\n", __func__); + return NL_SKIP; + } + rem_len = MAX_CMD_RESP_BUF_LEN; radioStatsBuf = (u8 *)malloc(MAX_CMD_RESP_BUF_LEN); if (!radioStatsBuf) { @@ -140,11 +145,6 @@ protected: memset(radioStatsBuf, 0, MAX_CMD_RESP_BUF_LEN); output = radioStatsBuf; - if (!data || !data_len) { - ALOGE("%s: null data\n", __func__); - return NL_SKIP; - } - data_ptr = (u8*)data; for (int i = 0; i < num_radios; i++) { rem_len -= per_radio_size; @@ -161,12 +161,18 @@ protected: convertToExternalRadioStatStructure((wifi_radio_stat*)data_ptr, &per_radio_size); if (!radio_stat_ptr || !per_radio_size) { + if (radio_stat_ptr) { + free(radio_stat_ptr); + radio_stat_ptr = NULL; + } ALOGE("No data for radio %d\n", i); continue; } memcpy(output, radio_stat_ptr, per_radio_size); output += per_radio_size; total_size += per_radio_size; + free(radio_stat_ptr); + radio_stat_ptr = NULL; } iface_stat = ((u8*)data + total_size); @@ -179,10 +185,6 @@ protected: num_radios, (wifi_radio_stat *)radioStatsBuf); } exit: - if (radio_stat_ptr) { - free(radio_stat_ptr); - radio_stat_ptr = NULL; - } if (radioStatsBuf) { free(radioStatsBuf); radioStatsBuf = NULL; diff --git a/bcmdhd/wifi_hal/nan.cpp b/bcmdhd/wifi_hal/nan.cpp index a2d2d47..4dd4dd9 100755 --- a/bcmdhd/wifi_hal/nan.cpp +++ b/bcmdhd/wifi_hal/nan.cpp @@ -1390,8 +1390,6 @@ class NanDiscEnginePrimitive : public WifiCommand } if (mParams->service_specific_info_len > 0) { - u16 len = min(mParams->service_specific_info_len, - sizeof(mParams->service_specific_info) - 1); result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN, mParams->service_specific_info_len); if (result < 0) { @@ -1406,7 +1404,7 @@ class NanDiscEnginePrimitive : public WifiCommand ALOGE("%s: Failed to put svc info, result = %d", __func__, result); return result; } - mParams->service_specific_info[len] = '\0'; + mParams->service_specific_info[mParams->service_specific_info_len] = '\0'; ALOGI("Transmit service info string is %s\n", mParams->service_specific_info); } @@ -1510,11 +1508,13 @@ class NanDiscEnginePrimitive : public WifiCommand { nan_hal_resp_t *rsp_vndr_data = NULL; NanResponseMsg rsp_data; + u32 len; if (reply.get_cmd() != NL80211_CMD_VENDOR || reply.get_vendor_data() == NULL) { ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); return NL_SKIP; } rsp_vndr_data = (nan_hal_resp_t *)reply.get_vendor_data(); + len = reply.get_vendor_data_len(); ALOGI("NanDiscEnginePrmitive::handle response\n"); memset(&rsp_data, 0, sizeof(NanResponseMsg)); rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd); @@ -1543,8 +1543,28 @@ class NanDiscEnginePrimitive : public WifiCommand } else if (rsp_data.response_type == NAN_RESPONSE_SUBSCRIBE) { rsp_data.body.subscribe_response.subscribe_id = mInstId; } else if (rsp_data.response_type == NAN_GET_CAPABILITIES) { - memcpy((void *)&rsp_data.body.nan_capabilities, (void *)&rsp_vndr_data->capabilities, - sizeof(rsp_data.body.nan_capabilities)); + /* avoid memcpy to keep backward compatibility */ + NanCapabilities *desc = &rsp_data.body.nan_capabilities; + NanCapabilities *src = &rsp_vndr_data->capabilities; + + desc->max_publishes = src->max_publishes; + desc->max_subscribes = src->max_subscribes; + desc->max_ndi_interfaces = src->max_ndi_interfaces; + desc->max_ndp_sessions = src->max_ndp_sessions; + desc->max_concurrent_nan_clusters = src->max_concurrent_nan_clusters; + desc->max_service_name_len = src->max_service_name_len; + desc->max_match_filter_len = src->max_match_filter_len; + desc->max_total_match_filter_len = src->max_total_match_filter_len; + desc->max_service_specific_info_len = src->max_service_specific_info_len; + desc->max_app_info_len = src->max_app_info_len; + desc->max_sdea_service_specific_info_len = src->max_sdea_service_specific_info_len; + desc->max_queued_transmit_followup_msgs = src->max_queued_transmit_followup_msgs; + desc->max_subscribe_address = src->max_subscribe_address; + desc->is_ndp_security_supported = src->is_ndp_security_supported; + desc->ndp_supported_bands = src->ndp_supported_bands; + desc->cipher_suites_supported = src->cipher_suites_supported; + desc->is_instant_mode_supported = src->is_instant_mode_supported; + desc->ndpe_attr_supported = src->ndpe_attr_supported; } GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data); diff --git a/bcmdhd/wifi_hal/rtt.cpp b/bcmdhd/wifi_hal/rtt.cpp index 603caf3..2197c81 100644 --- a/bcmdhd/wifi_hal/rtt.cpp +++ b/bcmdhd/wifi_hal/rtt.cpp @@ -48,7 +48,8 @@ #include "cpp_bindings.h" using namespace android; -#define RTT_RESULT_SIZE (sizeof(wifi_rtt_result)); +#define RTT_RESULT_V2_SIZE (sizeof(wifi_rtt_result_v2)) +#define RTT_RESULT_V1_SIZE (sizeof(wifi_rtt_result)) typedef enum { RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, @@ -82,6 +83,8 @@ typedef enum { RTT_ATTRIBUTE_RESULT_CNT = 32, RTT_ATTRIBUTE_RESULT = 33, RTT_ATTRIBUTE_RESUTL_DETAIL = 34, + RTT_ATTRIBUTE_RESULT_FREQ = 35, + RTT_ATTRIBUTE_RESULT_BW = 36, /* Add any new RTT_ATTRIBUTE prior to RTT_ATTRIBUTE_MAX */ RTT_ATTRIBUTE_MAX } RTT_ATTRIBUTE; @@ -131,7 +134,7 @@ get_err_info(int status) for (i = 0; i < (int) num_entries; i++) { if (p_entry->id == status) - return p_entry->text; + return p_entry->text.c_str(); p_entry++; /* next entry */ } return "unknown error"; /* not found */ @@ -321,9 +324,15 @@ class RttCommand : public WifiCommand int currDtlIdx; int totalCnt; static const int MAX_RESULTS = 1024; - wifi_rtt_result *rttResults[MAX_RESULTS]; + wifi_rtt_result_v2 *rttResults[MAX_RESULTS]; wifi_rtt_config *rttParams; wifi_rtt_event_handler rttHandler; + int nextidx = 0; + wifi_rtt_result *rttResultsV1[MAX_RESULTS]; + wifi_channel channel; + wifi_rtt_bw bw = WIFI_RTT_BW_UNSPECIFIED; + int result_size; + int opt_result_size; public: RttCommand(wifi_interface_handle iface, int id, unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler) @@ -331,6 +340,7 @@ public: rttHandler(handler) { memset(rttResults, 0, sizeof(rttResults)); + memset(rttResultsV1, 0, sizeof(rttResultsV1)); currentIdx = 0; mCompleted = 0; totalCnt = 0; @@ -345,9 +355,10 @@ public: totalCnt = 0; currDtlIdx = 0; numRttParams = 0; - memset(rttResults, 0, sizeof(rttResults)); - rttParams = NULL; - rttHandler.on_rtt_results = NULL; + memset(rttResults, 0, sizeof(rttResults)); + memset(rttResultsV1, 0, sizeof(rttResultsV1)); + rttParams = NULL; + rttHandler.on_rtt_results_v2 = NULL; } int createSetupRequest(WifiRequest& request) { @@ -563,79 +574,159 @@ public: bssid[3], bssid[4], bssid[5]); + } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_FREQ) { + channel = it2.get_u32(); + if (rttResults[currentIdx] == NULL) { + ALOGE("Not allocated, currentIdx %d\n", currentIdx); + break; + } + if (!channel) { + rttResults[currentIdx]->frequency = UNSPECIFIED; + } else { + rttResults[currentIdx]->frequency = channel; + } + ALOGI("retrieved rtt_result : \n\tchannel :%d", + rttResults[currentIdx]->frequency); + } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_BW) { + bw = (wifi_rtt_bw)it2.get_u32(); + if (rttResults[currentIdx] == NULL) { + ALOGE("Not allocated, currentIdx %d\n", currentIdx); + break; + } + rttResults[currentIdx]->packet_bw = bw; + ALOGI("retrieved rtt_result : \n\tpacket_bw :%d", + rttResults[currentIdx]->packet_bw); } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_CNT) { result_cnt = it2.get_u32(); ALOGI("retrieved result_cnt : %d\n", result_cnt); } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT) { + currentIdx = nextidx; int result_len = it2.get_len(); - rttResults[currentIdx] = (wifi_rtt_result *)malloc(it2.get_len()); - wifi_rtt_result *rtt_result = rttResults[currentIdx]; - if (rtt_result == NULL) { + rttResultsV1[currentIdx] = + (wifi_rtt_result *)malloc(it2.get_len()); + wifi_rtt_result *rtt_results_v1 = rttResultsV1[currentIdx]; + if (rtt_results_v1 == NULL) { mCompleted = 1; - ALOGE("failed to allocate the wifi_rtt_result\n"); + ALOGE("failed to allocate the wifi_result_v1\n"); break; } - memcpy(rtt_result, it2.get_data(), it2.get_len()); - result_len -= sizeof(wifi_rtt_result); + + /* Populate to the rtt_results_v1 struct */ + memcpy(rtt_results_v1, it2.get_data(), it2.get_len()); + + /* handle the optional data */ + result_len -= RTT_RESULT_V1_SIZE; if (result_len > 0) { dot11_rm_ie_t *ele_1; dot11_rm_ie_t *ele_2; /* The result has LCI or LCR element */ - ele_1 = (dot11_rm_ie_t *)(rtt_result + 1); + ele_1 = (dot11_rm_ie_t *)(rtt_results_v1 + 1); if (ele_1->id == DOT11_MNG_MEASURE_REPORT_ID) { if (ele_1->type == DOT11_MEASURE_TYPE_LCI) { - rtt_result->LCI = (wifi_information_element *)ele_1; + rtt_results_v1->LCI = (wifi_information_element *)ele_1; result_len -= (ele_1->len + DOT11_HDR_LEN); + opt_result_size += (ele_1->len + DOT11_HDR_LEN); /* get a next rm ie */ if (result_len > 0) { - ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN)); + ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + + (ele_1->len + DOT11_HDR_LEN)); if ((ele_2->id == DOT11_MNG_MEASURE_REPORT_ID) && (ele_2->type == DOT11_MEASURE_TYPE_CIVICLOC)) { - rtt_result->LCR = (wifi_information_element *)ele_2; + rtt_results_v1->LCR = (wifi_information_element *)ele_2; } } } else if (ele_1->type == DOT11_MEASURE_TYPE_CIVICLOC){ - rtt_result->LCR = (wifi_information_element *)ele_1; + rtt_results_v1->LCR = (wifi_information_element *)ele_1; result_len -= (ele_1->len + DOT11_HDR_LEN); + opt_result_size += (ele_1->len + DOT11_HDR_LEN); /* get a next rm ie */ if (result_len > 0) { - ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN)); + ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + + (ele_1->len + DOT11_HDR_LEN)); if ((ele_2->id == DOT11_MNG_MEASURE_REPORT_ID) && (ele_2->type == DOT11_MEASURE_TYPE_LCI)) { - rtt_result->LCI = (wifi_information_element *)ele_2; + rtt_results_v1->LCI = (wifi_information_element *)ele_2; } } } } } + + /* Alloc new struct including new elements, reserve for new elements */ + rttResults[currentIdx] = + (wifi_rtt_result_v2 *)malloc(RTT_RESULT_V2_SIZE + opt_result_size); + wifi_rtt_result_v2 *rtt_result_v2 = rttResults[currentIdx]; + if (rtt_result_v2 == NULL) { + ALOGE("failed to allocate the rtt_result\n"); + break; + } + + /* Populate the new struct as per the legacy struct elements */ + memcpy(&rtt_result_v2->rtt_result, + (wifi_rtt_result *)rtt_results_v1, RTT_RESULT_V1_SIZE); + if (!channel) { + rtt_result_v2->frequency = UNSPECIFIED; + } + + /* Copy the optional data to new struct */ + if (opt_result_size && + (opt_result_size == (it2.get_len() - RTT_RESULT_V1_SIZE))) { + + wifi_rtt_result_v2 *opt_rtt_result = NULL; + /* Intersect the optional data from legacy rtt result struct */ + wifi_rtt_result *opt_legacy_rtt_result = + (wifi_rtt_result *)(rtt_results_v1 + RTT_RESULT_V1_SIZE); + + /* shift dest buf by size of new rtt result struct */ + opt_rtt_result = + (wifi_rtt_result_v2 *)rtt_result_v2 + RTT_RESULT_V2_SIZE; + + /* Append optional rtt_result_v1 data to rtt_result_v2 */ + memcpy(opt_rtt_result, opt_legacy_rtt_result, + (it2.get_len() - RTT_RESULT_V1_SIZE)); + } else { + ALOGI("Optional rtt result elements missing, skip processing\n"); + } + totalCnt++; - ALOGI("retrived rtt_result : \n\tburst_num :%d, measurement_number : %d, success_number : %d\n" - "\tnumber_per_burst_peer : %d, status : %s, retry_after_duration : %d s\n" - "\trssi : %d dbm, rx_rate : %d Kbps, rtt : %lu ns, rtt_sd : %lu\n" - "\tdistance : %d cm, burst_duration : %d ms, negotiated_burst_num : %d\n", - rtt_result->burst_num, rtt_result->measurement_number, - rtt_result->success_number, rtt_result->number_per_burst_peer, - get_err_info(rtt_result->status), rtt_result->retry_after_duration, - rtt_result->rssi, rtt_result->rx_rate.bitrate * 100, - (unsigned long)rtt_result->rtt/1000, (unsigned long)rtt_result->rtt_sd, - rtt_result->distance_mm / 10, - rtt_result->burst_duration, rtt_result->negotiated_burst_num); - currentIdx++; + ALOGI("retrieved rtt_result : \n\tburst_num :%d, measurement_number : %d" + ", success_number : %d \tnumber_per_burst_peer : %d, status : %s," + " retry_after_duration : %d s\n \trssi : %d dbm," + " rx_rate : %d Kbps, rtt : %lu ns, rtt_sd : %lu\n" + "\tdistance : %d cm, burst_duration : %d ms," + " negotiated_burst_num : %d\n", + rtt_results_v1->burst_num, rtt_results_v1->measurement_number, + rtt_results_v1->success_number, + rtt_results_v1->number_per_burst_peer, + get_err_info(rtt_results_v1->status), + rtt_results_v1->retry_after_duration, + rtt_results_v1->rssi, rtt_results_v1->rx_rate.bitrate * 100, + (unsigned long)rtt_results_v1->rtt/1000, + (unsigned long)rtt_results_v1->rtt_sd, + rtt_results_v1->distance_mm / 10, + rtt_results_v1->burst_duration, + rtt_results_v1->negotiated_burst_num); + nextidx = currentIdx; + nextidx++; } } } - } if (mCompleted) { unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE); - if (*rttHandler.on_rtt_results) { - (*rttHandler.on_rtt_results)(id(), totalCnt, rttResults); + { + if (*rttHandler.on_rtt_results_v2) { + (*rttHandler.on_rtt_results_v2)(id(), totalCnt, rttResults); + } } for (int i = 0; i < currentIdx; i++) { free(rttResults[i]); rttResults[i] = NULL; + + free(rttResultsV1[i]); + rttResultsV1[i] = NULL; } - totalCnt = currentIdx = 0; + totalCnt = currentIdx = nextidx = 0; WifiCommand *cmd = wifi_unregister_cmd(wifiHandle(), id()); if (cmd) cmd->releaseRef(); @@ -650,16 +741,16 @@ wifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle ifac unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler) { if (iface == NULL) { - ALOGE("wifi_rtt_range_request: NULL iface pointer provided." - " Exit."); - return WIFI_ERROR_INVALID_ARGS; + ALOGE("wifi_rtt_range_request: NULL iface pointer provided." + " Exit."); + return WIFI_ERROR_INVALID_ARGS; } wifi_handle handle = getWifiHandle(iface); if (handle == NULL) { - ALOGE("wifi_rtt_range_request: NULL handle pointer provided." - " Exit."); - return WIFI_ERROR_INVALID_ARGS; + ALOGE("wifi_rtt_range_request: NULL handle pointer provided." + " Exit."); + return WIFI_ERROR_INVALID_ARGS; } ALOGI("Rtt range_request; id = %d", id); 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 <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 <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink/handlers.h>
+
+#include "sync.h"
+
+#define LOG_TAG "WifiHAL"
+
+#include <utils/Log.h>
+#include <hardware_legacy/wifi_hal.h>
+#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/twt.cpp b/bcmdhd/wifi_hal/twt.cpp index e3dd5bd..63cd002 100755 --- a/bcmdhd/wifi_hal/twt.cpp +++ b/bcmdhd/wifi_hal/twt.cpp @@ -367,7 +367,7 @@ protected: nlattr *data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); int len = reply.get_vendor_data_len(); - ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len); + ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); if (data == NULL || len == 0) { ALOGE("no vendor data in GetTwtCapabilitiesCommand response; ignoring it\n"); return NL_SKIP; @@ -463,7 +463,7 @@ protected: nlattr *data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); int len = reply.get_vendor_data_len(); - ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len); + ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); if (data == NULL || len == 0) { ALOGE("no vendor data in GetTwtStatsCommand response; ignoring it\n"); return NL_SKIP; diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp index e6a14e7..f746f09 100755..100644 --- a/bcmdhd/wifi_hal/wifi_hal.cpp +++ b/bcmdhd/wifi_hal/wifi_hal.cpp @@ -100,6 +100,10 @@ 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); +wifi_error wifi_enable_sta_channel_for_peer_network(wifi_handle handle, + u32 channelCategoryEnableFlag); typedef enum wifi_attr { ANDR_WIFI_ATTRIBUTE_INVALID = 0, @@ -117,6 +121,7 @@ typedef enum wifi_attr { ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW = 12, ANDR_WIFI_ATTRIBUTE_VOIP_MODE = 13, ANDR_WIFI_ATTRIBUTE_DTIM_MULTIPLIER = 14, + ANDR_WIFI_ATTRIBUTE_CHAN_POLICY = 15, // Add more attribute here ANDR_WIFI_ATTRIBUTE_MAX } wifi_attr_t; @@ -355,7 +360,8 @@ 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; + fn->wifi_enable_sta_channel_for_peer_network = wifi_enable_sta_channel_for_peer_network; return WIFI_SUCCESS; } #ifdef GOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER @@ -3056,3 +3062,47 @@ wifi_error wifi_enable_tx_power_limits(wifi_interface_handle handle, bool isEnab EnableTxPowerLimit command(handle, isEnable); return (wifi_error) command.requestResponse(); } + +////////////////////////////////////////////////////// +class EnableStaChannel : public WifiCommand { + +private: + u32 mChannelCatEnabFlag; +public: + EnableStaChannel(wifi_interface_handle handle, u32 channelCategoryEnableFlag) + : WifiCommand("EnableStaChannel", handle, 0) { + mChannelCatEnabFlag = channelCategoryEnableFlag; + } + virtual int create() { + int ret; + + ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CHANNEL_POLICY); + if (ret < 0) { + ALOGE("Can't create message to send to driver - %d", ret); + return ret; + } + + nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA); + ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_CHAN_POLICY, mChannelCatEnabFlag); + if (ret < 0) { + return ret; + } + + mMsg.attr_end(data); + return WIFI_SUCCESS; + } +}; + +/* enable or disable the feature of allowing current STA-connected + * channel for WFA GO, SAP and Wi-Fi Aware when the regulatory allows. + */ +wifi_error wifi_enable_sta_channel_for_peer_network(wifi_handle handle, + u32 channelCategoryEnableFlag) { + int numIfaceHandles = 0; + wifi_interface_handle *ifaceHandles = NULL; + wifi_interface_handle wlan0Handle; + + wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles); + EnableStaChannel command(wlan0Handle, channelCategoryEnableFlag); + return (wifi_error) command.requestResponse(); +} |