summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-03 15:58:41 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-03 15:58:41 +0000
commited8786614b409ba271952945dbba7a8155f571fc (patch)
treece3b69bd7685c85cab2f9ec566c8e9cc4740289b
parent373637feb77e429c8a133a3d84c43d3ab7c5c3a9 (diff)
parent68236de9ae117f14b8068684e90a056cb478cbb3 (diff)
downloadwlan-android14-mainline-adbd-release.tar.gz
Snap for 10428683 from 68236de9ae117f14b8068684e90a056cb478cbb3 to mainline-adbd-releaseaml_adb_340912530aml_adb_340912350aml_adb_340912200aml_adb_340912000android14-mainline-adbd-release
Change-Id: I85847be674b63854b2ca504940cf68b8d1580b3a
-rw-r--r--OWNERS1
-rw-r--r--bcmdhd/wifi_hal/Android.bp91
-rwxr-xr-xbcmdhd/wifi_hal/Android.mk69
-rwxr-xr-xbcmdhd/wifi_hal/common.cpp2
-rw-r--r--[-rwxr-xr-x]bcmdhd/wifi_hal/common.h12
-rwxr-xr-xbcmdhd/wifi_hal/cpp_bindings.cpp5
-rwxr-xr-xbcmdhd/wifi_hal/cpp_bindings.h2
-rwxr-xr-xbcmdhd/wifi_hal/gscan.cpp2
-rw-r--r--bcmdhd/wifi_hal/link_layer_stats.cpp84
-rwxr-xr-xbcmdhd/wifi_hal/nan.cpp240
-rw-r--r--bcmdhd/wifi_hal/rtt.cpp176
-rw-r--r--bcmdhd/wifi_hal/scan.cpp166
-rwxr-xr-xbcmdhd/wifi_hal/twt.cpp6
-rw-r--r--[-rwxr-xr-x]bcmdhd/wifi_hal/wifi_hal.cpp125
-rwxr-xr-xbcmdhd/wifi_hal/wifi_logger.cpp68
-rw-r--r--bcmdhd/wifi_hal/wifi_offload.cpp2
16 files changed, 777 insertions, 274 deletions
diff --git a/OWNERS b/OWNERS
index d8c95cc..dd590d3 100644
--- a/OWNERS
+++ b/OWNERS
@@ -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
new file mode 100644
index 0000000..4994828
--- /dev/null
+++ b/bcmdhd/wifi_hal/Android.bp
@@ -0,0 +1,91 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// 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.
+
+// Make the HAL library
+// ============================================================
+package {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: [
+ "Android-Apache-2.0",
+ ],
+}
+
+soong_config_module_type_import {
+ from: "frameworks/opt/net/wifi/libwifi_hal/Android.bp",
+ module_types: ["wifi_cc_defaults"],
+}
+
+wifi_cc_defaults {
+ name: "libwifi-hal-bcm-defaults",
+ soong_config_variables: {
+ google_wifi_config_lib: {
+ shared_libs: ["google_wifi_firmware_config_version_c_wrapper"],
+ cflags: [
+ "-DGOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER",
+ // only for pixel feature
+ "-DRING_DUMP",
+ ],
+ },
+ },
+}
+
+cc_library_static {
+ name: "libwifi-hal-bcm",
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-format",
+ "-Wno-reorder",
+ "-Wno-unused-function",
+ "-Wno-unused-parameter",
+ "-Wno-unused-private-field",
+ "-Wno-unused-variable",
+ "-Wno-unused-parameter",
+ ],
+
+ defaults: [
+ "libwifi-hal-bcm-defaults",
+ ],
+
+ header_libs: [
+ "libnetlink_iface_headers",
+ "libhardware_legacy_headers",
+ ],
+
+ shared_libs: [
+ // added for libwifi-hal-bcm
+ "libcrypto",
+ // shared_libs in libwifi-hal
+ "liblog",
+ "libnl",
+ "libutils",
+ ],
+
+ srcs: [
+ "wifi_hal.cpp",
+ "rtt.cpp",
+ "common.cpp",
+ "cpp_bindings.cpp",
+ "gscan.cpp",
+ "nan.cpp",
+ "link_layer_stats.cpp",
+ "wifi_logger.cpp",
+ "wifi_offload.cpp",
+ "twt.cpp",
+ "scan.cpp",
+ ],
+
+ proprietary: true,
+}
diff --git a/bcmdhd/wifi_hal/Android.mk b/bcmdhd/wifi_hal/Android.mk
deleted file mode 100755
index 471c312..0000000
--- a/bcmdhd/wifi_hal/Android.mk
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-
-# Make the HAL library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_CFLAGS := \
- -Wall \
- -Werror \
- -Wno-format \
- -Wno-reorder \
- -Wno-unused-function \
- -Wno-unused-parameter \
- -Wno-unused-private-field \
- -Wno-unused-variable \
- -Wno-unused-parameter
-
-LOCAL_C_INCLUDES += \
- external/libnl/include \
- $(call include-path-for, libhardware_legacy)/hardware_legacy \
- external/wpa_supplicant_8/src/drivers
-
-LOCAL_C_INCLUDES += \
- external/boringssl/include \
- external/boringssl/src/crypto/digest \
- external/boringssl/src/crypto/evp/
-
-LOCAL_HEADER_LIBRARIES := libutils_headers liblog_headers
-
-ifneq ($(wildcard vendor/google/libraries/GoogleWifiConfigLib),)
-LOCAL_SHARED_LIBRARIES += \
- google_wifi_firmware_config_version_c_wrapper
-LOCAL_CFLAGS += -DGOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER
-#only for pixel feature
-LOCAL_CFLAGS += -DRING_DUMP
-endif
-
-LOCAL_SRC_FILES := \
- wifi_hal.cpp \
- rtt.cpp \
- common.cpp \
- cpp_bindings.cpp \
- gscan.cpp \
- nan.cpp \
- link_layer_stats.cpp \
- wifi_logger.cpp \
- wifi_offload.cpp \
- twt.cpp
-
-LOCAL_MODULE := libwifi-hal-bcm
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_PROPRIETARY_MODULE := true
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/bcmdhd/wifi_hal/common.cpp b/bcmdhd/wifi_hal/common.cpp
index 5a9d5ab..1a55aac 100755
--- a/bcmdhd/wifi_hal/common.cpp
+++ b/bcmdhd/wifi_hal/common.cpp
@@ -33,7 +33,7 @@
#include <netlink/socket.h>
#include <netlink/handlers.h>
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#include "common.h"
#include "cpp_bindings.h"
diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h
index ecc1abf..b54fbb1 100755..100644
--- a/bcmdhd/wifi_hal/common.h
+++ b/bcmdhd/wifi_hal/common.h
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#ifndef __WIFI_HAL_COMMON_H__
#define __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,
@@ -233,6 +238,8 @@ typedef enum {
WIFI_SUBCMD_USABLE_CHANNEL = ANDROID_NL80211_SUBCMD_USABLE_CHANNEL_START,
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 {
@@ -459,8 +466,7 @@ wifi_interface_handle wifi_get_wlan_interface(wifi_handle info,
#ifdef RING_DUMP
wifi_error wifi_start_ring_dump(wifi_interface_handle iface,
wifi_ring_buffer_data_handler ring_handle);
-wifi_error wifi_stop_ring_dump(wifi_interface_handle iface,
- wifi_ring_buffer_data_handler ring_handle);
+wifi_error wifi_stop_ring_dump(wifi_interface_handle iface);
#endif /* RING_DUMP */
wifi_error wifi_hal_ota_update(wifi_interface_handle iface, uint32_t ota_version);
wifi_error wifi_hal_preInit(wifi_interface_handle iface);
diff --git a/bcmdhd/wifi_hal/cpp_bindings.cpp b/bcmdhd/wifi_hal/cpp_bindings.cpp
index 7a634bd..fa120e7 100755
--- a/bcmdhd/wifi_hal/cpp_bindings.cpp
+++ b/bcmdhd/wifi_hal/cpp_bindings.cpp
@@ -36,7 +36,7 @@
#include <ctype.h>
#include <errno.h>
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#include "common.h"
#include "cpp_bindings.h"
@@ -601,6 +601,9 @@ static int mapErrorCodes(int err)
case -EBUSY:
ret = WIFI_ERROR_BUSY;
break;
+ case -ENODEV:
+ ret = WIFI_ERROR_NOT_AVAILABLE;
+ break;
default:
ret = WIFI_ERROR_UNKNOWN;
}
diff --git a/bcmdhd/wifi_hal/cpp_bindings.h b/bcmdhd/wifi_hal/cpp_bindings.h
index 8b5600a..cc1c662 100755
--- a/bcmdhd/wifi_hal/cpp_bindings.h
+++ b/bcmdhd/wifi_hal/cpp_bindings.h
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#include "common.h"
#include "sync.h"
diff --git a/bcmdhd/wifi_hal/gscan.cpp b/bcmdhd/wifi_hal/gscan.cpp
index 995c989..19bab2b 100755
--- a/bcmdhd/wifi_hal/gscan.cpp
+++ b/bcmdhd/wifi_hal/gscan.cpp
@@ -40,7 +40,7 @@
#include <log/log.h>
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#include "common.h"
#include "cpp_bindings.h"
diff --git a/bcmdhd/wifi_hal/link_layer_stats.cpp b/bcmdhd/wifi_hal/link_layer_stats.cpp
index 3a922db..05ab438 100644
--- a/bcmdhd/wifi_hal/link_layer_stats.cpp
+++ b/bcmdhd/wifi_hal/link_layer_stats.cpp
@@ -39,7 +39,7 @@
#include <utils/Log.h>
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#include "common.h"
#include "cpp_bindings.h"
@@ -79,7 +79,7 @@ public:
{ }
virtual int create() {
- // ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
+ ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_GET_INFO);
if (ret < 0) {
@@ -99,7 +99,7 @@ protected:
uint32_t total_size = 0, per_radio_size = 0, data_len = 0, rem_len = 0;
int num_radios = 0, id = 0, subcmd = 0, len = 0;
- // ALOGI("In GetLinkStatsCommand::handleResponse");
+ ALOGI("In GetLinkStatsCommand::handleResponse");
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
@@ -126,10 +126,16 @@ protected:
} else {
ALOGW("Ignoring invalid attribute type = %d, size = %d\n",
it.get_type(), it.get_len());
+ return NL_SKIP;
}
}
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) {
@@ -139,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;
@@ -160,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);
@@ -176,38 +183,8 @@ protected:
}
(*mHandler.on_link_stats_results)(id, (wifi_iface_stat *)iface_stat,
num_radios, (wifi_radio_stat *)radioStatsBuf);
- } else {
- /* To be deprecated, adding it to keep it backward compatible */
- ALOGD("GetLinkStatCommand: zero radio case\n");
- data = reply.get_vendor_data();
- if (!data) {
- ALOGE("Invalid vendor data received\n");
- return NL_SKIP;
- }
-
- num_radios = 1;
- data = reply.get_vendor_data();
- len = reply.get_vendor_data_len();
- if (!data || !len) {
- ALOGE("Invalid vendor data received\n");
- return NL_SKIP;
- }
- radio_stat_ptr =
- convertToExternalRadioStatStructureLegacy((wifi_radio_stat_internal *)data);
- if (!radio_stat_ptr) {
- ALOGE("Invalid stats pointer received\n");
- return NL_SKIP;
- }
- wifi_iface_stat *iface_stat =
- (wifi_iface_stat *)((char *)&((wifi_radio_stat_internal *)data)->channels
- + radio_stat_ptr->num_channels * sizeof(wifi_channel_stat));
- (*mHandler.on_link_stats_results)(id, iface_stat, num_radios, radio_stat_ptr);
}
exit:
- if (radio_stat_ptr) {
- free(radio_stat_ptr);
- radio_stat_ptr = NULL;
- }
if (radioStatsBuf) {
free(radioStatsBuf);
radioStatsBuf = NULL;
@@ -247,37 +224,6 @@ private:
}
return external_stat_ptr;
}
-
- wifi_radio_stat *convertToExternalRadioStatStructureLegacy(wifi_radio_stat_internal *internal_stat_ptr) {
- wifi_radio_stat *external_stat_ptr = NULL;
- if (!internal_stat_ptr) {
- ALOGE("Sta_ptr is null\n");
- } else {
- uint32_t channel_size = internal_stat_ptr->num_channels * sizeof(wifi_channel_stat);
- uint32_t total_size = sizeof(wifi_radio_stat) + channel_size;
- external_stat_ptr = (wifi_radio_stat *)malloc(total_size);
- if (external_stat_ptr) {
- external_stat_ptr->radio = internal_stat_ptr->radio;
- external_stat_ptr->on_time = internal_stat_ptr->on_time;
- external_stat_ptr->tx_time = internal_stat_ptr->tx_time;
- external_stat_ptr->rx_time = internal_stat_ptr->rx_time;
- external_stat_ptr->tx_time_per_levels = NULL;
- external_stat_ptr->num_tx_levels = 0;
- external_stat_ptr->on_time_scan = internal_stat_ptr->on_time_scan;
- external_stat_ptr->on_time_nbd = internal_stat_ptr->on_time_nbd;
- external_stat_ptr->on_time_gscan = internal_stat_ptr->on_time_gscan;
- external_stat_ptr->on_time_roam_scan = internal_stat_ptr->on_time_roam_scan;
- external_stat_ptr->on_time_pno_scan = internal_stat_ptr->on_time_pno_scan;
- external_stat_ptr->on_time_hs20 = internal_stat_ptr->on_time_hs20;
- external_stat_ptr->num_channels = internal_stat_ptr->num_channels;
- if (internal_stat_ptr->num_channels) {
- memcpy(&(external_stat_ptr->channels), &(internal_stat_ptr->channels),
- channel_size);
- }
- }
- }
- return external_stat_ptr;
- }
};
wifi_error wifi_get_link_stats(wifi_request_id id,
diff --git a/bcmdhd/wifi_hal/nan.cpp b/bcmdhd/wifi_hal/nan.cpp
index 52f29e3..4dd4dd9 100755
--- a/bcmdhd/wifi_hal/nan.cpp
+++ b/bcmdhd/wifi_hal/nan.cpp
@@ -40,13 +40,13 @@
#include <utils/Log.h>
#include <log/log.h>
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#include "common.h"
#include "cpp_bindings.h"
#include "netinet/in.h"
#include "arpa/inet.h"
#include <openssl/sha.h>
-#include <openssl/evp.h>
+#include <openssl/evp.h>
#include <sys/ioctl.h>
/* Changes between incompatible Version of NAN */
@@ -385,6 +385,7 @@ static int is_cmd_response(int cmd);
static int get_svc_hash(unsigned char *svc_name, u16 svc_name_len,
u8 *svc_hash, u16 svc_hash_len);
NanResponseType get_response_type(WIFI_SUB_COMMAND nan_subcmd);
+NanResponseType get_response_type_frm_req_type(NanRequestType cmdType);
static NanStatusType nan_map_response_status(int vendor_status);
/* Function to separate the common events to NAN1.0 events */
@@ -701,6 +702,8 @@ class NanDiscEnginePrimitive : public WifiCommand
if (mParams->service_name_len) {
u8 svc_hash[NAN_SVC_HASH_SIZE];
+ u16 len = min(mParams->service_name_len, sizeof(mParams->service_name) - 1);
+ mParams->service_name[len] = '\0';
result = get_svc_hash(mParams->service_name, mParams->service_name_len,
svc_hash, NAN_SVC_HASH_SIZE);
@@ -1065,6 +1068,8 @@ class NanDiscEnginePrimitive : public WifiCommand
if (mParams->service_name_len) {
u8 svc_hash[NAN_SVC_HASH_SIZE];
+ u16 len = min(mParams->service_name_len, sizeof(mParams->service_name) - 1);
+ mParams->service_name[len] = '\0';
result = get_svc_hash(mParams->service_name, mParams->service_name_len,
svc_hash, NAN_SVC_HASH_SIZE);
@@ -1503,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);
@@ -1536,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);
@@ -1570,8 +1597,9 @@ class NanDiscEnginePrimitive : public WifiCommand
pub_term_event.reason = (NanStatusType)it.get_u8();
ALOGI("pub termination status %u", pub_term_event.reason);
} else if (attr_type == NAN_ATTRIBUTE_REASON) {
- u8 len = min(it.get_len(), sizeof(pub_term_event.nan_reason));
+ u8 len = min(it.get_len(), sizeof(pub_term_event.nan_reason) - 1);
memcpy(pub_term_event.nan_reason, it.get_data(), len);
+ pub_term_event.nan_reason[len] = '\0';
ALOGI("pub termination reason: %s, len = %d\n",
pub_term_event.nan_reason, len);
} else {
@@ -1693,8 +1721,9 @@ class NanDiscEnginePrimitive : public WifiCommand
sub_term_event.reason = (NanStatusType)it.get_u16();
ALOGI("sub termination status %u", sub_term_event.reason);
} else if (attr_type == NAN_ATTRIBUTE_REASON) {
- u8 len = min(it.get_len(), sizeof(sub_term_event.nan_reason));
+ u8 len = min(it.get_len(), sizeof(sub_term_event.nan_reason) - 1);
memcpy(sub_term_event.nan_reason, it.get_data(), len);
+ sub_term_event.nan_reason[len] = '\0';
ALOGI("sub termination nan reason: %s, len = %d\n",
sub_term_event.nan_reason, len);
} else {
@@ -1745,8 +1774,9 @@ class NanDiscEnginePrimitive : public WifiCommand
} else if (attr_type == NAN_ATTRIBUTE_STATUS) {
followup_ind.reason = (NanStatusType)it.get_u8();
} else if (attr_type == NAN_ATTRIBUTE_REASON) {
- u8 len = min(it.get_len(), sizeof(followup_ind.nan_reason));
+ u8 len = min(it.get_len(), sizeof(followup_ind.nan_reason) - 1);
memcpy(followup_ind.nan_reason, it.get_data(), len);
+ followup_ind.nan_reason[len] = '\0';
ALOGI("nan transmit followup ind: reason: %s, len = %d\n",
followup_ind.nan_reason, len);
}
@@ -1839,40 +1869,69 @@ class NanDataPathPrimitive : public WifiCommand
int createDataPathIfaceRequest(WifiRequest& request, char *iface_name)
{
- int result = request.create(GOOGLE_OUI, NAN_SUBCMD_DATA_PATH_IFACE_CREATE);
+ ALOGD("add ifname = %s, iface_type = %d", iface_name, NL80211_IFTYPE_STATION);
+ u32 wlan0_id = if_nametoindex("wlan0");
+ if (!wlan0_id) {
+ ALOGE("%s: Error wlan0 not present\n", __FUNCTION__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ /* Do not create interface if already exist. */
+ if (if_nametoindex(iface_name)) {
+ ALOGD("%s: if_nametoindex(%s) = %d already exists, skip create \n",
+ __FUNCTION__, iface_name, if_nametoindex(iface_name));
+ return WIFI_SUCCESS;
+ }
+
+ int result = request.create(NL80211_CMD_NEW_INTERFACE);
if (result < 0) {
- ALOGE("%s Failed to create request\n", __func__);
+ ALOGE("failed to create NL80211_CMD_NEW_INTERFACE; result = %d", result);
return result;
}
- nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
- result = request.put_string(NAN_ATTRIBUTE_IFACE, (char *)iface_name);
+ result = request.put_u32(NL80211_ATTR_IFINDEX, wlan0_id);
if (result < 0) {
- ALOGE("%s: Failed to fill iface, result = %d\n", __func__, result);
+ ALOGE("failed to put NL80211_ATTR_IFINDEX; result = %d", result);
+ return result;
+ }
+
+ result = request.put_string(NL80211_ATTR_IFNAME, iface_name);
+ if (result < 0) {
+ ALOGE("failed to put NL80211_ATTR_IFNAME = %s; result = %d", iface_name, result);
+ return result;
+ }
+
+ result = request.put_u32(NL80211_ATTR_IFTYPE, NL80211_IFTYPE_STATION);
+ if (result < 0) {
+ ALOGE("failed to put NL80211_ATTR_IFTYPE; result = %d", result);
return result;
}
- request.attr_end(data);
return WIFI_SUCCESS;
}
int deleteDataPathIfaceRequest(WifiRequest& request, char *iface_name)
{
- int result = request.create(GOOGLE_OUI, NAN_SUBCMD_DATA_PATH_IFACE_DELETE);
+ ALOGD("delete ifname = %s\n", iface_name);
+
+ int result = request.create(NL80211_CMD_DEL_INTERFACE);
if (result < 0) {
- ALOGE("%s: Failed to create request, result = %d\n", __func__, result);
+ ALOGE("failed to create NL80211_CMD_DEL_INTERFACE; result = %d", result);
return result;
}
- nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-
- result = request.put_string(NAN_ATTRIBUTE_IFACE, (char *)iface_name);
+ result = request.put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(iface_name));
if (result < 0) {
- ALOGE("%s: Failed to fill iface, result = %d\n", __func__, result);
+ ALOGE("failed to put NL80211_ATTR_IFINDEX = %d; result = %d",
+ if_nametoindex(iface_name), result);
return result;
}
- request.attr_end(data);
+ result = request.put_string(NL80211_ATTR_IFNAME, iface_name);
+ if (result < 0) {
+ ALOGE("failed to put NL80211_ATTR_IFNAME = %s; result = %d", iface_name, result);
+ return result;
+ }
return WIFI_SUCCESS;
}
@@ -2296,7 +2355,23 @@ class NanDataPathPrimitive : public WifiCommand
ALOGE("%s: failed to configure setup; result = %d", __func__, result);
return result;
}
-
+ ALOGI("NanDataPathPrmitive::request Response\n");
+ if (mType == NAN_DATA_PATH_IFACE_DELETE) {
+ NanResponseMsg rsp_data;
+ memset(&rsp_data, 0, sizeof(NanResponseMsg));
+ /* Prepare the NanResponseMsg payload */
+ rsp_data.response_type = get_response_type_frm_req_type((NanRequestType)mType);
+ /* Return success even for no dev case also, nothing to do */
+ rsp_data.status = NAN_STATUS_SUCCESS;
+ memcpy(rsp_data.nan_error, NanStatusToString(rsp_data.status),
+ strlen(NanStatusToString(rsp_data.status)));
+ rsp_data.nan_error[strlen(NanStatusToString(rsp_data.status))] = '\0';
+ rsp_data.nan_error[NAN_ERROR_STR_LEN - 1] = '\0';
+ ALOGI("Mapped hal status = %d\n", rsp_data.status);
+ ALOGI("Received nan_error string %s\n", (u8*)rsp_data.nan_error);
+ GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
+ ALOGE("Notified by cmd ret!!");
+ }
request.destroy();
return WIFI_SUCCESS;
}
@@ -2321,49 +2396,63 @@ class NanDataPathPrimitive : public WifiCommand
int handleResponse(WifiEvent& reply)
{
nan_hal_resp_t *rsp_vndr_data = NULL;
+ NanResponseMsg rsp_data;
+ int32_t result = BCME_OK;
- if (reply.get_cmd() != NL80211_CMD_VENDOR || reply.get_vendor_data() == NULL) {
+ ALOGI("NanDataPathPrmitive::handle Response\n");
+ memset(&rsp_data, 0, sizeof(NanResponseMsg));
+ if (mType == NAN_DATA_PATH_IFACE_CREATE) {
+ /* NDI creation and deletion are done through vendor ops,
+ * driver does not send the cmd response payload,
+ * but for framework,
+ * mimicking the NanResponseMsg for iface create and delete nan cmds
+ */
+ rsp_data.response_type = get_response_type_frm_req_type((NanRequestType)mType);
+ /* Return success even for no dev case also, nothing to do */
+ if (result == WIFI_SUCCESS || result == WIFI_ERROR_NOT_AVAILABLE) {
+ rsp_data.status = NAN_STATUS_SUCCESS;
+ } else {
+ rsp_data.status = NAN_STATUS_INTERNAL_FAILURE;
+ }
+ } else 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();
- ALOGI("NanDataPathPrmitive::handle response\n");
- int32_t result = rsp_vndr_data->value;
- NanResponseMsg rsp_data;
+ } else {
+ rsp_vndr_data = (nan_hal_resp_t *)reply.get_vendor_data();
+ result = rsp_vndr_data->value;
+ rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
- memset(&rsp_data, 0, sizeof(NanResponseMsg));
- rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
+ if ((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd == NAN_SUBCMD_DATA_PATH_SEC_INFO) {
+ /* Follow through */
+ } else if (!valid_dp_response_type(rsp_data.response_type)) {
+ return NL_SKIP;
+ }
+ rsp_data.status = nan_map_response_status(rsp_vndr_data->status);
- if ((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd == NAN_SUBCMD_DATA_PATH_SEC_INFO) {
- /* Follow through */
- } else if (!valid_dp_response_type(rsp_data.response_type)) {
- return NL_SKIP;
+ if (rsp_data.response_type == NAN_DP_INITIATOR_RESPONSE) {
+ ALOGI("received ndp instance_id %d and ret = %d\n",
+ rsp_vndr_data->ndp_instance_id, result);
+ rsp_data.body.data_request_response.ndp_instance_id =
+ rsp_vndr_data->ndp_instance_id;
+ mNdpId = rsp_vndr_data->ndp_instance_id;
+ } else if ((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd == NAN_SUBCMD_DATA_PATH_SEC_INFO) {
+ memcpy(mPubNmi, rsp_vndr_data->pub_nmi, NAN_MAC_ADDR_LEN);
+ memcpy(mSvcHash, rsp_vndr_data->svc_hash, NAN_SVC_HASH_SIZE);
+ return NL_SKIP;
+ }
}
- rsp_data.status = nan_map_response_status(rsp_vndr_data->status);
- ALOGE("Mapped hal status = %d\n", rsp_data.status);
- if (rsp_vndr_data->nan_reason[0] == '\0') {
- memcpy(rsp_data.nan_error, NanStatusToString(rsp_data.status),
- strlen(NanStatusToString(rsp_data.status)));
- rsp_data.nan_error[strlen(NanStatusToString(rsp_data.status))] = '\0';
- }
+ memcpy(rsp_data.nan_error, NanStatusToString(rsp_data.status),
+ strlen(NanStatusToString(rsp_data.status)));
+ rsp_data.nan_error[strlen(NanStatusToString(rsp_data.status))] = '\0';
rsp_data.nan_error[NAN_ERROR_STR_LEN - 1] = '\0';
- ALOGI("\n Received nan_error string %s\n", (u8*)rsp_data.nan_error);
-
- if (rsp_data.response_type == NAN_DP_INITIATOR_RESPONSE) {
- ALOGI("received ndp instance_id %d and ret = %d\n", rsp_vndr_data->ndp_instance_id, result);
- rsp_data.body.data_request_response.ndp_instance_id = rsp_vndr_data->ndp_instance_id;
- mNdpId = rsp_vndr_data->ndp_instance_id;
- } else if ((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd == NAN_SUBCMD_DATA_PATH_SEC_INFO) {
- memcpy(mPubNmi, rsp_vndr_data->pub_nmi, NAN_MAC_ADDR_LEN);
- memcpy(mSvcHash, rsp_vndr_data->svc_hash, NAN_SVC_HASH_SIZE);
- return NL_SKIP;
- }
+ ALOGI("Mapped hal status = %d\n", rsp_data.status);
+ ALOGI("Received nan_error string %s\n", (u8*)rsp_data.nan_error);
ALOGI("NanDataPathPrmitive:Received response for cmd [%s], ret %d\n",
- NanRspToString(rsp_data.response_type), rsp_data.status);
+ NanRspToString(rsp_data.response_type), rsp_data.status);
GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
+ ALOGE("Notified by cmd reply!!");
return NL_SKIP;
}
@@ -3553,8 +3642,9 @@ class NanMacControl : public WifiCommand
disabled_ind.reason = (NanStatusType)it.get_u8();
ALOGI("Nan Disable:status %u", disabled_ind.reason);
} else if (attr_type == NAN_ATTRIBUTE_REASON) {
- u8 len = min(it.get_len(), sizeof(disabled_ind.nan_reason));
+ u8 len = min(it.get_len(), sizeof(disabled_ind.nan_reason) - 1);
memcpy(disabled_ind.nan_reason, it.get_data(), len);
+ disabled_ind.nan_reason[len] = '\0';
ALOGI("Disabled nan reason: %s, len = %d\n",
disabled_ind.nan_reason, len);
}
@@ -3864,6 +3954,27 @@ NanResponseType get_response_type(WIFI_SUB_COMMAND nan_subcmd)
return response_type;
}
+
+NanResponseType get_response_type_frm_req_type(NanRequestType cmdType) {
+ NanResponseType response_type;
+
+ switch (cmdType) {
+ case NAN_DATA_PATH_IFACE_CREATE:
+ response_type = NAN_DP_INTERFACE_CREATE;
+ break;
+ case NAN_DATA_PATH_IFACE_DELETE:
+ response_type = NAN_DP_INTERFACE_DELETE;
+ break;
+ default:
+ /* unknown response for a request type */
+ response_type = NAN_RESPONSE_ERROR;
+ break;
+ }
+
+ return response_type;
+
+}
+
static int get_svc_hash(unsigned char *svc_name,
u16 svc_name_len, u8 *svc_hash, u16 svc_hash_len)
{
@@ -4413,7 +4524,8 @@ wifi_error nan_disable_request(transaction_id id,
ALOGE("Disable NAN MAC transId= %d\n", id);
mac_prim->setId(id);
} else {
- ALOGE("Invalid transId= %d cur= %d\n", id, mac_prim->getId());
+ ALOGE("Invalid transId= %d cur= %d\n", id,
+ mac_prim ? mac_prim->getId() : -1);
}
cmd->setChreNan(0);
@@ -4844,8 +4956,9 @@ class NanEventCap : public WifiCommand
disabled_ind.reason = (NanStatusType)it.get_u8();
ALOGI("Nan Disable:status %u", disabled_ind.reason);
} else if (attr_type == NAN_ATTRIBUTE_REASON) {
- u8 len = min(it.get_len(), sizeof(disabled_ind.nan_reason));
+ u8 len = min(it.get_len(), sizeof(disabled_ind.nan_reason) - 1);
memcpy(disabled_ind.nan_reason, it.get_data(), len);
+ disabled_ind.nan_reason[len] = '\0';
ALOGI("nan disabled reason: %s, len = %d\n",
disabled_ind.nan_reason, len);
}
@@ -4870,8 +4983,9 @@ class NanEventCap : public WifiCommand
pub_term_event.reason = (NanStatusType)it.get_u8();
ALOGI("pub termination status %u", pub_term_event.reason);
} else if (attr_type == NAN_ATTRIBUTE_REASON) {
- u8 len = min(it.get_len(), sizeof(pub_term_event.nan_reason));
+ u8 len = min(it.get_len(), sizeof(pub_term_event.nan_reason) - 1);
memcpy(pub_term_event.nan_reason, it.get_data(), len);
+ pub_term_event.nan_reason[len] = '\0';
ALOGI("Pub termination nan reason: %s, len = %d\n",
pub_term_event.nan_reason, len);
} else {
@@ -5001,8 +5115,9 @@ class NanEventCap : public WifiCommand
sub_term_event.reason = (NanStatusType)it.get_u8();
ALOGI("sub termination status %u", sub_term_event.reason);
} else if (attr_type == NAN_ATTRIBUTE_REASON) {
- u8 len = min(it.get_len(), sizeof(sub_term_event.nan_reason));
+ u8 len = min(it.get_len(), sizeof(sub_term_event.nan_reason) - 1);
memcpy(sub_term_event.nan_reason, it.get_data(), len);
+ sub_term_event.nan_reason[len] = '\0';
ALOGI("sub termination nan reason: %s, len = %d\n",
sub_term_event.nan_reason, len);
} else {
@@ -5250,8 +5365,9 @@ class NanEventCap : public WifiCommand
} else if (attr_type == NAN_ATTRIBUTE_STATUS) {
followup_ind.reason = (NanStatusType)it.get_u8();
} else if (attr_type == NAN_ATTRIBUTE_REASON) {
- u8 len = min(it.get_len(), sizeof(followup_ind.nan_reason));
+ u8 len = min(it.get_len(), sizeof(followup_ind.nan_reason) - 1);
memcpy(followup_ind.nan_reason, it.get_data(), len);
+ followup_ind.nan_reason[len] = '\0';
ALOGI("nan transmit followup ind: reason: %s, len = %d\n",
followup_ind.nan_reason, len);
}
@@ -5337,6 +5453,9 @@ wifi_error nan_data_request_initiator(transaction_id id,
#endif /* CONFIG_BRCM */
counters.dp_req++;
if (msg->service_name_len) {
+ u16 len = min(msg->service_name_len, sizeof(msg->service_name) - 1);
+ msg->service_name[len] = '\0';
+
if (strncmp(NAN_OOB_INTEROP_SVC_NAME,
(char*)msg->service_name, msg->service_name_len) == 0) {
ALOGI("Use Hardcoded svc_hash\n");
@@ -5422,6 +5541,9 @@ wifi_error nan_data_indication_response(transaction_id id,
#endif /* CONFIG_BRCM */
counters.dp_resp++;
if (msg->service_name_len) {
+ u16 len = min(msg->service_name_len, sizeof(msg->service_name) - 1);
+ msg->service_name[len] = '\0';
+
if (strncmp(NAN_OOB_INTEROP_SVC_NAME,
(char*)msg->service_name, msg->service_name_len) == 0) {
ALOGI("Use Hardcoded svc_hash\n");
diff --git a/bcmdhd/wifi_hal/rtt.cpp b/bcmdhd/wifi_hal/rtt.cpp
index 6bb0a49..819364a 100644
--- a/bcmdhd/wifi_hal/rtt.cpp
+++ b/bcmdhd/wifi_hal/rtt.cpp
@@ -43,12 +43,13 @@
#include <log/log.h>
#include <utils/String8.h>
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#include "common.h"
#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;
@@ -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,18 +741,19 @@ 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);
RttCommand *cmd = new RttCommand(iface, id, num_rtt_config, rtt_config, handler);
NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
wifi_error result = wifi_register_cmd(handle, id, cmd);
@@ -695,9 +787,11 @@ wifi_error wifi_rtt_range_cancel(wifi_request_id id, wifi_interface_handle ifac
return WIFI_ERROR_INVALID_ARGS;
}
+ ALOGI("Rtt range_cancel_request; id = %d", id);
RttCommand *cmd = new RttCommand(iface, id);
NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
cmd->cancel_specific(num_devices, addr);
+ wifi_unregister_cmd(handle, id);
cmd->releaseRef();
return WIFI_SUCCESS;
}
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 15bb738..63cd002 100755
--- a/bcmdhd/wifi_hal/twt.cpp
+++ b/bcmdhd/wifi_hal/twt.cpp
@@ -39,7 +39,7 @@
#include <utils/Log.h>
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#include "common.h"
#include "cpp_bindings.h"
@@ -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 fe679ab..f746f09 100755..100644
--- a/bcmdhd/wifi_hal/wifi_hal.cpp
+++ b/bcmdhd/wifi_hal/wifi_hal.cpp
@@ -47,10 +47,10 @@
#define LOG_TAG "WifiHAL"
#include <log/log.h>
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
+#include <hardware_legacy/rtt.h>
#include "common.h"
#include "cpp_bindings.h"
-#include "rtt.h"
#include "brcm_version.h"
#include <stdio.h>
#include <string>
@@ -98,6 +98,13 @@ static wifi_error wifi_get_supported_radio_combinations_matrix(wifi_handle handl
u32 max_size, u32* size, wifi_radio_combination_matrix *radio_combination_matrix);
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,
ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET = 1,
@@ -114,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;
@@ -196,6 +204,13 @@ enum multista_request_type {
SET_USE_CASE
};
+enum wifi_tx_power_limits {
+ TX_POWER_CAP_ATTRIBUTE_INVALID = 0,
+ TX_POWER_CAP_ENABLE_ATTRIBUTE = 1,
+ /* Add more attributes here */
+ TX_POWER_ATTRIBUTE_MAX
+};
+
/* Initialize/Cleanup */
void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
@@ -344,7 +359,9 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
fn->wifi_nan_rtt_chre_enable_request = nan_chre_enable_request;
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
@@ -554,12 +571,13 @@ wifi_error wifi_wait_for_driver_ready(void)
// Function times out after 10 seconds
int count = (POLL_DRIVER_MAX_TIME_MS * 1000) / POLL_DRIVER_DURATION_US;
FILE *fd;
+ wifi_error status = WIFI_SUCCESS;
do {
if ((fd = fopen("/sys/class/net/wlan0", "r")) != NULL) {
fclose(fd);
- wifi_pre_initialize();
- return WIFI_SUCCESS;
+ status = wifi_pre_initialize();
+ return status;
}
usleep(POLL_DRIVER_DURATION_US);
} while(--count > 0);
@@ -644,10 +662,13 @@ void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)
if (wlan0Handle != NULL) {
ALOGE("Calling hal cleanup");
if (!get_halutil_mode()) {
+ wifi_cleanup_dynamic_ifaces(handle);
+ ALOGI("Cleaned dynamic virtual ifaces\n");
result = wifi_stop_hal(wlan0Handle);
if (result != WIFI_SUCCESS) {
ALOGE("wifi_stop_hal failed");
}
+ ALOGI("wifi_stop_hal success");
}
} else {
@@ -703,9 +724,6 @@ void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)
WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
ALOGE("Leaked command %p", cmd);
}
- if (!get_halutil_mode()) {
- wifi_cleanup_dynamic_ifaces(handle);
- }
pthread_mutex_unlock(&info->cb_lock);
info->clean_up = true;
@@ -2506,7 +2524,7 @@ public:
}
int createIface() {
- ALOGE("Creating virtual interface");
+ ALOGD("Creating virtual interface");
WifiRequest request(familyId(), ifaceId());
int result = createRequest(request, mIfname, mType, mwlan0_id);
if (result != WIFI_SUCCESS) {
@@ -2519,7 +2537,7 @@ public:
ALOGE("failed to get the virtual iface create response; result = %d\n", result);
return result;
}
- ALOGE("Created virtual interface");
+ ALOGD("Created virtual interface");
return WIFI_SUCCESS;
}
@@ -2537,6 +2555,7 @@ public:
ALOGE("failed to get response of delete virtual interface; result = %d\n", result);
return result;
}
+ ALOGD("Deleted virtual interface");
return WIFI_SUCCESS;
}
protected:
@@ -2552,8 +2571,11 @@ static std::vector<std::string> added_ifaces;
static void wifi_cleanup_dynamic_ifaces(wifi_handle handle)
{
int len = added_ifaces.size();
+ ALOGI("%s: virtual iface size %d\n", __FUNCTION__, len);
while (len--) {
wifi_virtual_interface_delete(handle, added_ifaces.front().c_str());
+ ALOGI("%s: deleted virtual iface %s\n",
+ __FUNCTION__, added_ifaces.front().c_str());
}
added_ifaces.clear();
}
@@ -3001,3 +3023,86 @@ wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask, u32 iface
filter_mask, max_size, size, channels);
return (wifi_error)command.start();
}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+class EnableTxPowerLimit : public WifiCommand {
+private:
+ bool mEnableTxLimits;
+public:
+ EnableTxPowerLimit(wifi_interface_handle handle, bool enable_tx_pwr_limits)
+ : WifiCommand("EnableTxPowerLimit", handle, 0)
+ {
+ mEnableTxLimits = enable_tx_pwr_limits;
+ }
+
+ virtual int create() {
+ int ret;
+
+ ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_ENABLE_TX_POWER_LIMIT);
+ 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_u8(TX_POWER_CAP_ENABLE_ATTRIBUTE, mEnableTxLimits);
+ if (ret < 0) {
+ ALOGE("Failed to put enable tx power limit param %d\n", mEnableTxLimits);
+ return ret;
+ }
+ mMsg.attr_end(data);
+ return WIFI_SUCCESS;
+ }
+};
+
+wifi_error wifi_enable_tx_power_limits(wifi_interface_handle handle, bool isEnable)
+{
+ ALOGD("Configuring the tx power limits , halHandle = %p\n", handle);
+
+ 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();
+}
diff --git a/bcmdhd/wifi_hal/wifi_logger.cpp b/bcmdhd/wifi_hal/wifi_logger.cpp
index 4d2d8dd..dbbcf79 100755
--- a/bcmdhd/wifi_hal/wifi_logger.cpp
+++ b/bcmdhd/wifi_hal/wifi_logger.cpp
@@ -45,7 +45,7 @@
#include <log/log.h>
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#include "common.h"
#include "cpp_bindings.h"
#include <sys/stat.h>
@@ -1035,6 +1035,12 @@ wifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level,
}
}
+typedef struct {
+ u32 magic;
+ int num_entries;
+} __attribute__((packed)) wifi_ring_buffer_entry_pack;
+
+#define WIFI_RING_BUFFER_PACK_MAGIC 0xDBAADBAA
///////////////////////////////////////////////////////////////////////////////
class SetLogHandler : public WifiCommand
@@ -1073,7 +1079,7 @@ public:
unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
ALOGV("Hal preInit Failed to put pid= %d", result);
return result;
- }
+ }
request.attr_end(data);
@@ -1153,11 +1159,46 @@ public:
if (mHandler.on_ring_buffer_data) {
/* Skip msg header. Retrieved log */
char *pBuff;
- wifi_ring_buffer_entry *buffer_entry =
- (wifi_ring_buffer_entry *) buffer;
- pBuff = (char *) (buffer_entry + 1);
- (*mHandler.on_ring_buffer_data)((char *)status.name, pBuff,
- buffer_entry->entry_size, &status);
+ int num_entries;
+ int cur_off = 0;
+ wifi_ring_buffer_entry_pack *pack_hdr =
+ (wifi_ring_buffer_entry_pack *)buffer;
+ wifi_ring_buffer_entry *entry_hdr =
+ (wifi_ring_buffer_entry *)(buffer + sizeof(*pack_hdr));
+ cur_off += sizeof(*pack_hdr);
+
+ if (pack_hdr->magic != WIFI_RING_BUFFER_PACK_MAGIC) {
+ ALOGE("SetLogHandler: magic code is not matched "
+ "magic:%u ring_name:%s\n", pack_hdr->magic, status.name);
+ return NL_SKIP;
+ }
+
+ num_entries = pack_hdr->num_entries;
+
+ while (num_entries > 0) {
+ /* Check for accesses that exceed the total buffer size */
+ if (cur_off + sizeof(*entry_hdr) + entry_hdr->entry_size > buffer_size) {
+ ALOGE("SetLogHandler: detected invalid access "
+ "num_entries:%d cur_num:%d buffer_size:%d cur_off:%d "
+ "hdrsize:%lu entry_size:%d ring_name:%s\n",
+ pack_hdr->num_entries, num_entries, buffer_size, cur_off,
+ sizeof(*entry_hdr), entry_hdr->entry_size, status.name);
+ return NL_SKIP;
+ }
+
+ /* Copy buffer without hdr to the ringbuffer in LegacyHAL */
+ pBuff = (char *)entry_hdr + sizeof(*entry_hdr);
+ (*mHandler.on_ring_buffer_data)((char *)status.name, pBuff,
+ entry_hdr->entry_size, &status);
+
+ cur_off += sizeof(*entry_hdr) + entry_hdr->entry_size;
+
+ /* jump to next entry_hdr */
+ entry_hdr = (wifi_ring_buffer_entry *)((char *)entry_hdr + sizeof(*entry_hdr) + entry_hdr->entry_size);
+
+ num_entries--;
+ }
+
}
} else {
ALOGE("Unknown Event");
@@ -1198,6 +1239,10 @@ wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle ifac
wifi_handle handle = getWifiHandle(iface);
ALOGE("Loghandler reset, wifi_request_id = %d, handle = %p", id, handle);
+#ifdef RING_DUMP
+ wifi_stop_ring_dump(iface);
+#endif /* RING_DUMP */
+
if (id == -1) {
wifi_ring_buffer_data_handler handler;
memset(&handler, 0, sizeof(handler));
@@ -1207,9 +1252,6 @@ wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle ifac
cmd->cancel();
cmd->releaseRef();
-#ifdef RING_DUMP
- wifi_stop_ring_dump(iface, handler);
-#endif /* RING_DUMP */
return WIFI_SUCCESS;
}
@@ -1643,9 +1685,6 @@ public:
ring_name[i] = NULL;
}
}
- if (mBuff) {
- free(mBuff);
- }
DUMP_INFO(("Stop Ring Dump Successfully Completed, mErrCode = %d\n", mErrCode));
return WIFI_SUCCESS;
@@ -1984,8 +2023,7 @@ wifi_error wifi_start_ring_dump(wifi_interface_handle iface,
return result;
}
-wifi_error wifi_stop_ring_dump(wifi_interface_handle iface,
- wifi_ring_buffer_data_handler ring_handle)
+wifi_error wifi_stop_ring_dump(wifi_interface_handle iface)
{
RingDump *cmd = new RingDump(iface, FILE_DUMP_REQUEST_ID);
NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
diff --git a/bcmdhd/wifi_hal/wifi_offload.cpp b/bcmdhd/wifi_hal/wifi_offload.cpp
index 1702ffd..a24a882 100644
--- a/bcmdhd/wifi_hal/wifi_offload.cpp
+++ b/bcmdhd/wifi_hal/wifi_offload.cpp
@@ -42,7 +42,7 @@
#include <log/log.h>
-#include "wifi_hal.h"
+#include <hardware_legacy/wifi_hal.h>
#include "common.h"
#include "cpp_bindings.h"