diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 04:59:37 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 04:59:37 +0000 |
commit | 289db8264b10d7d4848271f64b4b17c877637714 (patch) | |
tree | ce3b69bd7685c85cab2f9ec566c8e9cc4740289b | |
parent | 353e7d58feafb5313c2f671dc8cb30771b621ce9 (diff) | |
parent | 68236de9ae117f14b8068684e90a056cb478cbb3 (diff) | |
download | wlan-289db8264b10d7d4848271f64b4b17c877637714.tar.gz |
Snap for 10453563 from 68236de9ae117f14b8068684e90a056cb478cbb3 to mainline-media-swcodec-releaseaml_swc_341111000aml_swc_341011020aml_swc_340922010
Change-Id: Iae3cd68e38569506961701a55d3a32042285484e
-rw-r--r-- | OWNERS | 1 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/Android.bp | 91 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/Android.mk | 69 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/common.cpp | 2 | ||||
-rw-r--r--[-rwxr-xr-x] | bcmdhd/wifi_hal/common.h | 12 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/cpp_bindings.cpp | 5 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/cpp_bindings.h | 2 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/gscan.cpp | 2 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/link_layer_stats.cpp | 84 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/nan.cpp | 240 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/rtt.cpp | 176 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/scan.cpp | 166 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/twt.cpp | 6 | ||||
-rw-r--r--[-rwxr-xr-x] | bcmdhd/wifi_hal/wifi_hal.cpp | 125 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/wifi_logger.cpp | 68 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/wifi_offload.cpp | 2 |
16 files changed, 777 insertions, 274 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 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" |