mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Add AIDL implementation for the vendor HAL service.
Bug: 205044134 Test: Pass AIDL VTS tests and regression tests. Change-Id: Iad04ce01f71fc220443e05a4be05d7d5545227e8
This commit is contained in:
committed by
Mahesh KKV
parent
da9b3895d2
commit
f3262f970d
214
wifi/aidl/default/Android.bp
Normal file
214
wifi/aidl/default/Android.bp
Normal file
@@ -0,0 +1,214 @@
|
||||
// Copyright (C) 2022 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.
|
||||
|
||||
package {
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
soong_config_module_type {
|
||||
name: "wifi_hal_cc_defaults",
|
||||
module_type: "cc_defaults",
|
||||
config_namespace: "wifi",
|
||||
bool_variables: [
|
||||
"hidl_feature_aware", // WIFI_HIDL_FEATURE_AWARE
|
||||
"hidl_feature_dual_interface", // WIFI_HIDL_FEATURE_DUAL_INTERFACE
|
||||
"hidl_feature_disable_ap", // WIFI_HIDL_FEATURE_DISABLE_AP
|
||||
"hidl_feature_disable_ap_mac_randomization", // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
|
||||
"avoid_iface_reset_mac_change", // WIFI_AVOID_IFACE_RESET_MAC_CHANGE
|
||||
],
|
||||
value_variables: [
|
||||
"hal_interface_combinations", // WIFI_HAL_INTERFACE_COMBINATIONS
|
||||
],
|
||||
properties: [
|
||||
"cppflags",
|
||||
],
|
||||
}
|
||||
|
||||
wifi_hal_cc_defaults {
|
||||
name: "android.hardware.wifi-service-cppflags-defaults",
|
||||
soong_config_variables: {
|
||||
hidl_feature_aware: {
|
||||
cppflags: ["-DWIFI_HIDL_FEATURE_AWARE"],
|
||||
},
|
||||
hidl_feature_dual_interface: {
|
||||
cppflags: ["-DWIFI_HIDL_FEATURE_DUAL_INTERFACE"],
|
||||
},
|
||||
hidl_feature_disable_ap: {
|
||||
cppflags: ["-DWIFI_HIDL_FEATURE_DISABLE_AP"],
|
||||
},
|
||||
hidl_feature_disable_ap_mac_randomization: {
|
||||
cppflags: ["-DWIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION"],
|
||||
},
|
||||
avoid_iface_reset_mac_change: {
|
||||
cppflags: ["-DWIFI_AVOID_IFACE_RESET_MAC_CHANGE"],
|
||||
},
|
||||
hal_interface_combinations: {
|
||||
cppflags: ["-DWIFI_HAL_INTERFACE_COMBINATIONS=%s"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cc_library_static {
|
||||
name: "android.hardware.wifi-service-lib",
|
||||
defaults: ["android.hardware.wifi-service-cppflags-defaults"],
|
||||
proprietary: true,
|
||||
compile_multilib: "first",
|
||||
cppflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wextra",
|
||||
],
|
||||
// Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed.
|
||||
cflags: ["-Wno-error=implicit-fallthrough"],
|
||||
srcs: [
|
||||
"aidl_struct_util.cpp",
|
||||
"aidl_sync_util.cpp",
|
||||
"ringbuffer.cpp",
|
||||
"wifi.cpp",
|
||||
"wifi_ap_iface.cpp",
|
||||
"wifi_chip.cpp",
|
||||
"wifi_feature_flags.cpp",
|
||||
"wifi_iface_util.cpp",
|
||||
"wifi_legacy_hal.cpp",
|
||||
"wifi_legacy_hal_factory.cpp",
|
||||
"wifi_legacy_hal_stubs.cpp",
|
||||
"wifi_mode_controller.cpp",
|
||||
"wifi_nan_iface.cpp",
|
||||
"wifi_p2p_iface.cpp",
|
||||
"wifi_rtt_controller.cpp",
|
||||
"wifi_sta_iface.cpp",
|
||||
"wifi_status_util.cpp",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libnl",
|
||||
"libutils",
|
||||
"libwifi-hal",
|
||||
"libwifi-system-iface",
|
||||
"libxml2",
|
||||
"android.hardware.wifi-V1-ndk",
|
||||
],
|
||||
|
||||
export_include_dirs: ["."],
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.wifi-service",
|
||||
vintf_fragments: ["android.hardware.wifi-service.xml"],
|
||||
relative_install_path: "hw",
|
||||
proprietary: true,
|
||||
cppflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wextra",
|
||||
],
|
||||
srcs: ["service.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libnl",
|
||||
"libutils",
|
||||
"libwifi-hal",
|
||||
"libwifi-system-iface",
|
||||
"libxml2",
|
||||
"android.hardware.wifi-V1-ndk",
|
||||
],
|
||||
static_libs: ["android.hardware.wifi-service-lib"],
|
||||
init_rc: ["android.hardware.wifi-service.rc"],
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.wifi-service-lazy",
|
||||
vintf_fragments: ["android.hardware.wifi-service.xml"],
|
||||
overrides: ["android.hardware.wifi-service"],
|
||||
cflags: ["-DLAZY_SERVICE"],
|
||||
relative_install_path: "hw",
|
||||
proprietary: true,
|
||||
cppflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wextra",
|
||||
],
|
||||
srcs: ["service.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libnl",
|
||||
"libutils",
|
||||
"libwifi-hal",
|
||||
"libwifi-system-iface",
|
||||
"libxml2",
|
||||
"android.hardware.wifi-V1-ndk",
|
||||
],
|
||||
static_libs: ["android.hardware.wifi-service-lib"],
|
||||
init_rc: ["android.hardware.wifi-service-lazy.rc"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "android.hardware.wifi-service-tests",
|
||||
proprietary: true,
|
||||
compile_multilib: "first",
|
||||
cppflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wextra",
|
||||
],
|
||||
srcs: [
|
||||
"tests/aidl_struct_util_unit_tests.cpp",
|
||||
"tests/main.cpp",
|
||||
"tests/mock_interface_tool.cpp",
|
||||
"tests/mock_wifi_feature_flags.cpp",
|
||||
"tests/mock_wifi_iface_util.cpp",
|
||||
"tests/mock_wifi_legacy_hal.cpp",
|
||||
"tests/mock_wifi_mode_controller.cpp",
|
||||
"tests/ringbuffer_unit_tests.cpp",
|
||||
"tests/wifi_nan_iface_unit_tests.cpp",
|
||||
"tests/wifi_chip_unit_tests.cpp",
|
||||
"tests/wifi_iface_util_unit_tests.cpp",
|
||||
],
|
||||
static_libs: [
|
||||
"libgmock",
|
||||
"libgtest",
|
||||
"android.hardware.wifi-V1-ndk",
|
||||
"android.hardware.wifi-service-lib",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libnl",
|
||||
"libutils",
|
||||
"libwifi-hal",
|
||||
"libwifi-system-iface",
|
||||
],
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "default-android.hardware.wifi-service.rc",
|
||||
srcs: ["android.hardware.wifi-service.rc"],
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "default-android.hardware.wifi-service.xml",
|
||||
srcs: ["android.hardware.wifi-service.xml"],
|
||||
}
|
||||
35
wifi/aidl/default/THREADING.README
Normal file
35
wifi/aidl/default/THREADING.README
Normal file
@@ -0,0 +1,35 @@
|
||||
Vendor HAL Threading Model
|
||||
==========================
|
||||
The vendor HAL service has two threads:
|
||||
1. AIDL thread: This is the main thread which processes all the incoming AIDL
|
||||
RPC's.
|
||||
2. Legacy HAL event loop thread: This is the thread forked off for processing
|
||||
the legacy HAL event loop (wifi_event_loop()). This thread is used to process
|
||||
any asynchronous netlink events posted by the driver. Any asynchronous
|
||||
callbacks passed to the legacy HAL API's are invoked on this thread.
|
||||
|
||||
Synchronization Concerns
|
||||
========================
|
||||
wifi_legacy_hal.cpp has a bunch of global "C" style functions to handle the
|
||||
legacy callbacks. Each of these "C" style functions invokes a corresponding
|
||||
"std::function" version of the callback which does the actual processing.
|
||||
The variables holding these "std::function" callbacks are reset from the AIDL
|
||||
thread when they are no longer used. For example: stopGscan() will reset the
|
||||
corresponding "on_gscan_*" callback variables which were set when startGscan()
|
||||
was invoked. This is not thread safe since these callback variables are
|
||||
accesed from the legacy hal event loop thread as well.
|
||||
|
||||
Synchronization Solution
|
||||
========================
|
||||
Adding a global lock seems to be the most trivial solution to the problem.
|
||||
a) All of the asynchronous "C" style callbacks will acquire the global lock
|
||||
before invoking the corresponding "std::function" callback variables.
|
||||
b) All of the AIDL methods will also acquire the global lock before processing
|
||||
(in aidl_return_util::validateAndCall()).
|
||||
|
||||
Note: It's important that we only acquire the global lock for asynchronous
|
||||
callbacks, because there is no guarantee (or documentation to clarify) that the
|
||||
synchronous callbacks are invoked on the same invocation thread. If that is not
|
||||
the case in some implementation, we will end up deadlocking the system since the
|
||||
AIDL thread would have acquired the global lock which is needed by the
|
||||
synchronous callback executed on the legacy hal event loop thread.
|
||||
140
wifi/aidl/default/aidl_callback_util.h
Normal file
140
wifi/aidl/default/aidl_callback_util.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef AIDL_CALLBACK_UTIL_H_
|
||||
#define AIDL_CALLBACK_UTIL_H_
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace {
|
||||
std::unordered_map<void* /* callback */, void* /* handler */> callback_handler_map_;
|
||||
}
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace aidl_callback_util {
|
||||
|
||||
// Provides a class to manage callbacks for the various AIDL interfaces and
|
||||
// handle the death of the process hosting each callback.
|
||||
template <typename CallbackType>
|
||||
class AidlCallbackHandler {
|
||||
public:
|
||||
AidlCallbackHandler() {
|
||||
death_handler_ = AIBinder_DeathRecipient_new(AidlCallbackHandler::onCallbackDeath);
|
||||
}
|
||||
~AidlCallbackHandler() { invalidate(); }
|
||||
|
||||
bool addCallback(const std::shared_ptr<CallbackType>& cb) {
|
||||
void* cbPtr = reinterpret_cast<void*>(cb->asBinder().get());
|
||||
const auto& cbPosition = findCbInSet(cbPtr);
|
||||
if (cbPosition != cb_set_.end()) {
|
||||
LOG(WARNING) << "Duplicate death notification registration";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (AIBinder_linkToDeath(cb->asBinder().get(), death_handler_, cbPtr /* cookie */) !=
|
||||
STATUS_OK) {
|
||||
LOG(ERROR) << "Failed to register death notification";
|
||||
return false;
|
||||
}
|
||||
|
||||
callback_handler_map_[cbPtr] = reinterpret_cast<void*>(this);
|
||||
cb_set_.insert(cb);
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::set<std::shared_ptr<CallbackType>>& getCallbacks() { return cb_set_; }
|
||||
|
||||
void invalidate() {
|
||||
for (auto cb : cb_set_) {
|
||||
void* cookie = reinterpret_cast<void*>(cb->asBinder().get());
|
||||
if (AIBinder_unlinkToDeath(cb->asBinder().get(), death_handler_, cookie) != STATUS_OK) {
|
||||
LOG(ERROR) << "Failed to deregister death notification";
|
||||
}
|
||||
if (!removeCbFromHandlerMap(cookie)) {
|
||||
LOG(ERROR) << "Failed to remove callback from handler map";
|
||||
}
|
||||
}
|
||||
cb_set_.clear();
|
||||
}
|
||||
|
||||
// Entry point for the death handling logic. AIBinder_DeathRecipient
|
||||
// can only call a static function, so use the cookie to find the
|
||||
// proper handler and route the request there.
|
||||
static void onCallbackDeath(void* cookie) {
|
||||
auto cbQuery = callback_handler_map_.find(cookie);
|
||||
if (cbQuery == callback_handler_map_.end()) {
|
||||
LOG(ERROR) << "Invalid death cookie received";
|
||||
return;
|
||||
}
|
||||
|
||||
AidlCallbackHandler* cbHandler = reinterpret_cast<AidlCallbackHandler*>(cbQuery->second);
|
||||
if (cbHandler == nullptr) {
|
||||
LOG(ERROR) << "Handler mapping contained an invalid handler";
|
||||
return;
|
||||
}
|
||||
cbHandler->handleCallbackDeath(cbQuery->first);
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<std::shared_ptr<CallbackType>> cb_set_;
|
||||
AIBinder_DeathRecipient* death_handler_;
|
||||
|
||||
typename std::set<std::shared_ptr<CallbackType>>::iterator findCbInSet(void* cbPtr) {
|
||||
const auto& cbPosition = std::find_if(
|
||||
cb_set_.begin(), cb_set_.end(), [cbPtr](const std::shared_ptr<CallbackType>& p) {
|
||||
return cbPtr == reinterpret_cast<void*>(p->asBinder().get());
|
||||
});
|
||||
return cbPosition;
|
||||
}
|
||||
|
||||
bool removeCbFromHandlerMap(void* cbPtr) {
|
||||
auto cbQuery = callback_handler_map_.find(cbPtr);
|
||||
if (cbQuery != callback_handler_map_.end()) {
|
||||
callback_handler_map_.erase(cbQuery);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void handleCallbackDeath(void* cbPtr) {
|
||||
const auto& cbPosition = findCbInSet(cbPtr);
|
||||
if (cbPosition == cb_set_.end()) {
|
||||
LOG(ERROR) << "Unknown callback death notification received";
|
||||
return;
|
||||
}
|
||||
cb_set_.erase(cbPosition);
|
||||
|
||||
if (!removeCbFromHandlerMap(cbPtr)) {
|
||||
LOG(ERROR) << "Callback was not in callback handler map";
|
||||
}
|
||||
}
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AidlCallbackHandler);
|
||||
};
|
||||
|
||||
} // namespace aidl_callback_util
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // AIDL_CALLBACK_UTIL_H_
|
||||
85
wifi/aidl/default/aidl_return_util.h
Normal file
85
wifi/aidl/default/aidl_return_util.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef AIDL_RETURN_UTIL_H_
|
||||
#define AIDL_RETURN_UTIL_H_
|
||||
|
||||
#include "aidl_sync_util.h"
|
||||
#include "wifi_status_util.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace aidl_return_util {
|
||||
using aidl::android::hardware::wifi::WifiStatusCode;
|
||||
using aidl::android::hardware::wifi::aidl_sync_util::acquireGlobalLock;
|
||||
|
||||
/**
|
||||
* These utility functions are used to invoke a method on the provided
|
||||
* AIDL interface object.
|
||||
* These functions checks if the provided AIDL interface object is valid.
|
||||
* a) If valid, Invokes the corresponding internal implementation function of
|
||||
* the AIDL method.
|
||||
* b) If invalid, return without calling the internal implementation function.
|
||||
*/
|
||||
|
||||
// Use for AIDL methods which return only an AIDL status.
|
||||
template <typename ObjT, typename WorkFuncT, typename... Args>
|
||||
::ndk::ScopedAStatus validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid,
|
||||
WorkFuncT&& work, Args&&... args) {
|
||||
const auto lock = acquireGlobalLock();
|
||||
if (obj->isValid()) {
|
||||
return (obj->*work)(std::forward<Args>(args)...);
|
||||
} else {
|
||||
return createWifiStatus(status_code_if_invalid);
|
||||
}
|
||||
}
|
||||
|
||||
// Use for AIDL methods which return only an AIDL status.
|
||||
// This version passes the global lock acquired to the body of the method.
|
||||
template <typename ObjT, typename WorkFuncT, typename... Args>
|
||||
::ndk::ScopedAStatus validateAndCallWithLock(ObjT* obj, WifiStatusCode status_code_if_invalid,
|
||||
WorkFuncT&& work, Args&&... args) {
|
||||
auto lock = acquireGlobalLock();
|
||||
if (obj->isValid()) {
|
||||
return (obj->*work)(&lock, std::forward<Args>(args)...);
|
||||
} else {
|
||||
return createWifiStatus(status_code_if_invalid);
|
||||
}
|
||||
}
|
||||
|
||||
// Use for AIDL methods which have a return value along with the AIDL status
|
||||
template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
|
||||
::ndk::ScopedAStatus validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid,
|
||||
WorkFuncT&& work, ReturnT* ret_val, Args&&... args) {
|
||||
const auto lock = acquireGlobalLock();
|
||||
if (obj->isValid()) {
|
||||
auto call_pair = (obj->*work)(std::forward<Args>(args)...);
|
||||
*ret_val = call_pair.first;
|
||||
return std::forward<::ndk::ScopedAStatus>(call_pair.second);
|
||||
} else {
|
||||
return ndk::ScopedAStatus::fromServiceSpecificError(
|
||||
static_cast<int32_t>(status_code_if_invalid));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace aidl_return_util
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
#endif // AIDL_RETURN_UTIL_H_
|
||||
2775
wifi/aidl/default/aidl_struct_util.cpp
Normal file
2775
wifi/aidl/default/aidl_struct_util.cpp
Normal file
File diff suppressed because it is too large
Load Diff
180
wifi/aidl/default/aidl_struct_util.h
Normal file
180
wifi/aidl/default/aidl_struct_util.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef AIDL_STRUCT_UTIL_H_
|
||||
#define AIDL_STRUCT_UTIL_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/IWifiChip.h>
|
||||
#include <aidl/android/hardware/wifi/IWifiChipEventCallback.h>
|
||||
#include <aidl/android/hardware/wifi/NanBandIndex.h>
|
||||
#include <aidl/android/hardware/wifi/WifiDebugRingBufferFlags.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
/**
|
||||
* This file contains a bunch of functions to convert structs from the legacy
|
||||
* HAL to AIDL and vice versa.
|
||||
*/
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace aidl_struct_util {
|
||||
|
||||
// Chip conversion methods.
|
||||
bool convertLegacyFeaturesToAidlChipCapabilities(uint64_t legacy_feature_set,
|
||||
uint32_t legacy_logger_feature_set,
|
||||
uint32_t* aidl_caps);
|
||||
bool convertLegacyDebugRingBufferStatusToAidl(
|
||||
const legacy_hal::wifi_ring_buffer_status& legacy_status,
|
||||
WifiDebugRingBufferStatus* aidl_status);
|
||||
bool convertLegacyVectorOfDebugRingBufferStatusToAidl(
|
||||
const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
|
||||
std::vector<WifiDebugRingBufferStatus>* aidl_status_vec);
|
||||
bool convertLegacyWakeReasonStatsToAidl(const legacy_hal::WakeReasonStats& legacy_stats,
|
||||
WifiDebugHostWakeReasonStats* aidl_stats);
|
||||
legacy_hal::wifi_power_scenario convertAidlTxPowerScenarioToLegacy(
|
||||
IWifiChip::TxPowerScenario aidl_scenario);
|
||||
legacy_hal::wifi_latency_mode convertAidlLatencyModeToLegacy(
|
||||
IWifiChip::LatencyMode aidl_latency_mode);
|
||||
bool convertLegacyWifiMacInfosToAidl(
|
||||
const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
|
||||
std::vector<IWifiChipEventCallback::RadioModeInfo>* aidl_radio_mode_infos);
|
||||
legacy_hal::wifi_interface_type convertAidlIfaceTypeToLegacy(IfaceType aidl_interface_type);
|
||||
legacy_hal::wifi_multi_sta_use_case convertAidlMultiStaUseCaseToLegacy(
|
||||
IWifiChip::MultiStaUseCase use_case);
|
||||
bool convertAidlCoexUnsafeChannelToLegacy(
|
||||
const IWifiChip::CoexUnsafeChannel& aidl_unsafe_channel,
|
||||
legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel);
|
||||
bool convertAidlVectorOfCoexUnsafeChannelToLegacy(
|
||||
const std::vector<IWifiChip::CoexUnsafeChannel>& aidl_unsafe_channels,
|
||||
std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels);
|
||||
bool convertLegacyRadioCombinationsMatrixToAidl(
|
||||
legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
|
||||
WifiRadioCombinationMatrix* aidl_matrix);
|
||||
WifiBand convertLegacyMacBandToAidlWifiBand(uint32_t band);
|
||||
WifiAntennaMode convertLegacyAntennaConfigurationToAidl(uint32_t antenna_cfg);
|
||||
|
||||
// STA iface conversion methods.
|
||||
bool convertLegacyFeaturesToAidlStaCapabilities(uint64_t legacy_feature_set,
|
||||
uint32_t legacy_logger_feature_set,
|
||||
uint32_t* aidl_caps);
|
||||
bool convertLegacyApfCapabilitiesToAidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
|
||||
StaApfPacketFilterCapabilities* aidl_caps);
|
||||
bool convertLegacyGscanCapabilitiesToAidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
|
||||
StaBackgroundScanCapabilities* aidl_caps);
|
||||
legacy_hal::wifi_band convertAidlWifiBandToLegacy(WifiBand band);
|
||||
bool convertAidlGscanParamsToLegacy(const StaBackgroundScanParameters& aidl_scan_params,
|
||||
legacy_hal::wifi_scan_cmd_params* legacy_scan_params);
|
||||
// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11
|
||||
// Information Elements (IEs)
|
||||
bool convertLegacyGscanResultToAidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
|
||||
bool has_ie_data, StaScanResult* aidl_scan_result);
|
||||
// |cached_results| is assumed to not include IEs.
|
||||
bool convertLegacyVectorOfCachedGscanResultsToAidl(
|
||||
const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
|
||||
std::vector<StaScanData>* aidl_scan_datas);
|
||||
bool convertLegacyLinkLayerStatsToAidl(const legacy_hal::LinkLayerStats& legacy_stats,
|
||||
StaLinkLayerStats* aidl_stats);
|
||||
bool convertLegacyRoamingCapabilitiesToAidl(
|
||||
const legacy_hal::wifi_roaming_capabilities& legacy_caps,
|
||||
StaRoamingCapabilities* aidl_caps);
|
||||
bool convertAidlRoamingConfigToLegacy(const StaRoamingConfig& aidl_config,
|
||||
legacy_hal::wifi_roaming_config* legacy_config);
|
||||
legacy_hal::fw_roaming_state_t convertAidlRoamingStateToLegacy(StaRoamingState state);
|
||||
bool convertLegacyVectorOfDebugTxPacketFateToAidl(
|
||||
const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
|
||||
std::vector<WifiDebugTxPacketFateReport>* aidl_fates);
|
||||
bool convertLegacyVectorOfDebugRxPacketFateToAidl(
|
||||
const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
|
||||
std::vector<WifiDebugRxPacketFateReport>* aidl_fates);
|
||||
|
||||
// NAN iface conversion methods.
|
||||
void convertToNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
|
||||
NanStatus* nanStatus);
|
||||
bool convertAidlNanEnableRequestToLegacy(const NanEnableRequest& aidl_request1,
|
||||
const NanConfigRequestSupplemental& aidl_request2,
|
||||
legacy_hal::NanEnableRequest* legacy_request);
|
||||
bool convertAidlNanConfigRequestToLegacy(const NanConfigRequest& aidl_request1,
|
||||
const NanConfigRequestSupplemental& aidl_request2,
|
||||
legacy_hal::NanConfigRequest* legacy_request);
|
||||
bool convertAidlNanPublishRequestToLegacy(const NanPublishRequest& aidl_request,
|
||||
legacy_hal::NanPublishRequest* legacy_request);
|
||||
bool convertAidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& aidl_request,
|
||||
legacy_hal::NanSubscribeRequest* legacy_request);
|
||||
bool convertAidlNanTransmitFollowupRequestToLegacy(
|
||||
const NanTransmitFollowupRequest& aidl_request,
|
||||
legacy_hal::NanTransmitFollowupRequest* legacy_request);
|
||||
bool convertAidlNanDataPathInitiatorRequestToLegacy(
|
||||
const NanInitiateDataPathRequest& aidl_request,
|
||||
legacy_hal::NanDataPathInitiatorRequest* legacy_request);
|
||||
bool convertAidlNanDataPathIndicationResponseToLegacy(
|
||||
const NanRespondToDataPathIndicationRequest& aidl_response,
|
||||
legacy_hal::NanDataPathIndicationResponse* legacy_response);
|
||||
bool convertLegacyNanResponseHeaderToAidl(const legacy_hal::NanResponseMsg& legacy_response,
|
||||
NanStatus* nanStatus);
|
||||
bool convertLegacyNanCapabilitiesResponseToAidl(const legacy_hal::NanCapabilities& legacy_response,
|
||||
NanCapabilities* aidl_response);
|
||||
bool convertLegacyNanMatchIndToAidl(const legacy_hal::NanMatchInd& legacy_ind,
|
||||
NanMatchInd* aidl_ind);
|
||||
bool convertLegacyNanFollowupIndToAidl(const legacy_hal::NanFollowupInd& legacy_ind,
|
||||
NanFollowupReceivedInd* aidl_ind);
|
||||
bool convertLegacyNanDataPathRequestIndToAidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
|
||||
NanDataPathRequestInd* aidl_ind);
|
||||
bool convertLegacyNanDataPathConfirmIndToAidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
|
||||
NanDataPathConfirmInd* aidl_ind);
|
||||
bool convertLegacyNanDataPathScheduleUpdateIndToAidl(
|
||||
const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
|
||||
NanDataPathScheduleUpdateInd* aidl_ind);
|
||||
|
||||
// RTT controller conversion methods.
|
||||
bool convertAidlVectorOfRttConfigToLegacy(const std::vector<RttConfig>& aidl_configs,
|
||||
std::vector<legacy_hal::wifi_rtt_config>* legacy_configs);
|
||||
bool convertAidlRttLciInformationToLegacy(const RttLciInformation& aidl_info,
|
||||
legacy_hal::wifi_lci_information* legacy_info);
|
||||
bool convertAidlRttLcrInformationToLegacy(const RttLcrInformation& aidl_info,
|
||||
legacy_hal::wifi_lcr_information* legacy_info);
|
||||
bool convertAidlRttResponderToLegacy(const RttResponder& aidl_responder,
|
||||
legacy_hal::wifi_rtt_responder* legacy_responder);
|
||||
bool convertAidlWifiChannelInfoToLegacy(const WifiChannelInfo& aidl_info,
|
||||
legacy_hal::wifi_channel_info* legacy_info);
|
||||
bool convertLegacyRttResponderToAidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
|
||||
RttResponder* aidl_responder);
|
||||
bool convertLegacyRttCapabilitiesToAidl(
|
||||
const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
|
||||
RttCapabilities* aidl_capabilities);
|
||||
bool convertLegacyVectorOfRttResultToAidl(
|
||||
const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
|
||||
std::vector<RttResult>* aidl_results);
|
||||
uint32_t convertAidlWifiBandToLegacyMacBand(WifiBand band);
|
||||
uint32_t convertAidlWifiIfaceModeToLegacy(uint32_t aidl_iface_mask);
|
||||
uint32_t convertAidlUsableChannelFilterToLegacy(uint32_t aidl_filter_mask);
|
||||
bool convertLegacyWifiUsableChannelsToAidl(
|
||||
const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
|
||||
std::vector<WifiUsableChannel>* aidl_usable_channels);
|
||||
bool convertLegacyPeerInfoStatsToAidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
|
||||
StaPeerInfo* aidl_peer_info_stats);
|
||||
bool convertLegacyWifiRateInfoToAidl(const legacy_hal::wifi_rate& legacy_rate,
|
||||
WifiRateInfo* aidl_rate);
|
||||
} // namespace aidl_struct_util
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // AIDL_STRUCT_UTIL_H_
|
||||
37
wifi/aidl/default/aidl_sync_util.cpp
Normal file
37
wifi/aidl/default/aidl_sync_util.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "aidl_sync_util.h"
|
||||
|
||||
namespace {
|
||||
std::recursive_mutex g_mutex;
|
||||
} // namespace
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace aidl_sync_util {
|
||||
|
||||
std::unique_lock<std::recursive_mutex> acquireGlobalLock() {
|
||||
return std::unique_lock<std::recursive_mutex>{g_mutex};
|
||||
}
|
||||
|
||||
} // namespace aidl_sync_util
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
35
wifi/aidl/default/aidl_sync_util.h
Normal file
35
wifi/aidl/default/aidl_sync_util.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef AIDL_SYNC_UTIL_H_
|
||||
#define AIDL_SYNC_UTIL_H_
|
||||
|
||||
#include <mutex>
|
||||
|
||||
// Utility that provides a global lock to synchronize access between
|
||||
// the AIDL thread and the legacy HAL's event loop.
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace aidl_sync_util {
|
||||
std::unique_lock<std::recursive_mutex> acquireGlobalLock();
|
||||
} // namespace aidl_sync_util
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
#endif // AIDL_SYNC_UTIL_H_
|
||||
8
wifi/aidl/default/android.hardware.wifi-service-lazy.rc
Normal file
8
wifi/aidl/default/android.hardware.wifi-service-lazy.rc
Normal file
@@ -0,0 +1,8 @@
|
||||
service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi-service-lazy
|
||||
interface aidl android.hardware.wifi.IWifi/default
|
||||
oneshot
|
||||
disabled
|
||||
class hal
|
||||
capabilities NET_ADMIN NET_RAW SYS_MODULE
|
||||
user wifi
|
||||
group wifi gps
|
||||
6
wifi/aidl/default/android.hardware.wifi-service.rc
Normal file
6
wifi/aidl/default/android.hardware.wifi-service.rc
Normal file
@@ -0,0 +1,6 @@
|
||||
service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi-service
|
||||
interface aidl android.hardware.wifi.IWifi/default
|
||||
class hal
|
||||
capabilities NET_ADMIN NET_RAW SYS_MODULE
|
||||
user wifi
|
||||
group wifi gps
|
||||
6
wifi/aidl/default/android.hardware.wifi-service.xml
Normal file
6
wifi/aidl/default/android.hardware.wifi-service.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.wifi</name>
|
||||
<fqname>IWifi/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
||||
62
wifi/aidl/default/ringbuffer.cpp
Normal file
62
wifi/aidl/default/ringbuffer.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "ringbuffer.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {}
|
||||
|
||||
enum Ringbuffer::AppendStatus Ringbuffer::append(const std::vector<uint8_t>& input) {
|
||||
if (input.size() == 0) {
|
||||
return AppendStatus::FAIL_IP_BUFFER_ZERO;
|
||||
}
|
||||
if (input.size() > maxSize_) {
|
||||
LOG(INFO) << "Oversized message of " << input.size() << " bytes is dropped";
|
||||
return AppendStatus::FAIL_IP_BUFFER_EXCEEDED_MAXSIZE;
|
||||
}
|
||||
data_.push_back(input);
|
||||
size_ += input.size() * sizeof(input[0]);
|
||||
while (size_ > maxSize_) {
|
||||
if (data_.front().size() <= 0 || data_.front().size() > maxSize_) {
|
||||
LOG(ERROR) << "First buffer in the ring buffer is Invalid. Size: "
|
||||
<< data_.front().size();
|
||||
return AppendStatus::FAIL_RING_BUFFER_CORRUPTED;
|
||||
}
|
||||
size_ -= data_.front().size() * sizeof(data_.front()[0]);
|
||||
data_.pop_front();
|
||||
}
|
||||
return AppendStatus::SUCCESS;
|
||||
}
|
||||
|
||||
const std::list<std::vector<uint8_t>>& Ringbuffer::getData() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
void Ringbuffer::clear() {
|
||||
data_.clear();
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
60
wifi/aidl/default/ringbuffer.h
Normal file
60
wifi/aidl/default/ringbuffer.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef RINGBUFFER_H_
|
||||
#define RINGBUFFER_H_
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
/**
|
||||
* Ringbuffer object used to store debug data.
|
||||
*/
|
||||
class Ringbuffer {
|
||||
public:
|
||||
// Error codes for the append ring buffer operation
|
||||
enum AppendStatus {
|
||||
SUCCESS,
|
||||
FAIL_GENERIC,
|
||||
FAIL_IP_BUFFER_ZERO,
|
||||
FAIL_IP_BUFFER_EXCEEDED_MAXSIZE,
|
||||
FAIL_RING_BUFFER_CORRUPTED
|
||||
};
|
||||
explicit Ringbuffer(size_t maxSize);
|
||||
|
||||
// Appends the data buffer and deletes from the front until buffer is
|
||||
// within |maxSize_|.
|
||||
enum AppendStatus append(const std::vector<uint8_t>& input);
|
||||
const std::list<std::vector<uint8_t>>& getData() const;
|
||||
void clear();
|
||||
|
||||
private:
|
||||
std::list<std::vector<uint8_t>> data_;
|
||||
size_t size_;
|
||||
size_t maxSize_;
|
||||
};
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // RINGBUFFER_H_
|
||||
73
wifi/aidl/default/service.cpp
Normal file
73
wifi/aidl/default/service.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "wifi.h"
|
||||
#include "wifi_feature_flags.h"
|
||||
#include "wifi_legacy_hal.h"
|
||||
#include "wifi_legacy_hal_factory.h"
|
||||
#include "wifi_mode_controller.h"
|
||||
|
||||
using aidl::android::hardware::wifi::feature_flags::WifiFeatureFlags;
|
||||
using aidl::android::hardware::wifi::legacy_hal::WifiLegacyHal;
|
||||
using aidl::android::hardware::wifi::legacy_hal::WifiLegacyHalFactory;
|
||||
using aidl::android::hardware::wifi::mode_controller::WifiModeController;
|
||||
|
||||
#ifdef LAZY_SERVICE
|
||||
const bool kLazyService = true;
|
||||
#else
|
||||
const bool kLazyService = false;
|
||||
#endif
|
||||
|
||||
int main(int /*argc*/, char** argv) {
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
|
||||
LOG(INFO) << "Wifi Hal is booting up...";
|
||||
|
||||
// Prepare the RPC-serving thread pool. Allocate 1 thread in the pool,
|
||||
// which our main thread will join below.
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(1);
|
||||
|
||||
const auto iface_tool = std::make_shared<::android::wifi_system::InterfaceTool>();
|
||||
const auto legacy_hal_factory = std::make_shared<WifiLegacyHalFactory>(iface_tool);
|
||||
|
||||
// Setup binder service
|
||||
std::shared_ptr<aidl::android::hardware::wifi::Wifi> service =
|
||||
ndk::SharedRefBase::make<aidl::android::hardware::wifi::Wifi>(
|
||||
iface_tool, legacy_hal_factory, std::make_shared<WifiModeController>(),
|
||||
std::make_shared<WifiFeatureFlags>());
|
||||
std::string instance =
|
||||
std::string() + aidl::android::hardware::wifi::Wifi::descriptor + "/default";
|
||||
if (kLazyService) {
|
||||
auto result =
|
||||
AServiceManager_registerLazyService(service->asBinder().get(), instance.c_str());
|
||||
CHECK_EQ(result, STATUS_OK) << "Failed to register lazy wifi HAL";
|
||||
} else {
|
||||
auto result = AServiceManager_addService(service->asBinder().get(), instance.c_str());
|
||||
CHECK_EQ(result, STATUS_OK) << "Failed to register wifi HAL";
|
||||
}
|
||||
|
||||
ABinderProcess_startThreadPool();
|
||||
LOG(INFO) << "Joining RPC thread pool";
|
||||
ABinderProcess_joinThreadPool();
|
||||
|
||||
LOG(INFO) << "Wifi Hal is terminating...";
|
||||
return 0;
|
||||
}
|
||||
485
wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
Normal file
485
wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
Normal file
@@ -0,0 +1,485 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "aidl_struct_util.h"
|
||||
|
||||
using testing::Test;
|
||||
|
||||
namespace {
|
||||
constexpr uint32_t kMacId1 = 1;
|
||||
constexpr uint32_t kMacId2 = 2;
|
||||
constexpr uint32_t kIfaceChannel1 = 3;
|
||||
constexpr uint32_t kIfaceChannel2 = 5;
|
||||
constexpr char kIfaceName1[] = "wlan0";
|
||||
constexpr char kIfaceName2[] = "wlan1";
|
||||
} // namespace
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
class AidlStructUtilTest : public Test {};
|
||||
|
||||
TEST_F(AidlStructUtilTest, CanConvertLegacyWifiMacInfosToAidlWithOneMac) {
|
||||
std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
|
||||
legacy_hal::WifiMacInfo legacy_mac_info1 = {
|
||||
.wlan_mac_id = kMacId1,
|
||||
.mac_band = legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND};
|
||||
legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1};
|
||||
legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2};
|
||||
legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
|
||||
legacy_mac_info1.iface_infos.push_back(legacy_iface_info2);
|
||||
legacy_mac_infos.push_back(legacy_mac_info1);
|
||||
|
||||
std::vector<IWifiChipEventCallback::RadioModeInfo> aidl_radio_mode_infos;
|
||||
ASSERT_TRUE(aidl_struct_util::convertLegacyWifiMacInfosToAidl(legacy_mac_infos,
|
||||
&aidl_radio_mode_infos));
|
||||
|
||||
ASSERT_EQ(1u, aidl_radio_mode_infos.size());
|
||||
auto aidl_radio_mode_info1 = aidl_radio_mode_infos[0];
|
||||
EXPECT_EQ(legacy_mac_info1.wlan_mac_id, (uint32_t)aidl_radio_mode_info1.radioId);
|
||||
EXPECT_EQ(WifiBand::BAND_24GHZ_5GHZ, aidl_radio_mode_info1.bandInfo);
|
||||
ASSERT_EQ(2u, aidl_radio_mode_info1.ifaceInfos.size());
|
||||
auto aidl_iface_info1 = aidl_radio_mode_info1.ifaceInfos[0];
|
||||
EXPECT_EQ(legacy_iface_info1.name, aidl_iface_info1.name);
|
||||
EXPECT_EQ(static_cast<int32_t>(legacy_iface_info1.channel), aidl_iface_info1.channel);
|
||||
auto aidl_iface_info2 = aidl_radio_mode_info1.ifaceInfos[1];
|
||||
EXPECT_EQ(legacy_iface_info2.name, aidl_iface_info2.name);
|
||||
EXPECT_EQ(static_cast<int32_t>(legacy_iface_info2.channel), aidl_iface_info2.channel);
|
||||
}
|
||||
|
||||
TEST_F(AidlStructUtilTest, CanConvertLegacyWifiMacInfosToAidlWithTwoMac) {
|
||||
std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
|
||||
legacy_hal::WifiMacInfo legacy_mac_info1 = {.wlan_mac_id = kMacId1,
|
||||
.mac_band = legacy_hal::WLAN_MAC_5_0_BAND};
|
||||
legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1};
|
||||
legacy_hal::WifiMacInfo legacy_mac_info2 = {.wlan_mac_id = kMacId2,
|
||||
.mac_band = legacy_hal::WLAN_MAC_2_4_BAND};
|
||||
legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2};
|
||||
legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
|
||||
legacy_mac_infos.push_back(legacy_mac_info1);
|
||||
legacy_mac_info2.iface_infos.push_back(legacy_iface_info2);
|
||||
legacy_mac_infos.push_back(legacy_mac_info2);
|
||||
|
||||
std::vector<IWifiChipEventCallback::RadioModeInfo> aidl_radio_mode_infos;
|
||||
ASSERT_TRUE(aidl_struct_util::convertLegacyWifiMacInfosToAidl(legacy_mac_infos,
|
||||
&aidl_radio_mode_infos));
|
||||
|
||||
ASSERT_EQ(2u, aidl_radio_mode_infos.size());
|
||||
|
||||
// Find mac info 1.
|
||||
const auto aidl_radio_mode_info1 =
|
||||
std::find_if(aidl_radio_mode_infos.begin(), aidl_radio_mode_infos.end(),
|
||||
[&legacy_mac_info1](const IWifiChipEventCallback::RadioModeInfo& x) {
|
||||
return (uint32_t)x.radioId == legacy_mac_info1.wlan_mac_id;
|
||||
});
|
||||
ASSERT_NE(aidl_radio_mode_infos.end(), aidl_radio_mode_info1);
|
||||
EXPECT_EQ(WifiBand::BAND_5GHZ, aidl_radio_mode_info1->bandInfo);
|
||||
ASSERT_EQ(1u, aidl_radio_mode_info1->ifaceInfos.size());
|
||||
auto aidl_iface_info1 = aidl_radio_mode_info1->ifaceInfos[0];
|
||||
EXPECT_EQ(legacy_iface_info1.name, aidl_iface_info1.name);
|
||||
EXPECT_EQ(static_cast<int32_t>(legacy_iface_info1.channel), aidl_iface_info1.channel);
|
||||
|
||||
// Find mac info 2.
|
||||
const auto aidl_radio_mode_info2 =
|
||||
std::find_if(aidl_radio_mode_infos.begin(), aidl_radio_mode_infos.end(),
|
||||
[&legacy_mac_info2](const IWifiChipEventCallback::RadioModeInfo& x) {
|
||||
return (uint32_t)x.radioId == legacy_mac_info2.wlan_mac_id;
|
||||
});
|
||||
ASSERT_NE(aidl_radio_mode_infos.end(), aidl_radio_mode_info2);
|
||||
EXPECT_EQ(WifiBand::BAND_24GHZ, aidl_radio_mode_info2->bandInfo);
|
||||
ASSERT_EQ(1u, aidl_radio_mode_info2->ifaceInfos.size());
|
||||
auto aidl_iface_info2 = aidl_radio_mode_info2->ifaceInfos[0];
|
||||
EXPECT_EQ(legacy_iface_info2.name, aidl_iface_info2.name);
|
||||
EXPECT_EQ(static_cast<int32_t>(legacy_iface_info2.channel), aidl_iface_info2.channel);
|
||||
}
|
||||
|
||||
TEST_F(AidlStructUtilTest, canConvertLegacyLinkLayerStatsToAidl) {
|
||||
legacy_hal::LinkLayerStats legacy_stats{};
|
||||
legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
|
||||
legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
|
||||
legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{});
|
||||
legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{});
|
||||
legacy_stats.iface.beacon_rx = rand();
|
||||
legacy_stats.iface.rssi_mgmt = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = rand();
|
||||
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = rand();
|
||||
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = rand();
|
||||
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = rand();
|
||||
|
||||
legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand();
|
||||
legacy_stats.iface.num_peers = 1;
|
||||
|
||||
for (auto& radio : legacy_stats.radios) {
|
||||
radio.stats.radio = rand();
|
||||
radio.stats.on_time = rand();
|
||||
radio.stats.tx_time = rand();
|
||||
radio.stats.rx_time = rand();
|
||||
radio.stats.on_time_scan = rand();
|
||||
radio.stats.on_time_nbd = rand();
|
||||
radio.stats.on_time_gscan = rand();
|
||||
radio.stats.on_time_roam_scan = rand();
|
||||
radio.stats.on_time_pno_scan = rand();
|
||||
radio.stats.on_time_hs20 = rand();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
radio.tx_time_per_levels.push_back(rand());
|
||||
}
|
||||
|
||||
legacy_hal::wifi_channel_stat channel_stat1 = {
|
||||
.channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
|
||||
.on_time = 0x1111,
|
||||
.cca_busy_time = 0x55,
|
||||
};
|
||||
legacy_hal::wifi_channel_stat channel_stat2 = {
|
||||
.channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
|
||||
.on_time = 0x2222,
|
||||
.cca_busy_time = 0x66,
|
||||
};
|
||||
radio.channel_stats.push_back(channel_stat1);
|
||||
radio.channel_stats.push_back(channel_stat2);
|
||||
}
|
||||
|
||||
for (auto& peer : legacy_stats.peers) {
|
||||
peer.peer_info.bssload.sta_count = rand();
|
||||
peer.peer_info.bssload.chan_util = rand();
|
||||
wifi_rate_stat rate_stat1 = {
|
||||
.rate = {3, 1, 2, 5, 0, 0},
|
||||
.tx_mpdu = 0,
|
||||
.rx_mpdu = 1,
|
||||
.mpdu_lost = 2,
|
||||
.retries = 3,
|
||||
.retries_short = 4,
|
||||
.retries_long = 5,
|
||||
};
|
||||
wifi_rate_stat rate_stat2 = {
|
||||
.rate = {2, 2, 1, 6, 0, 1},
|
||||
.tx_mpdu = 6,
|
||||
.rx_mpdu = 7,
|
||||
.mpdu_lost = 8,
|
||||
.retries = 9,
|
||||
.retries_short = 10,
|
||||
.retries_long = 11,
|
||||
};
|
||||
peer.rate_stats.push_back(rate_stat1);
|
||||
peer.rate_stats.push_back(rate_stat2);
|
||||
}
|
||||
|
||||
StaLinkLayerStats converted{};
|
||||
aidl_struct_util::convertLegacyLinkLayerStatsToAidl(legacy_stats, &converted);
|
||||
EXPECT_EQ(legacy_stats.iface.beacon_rx, (uint32_t)converted.iface.beaconRx);
|
||||
EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.avgRssiMgmt);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
|
||||
converted.iface.wmeBePktStats.rxMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu,
|
||||
converted.iface.wmeBePktStats.txMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost,
|
||||
converted.iface.wmeBePktStats.lostMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries,
|
||||
converted.iface.wmeBePktStats.retries);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min,
|
||||
(uint32_t)converted.iface.wmeBeContentionTimeStats.contentionTimeMinInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max,
|
||||
(uint32_t)converted.iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg,
|
||||
(uint32_t)converted.iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples,
|
||||
(uint32_t)converted.iface.wmeBeContentionTimeStats.contentionNumSamples);
|
||||
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
|
||||
converted.iface.wmeBkPktStats.rxMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu,
|
||||
converted.iface.wmeBkPktStats.txMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost,
|
||||
converted.iface.wmeBkPktStats.lostMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries,
|
||||
converted.iface.wmeBkPktStats.retries);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min,
|
||||
(uint32_t)converted.iface.wmeBkContentionTimeStats.contentionTimeMinInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max,
|
||||
(uint32_t)converted.iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg,
|
||||
(uint32_t)converted.iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples,
|
||||
(uint32_t)converted.iface.wmeBkContentionTimeStats.contentionNumSamples);
|
||||
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
|
||||
converted.iface.wmeViPktStats.rxMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu,
|
||||
converted.iface.wmeViPktStats.txMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost,
|
||||
converted.iface.wmeViPktStats.lostMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries,
|
||||
converted.iface.wmeViPktStats.retries);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min,
|
||||
(uint32_t)converted.iface.wmeViContentionTimeStats.contentionTimeMinInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max,
|
||||
(uint32_t)converted.iface.wmeViContentionTimeStats.contentionTimeMaxInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg,
|
||||
(uint32_t)converted.iface.wmeViContentionTimeStats.contentionTimeAvgInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples,
|
||||
(uint32_t)converted.iface.wmeViContentionTimeStats.contentionNumSamples);
|
||||
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
|
||||
converted.iface.wmeVoPktStats.rxMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu,
|
||||
converted.iface.wmeVoPktStats.txMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost,
|
||||
converted.iface.wmeVoPktStats.lostMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries,
|
||||
converted.iface.wmeVoPktStats.retries);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min,
|
||||
(uint32_t)converted.iface.wmeVoContentionTimeStats.contentionTimeMinInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max,
|
||||
(uint32_t)converted.iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg,
|
||||
(uint32_t)converted.iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples,
|
||||
(uint32_t)converted.iface.wmeVoContentionTimeStats.contentionNumSamples);
|
||||
|
||||
EXPECT_EQ(legacy_stats.iface.info.time_slicing_duty_cycle_percent,
|
||||
converted.iface.timeSliceDutyCycleInPercent);
|
||||
|
||||
EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size());
|
||||
for (size_t i = 0; i < legacy_stats.radios.size(); i++) {
|
||||
EXPECT_EQ(legacy_stats.radios[i].stats.radio, converted.radios[i].radioId);
|
||||
EXPECT_EQ(legacy_stats.radios[i].stats.on_time, (uint32_t)converted.radios[i].onTimeInMs);
|
||||
EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, (uint32_t)converted.radios[i].txTimeInMs);
|
||||
EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, (uint32_t)converted.radios[i].rxTimeInMs);
|
||||
EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan,
|
||||
(uint32_t)converted.radios[i].onTimeInMsForScan);
|
||||
EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(),
|
||||
converted.radios[i].txTimeInMsPerLevel.size());
|
||||
for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); j++) {
|
||||
EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j],
|
||||
(uint32_t)converted.radios[i].txTimeInMsPerLevel[j]);
|
||||
}
|
||||
EXPECT_EQ(legacy_stats.radios[i].stats.on_time_nbd,
|
||||
(uint32_t)converted.radios[i].onTimeInMsForNanScan);
|
||||
EXPECT_EQ(legacy_stats.radios[i].stats.on_time_gscan,
|
||||
(uint32_t)converted.radios[i].onTimeInMsForBgScan);
|
||||
EXPECT_EQ(legacy_stats.radios[i].stats.on_time_roam_scan,
|
||||
(uint32_t)converted.radios[i].onTimeInMsForRoamScan);
|
||||
EXPECT_EQ(legacy_stats.radios[i].stats.on_time_pno_scan,
|
||||
(uint32_t)converted.radios[i].onTimeInMsForPnoScan);
|
||||
EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20,
|
||||
(uint32_t)converted.radios[i].onTimeInMsForHs20Scan);
|
||||
EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(),
|
||||
converted.radios[i].channelStats.size());
|
||||
for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size(); k++) {
|
||||
auto& legacy_channel_st = legacy_stats.radios[i].channel_stats[k];
|
||||
EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20,
|
||||
converted.radios[i].channelStats[k].channel.width);
|
||||
EXPECT_EQ(legacy_channel_st.channel.center_freq,
|
||||
converted.radios[i].channelStats[k].channel.centerFreq);
|
||||
EXPECT_EQ(legacy_channel_st.channel.center_freq0,
|
||||
converted.radios[i].channelStats[k].channel.centerFreq0);
|
||||
EXPECT_EQ(legacy_channel_st.channel.center_freq1,
|
||||
converted.radios[i].channelStats[k].channel.centerFreq1);
|
||||
EXPECT_EQ(legacy_channel_st.cca_busy_time,
|
||||
(uint32_t)converted.radios[i].channelStats[k].ccaBusyTimeInMs);
|
||||
EXPECT_EQ(legacy_channel_st.on_time,
|
||||
(uint32_t)converted.radios[i].channelStats[k].onTimeInMs);
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(legacy_stats.peers.size(), converted.iface.peers.size());
|
||||
for (size_t i = 0; i < legacy_stats.peers.size(); i++) {
|
||||
EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.sta_count,
|
||||
converted.iface.peers[i].staCount);
|
||||
EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.chan_util,
|
||||
converted.iface.peers[i].chanUtil);
|
||||
for (size_t j = 0; j < legacy_stats.peers[i].rate_stats.size(); j++) {
|
||||
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.preamble,
|
||||
(uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.preamble);
|
||||
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.nss,
|
||||
(uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.nss);
|
||||
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.bw,
|
||||
(uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.bw);
|
||||
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx,
|
||||
(uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.rateMcsIdx);
|
||||
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].tx_mpdu,
|
||||
(uint32_t)converted.iface.peers[i].rateStats[j].txMpdu);
|
||||
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rx_mpdu,
|
||||
(uint32_t)converted.iface.peers[i].rateStats[j].rxMpdu);
|
||||
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].mpdu_lost,
|
||||
(uint32_t)converted.iface.peers[i].rateStats[j].mpduLost);
|
||||
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].retries,
|
||||
(uint32_t)converted.iface.peers[i].rateStats[j].retries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(AidlStructUtilTest, CanConvertLegacyFeaturesToAidl) {
|
||||
using AidlChipCaps = IWifiChip::ChipCapabilityMask;
|
||||
|
||||
uint32_t aidl_caps;
|
||||
|
||||
uint32_t legacy_feature_set = WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE;
|
||||
uint32_t legacy_logger_feature_set = legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
|
||||
|
||||
ASSERT_TRUE(aidl_struct_util::convertLegacyFeaturesToAidlChipCapabilities(
|
||||
legacy_feature_set, legacy_logger_feature_set, &aidl_caps));
|
||||
|
||||
EXPECT_EQ((uint32_t)AidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA |
|
||||
(uint32_t)AidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS |
|
||||
(uint32_t)AidlChipCaps::DEBUG_ERROR_ALERTS | (uint32_t)AidlChipCaps::D2D_RTT |
|
||||
(uint32_t)AidlChipCaps::SET_LATENCY_MODE |
|
||||
(uint32_t)AidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP,
|
||||
aidl_caps);
|
||||
}
|
||||
|
||||
void insertRadioCombination(legacy_hal::wifi_radio_combination* dst_radio_combination_ptr,
|
||||
int num_radio_configurations,
|
||||
legacy_hal::wifi_radio_configuration* radio_configuration) {
|
||||
dst_radio_combination_ptr->num_radio_configurations = num_radio_configurations;
|
||||
memcpy(dst_radio_combination_ptr->radio_configurations, radio_configuration,
|
||||
num_radio_configurations * sizeof(legacy_hal::wifi_radio_configuration));
|
||||
}
|
||||
|
||||
void verifyRadioCombination(WifiRadioCombination* radioCombination, size_t num_radio_configurations,
|
||||
legacy_hal::wifi_radio_configuration* radio_configuration) {
|
||||
EXPECT_EQ(num_radio_configurations, radioCombination->radioConfigurations.size());
|
||||
for (size_t i = 0; i < num_radio_configurations; i++) {
|
||||
EXPECT_EQ(aidl_struct_util::convertLegacyMacBandToAidlWifiBand(radio_configuration->band),
|
||||
radioCombination->radioConfigurations[i].bandInfo);
|
||||
EXPECT_EQ(aidl_struct_util::convertLegacyAntennaConfigurationToAidl(
|
||||
radio_configuration->antenna_cfg),
|
||||
radioCombination->radioConfigurations[i].antennaMode);
|
||||
radio_configuration++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(AidlStructUtilTest, canConvertLegacyRadioCombinationsMatrixToAidl) {
|
||||
legacy_hal::wifi_radio_configuration radio_configurations_array1[] = {
|
||||
{.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_1X1},
|
||||
};
|
||||
legacy_hal::wifi_radio_configuration radio_configurations_array2[] = {
|
||||
{.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_2X2},
|
||||
{.band = legacy_hal::WLAN_MAC_5_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_3X3},
|
||||
};
|
||||
legacy_hal::wifi_radio_configuration radio_configurations_array3[] = {
|
||||
{.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_2X2},
|
||||
{.band = legacy_hal::WLAN_MAC_6_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_1X1},
|
||||
{.band = legacy_hal::WLAN_MAC_5_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_4X4},
|
||||
};
|
||||
|
||||
int num_radio_configs = 0;
|
||||
int num_combinations = 0;
|
||||
std::array<char, 256> buffer;
|
||||
buffer.fill(0);
|
||||
legacy_hal::wifi_radio_combination_matrix* legacy_matrix =
|
||||
reinterpret_cast<wifi_radio_combination_matrix*>(buffer.data());
|
||||
legacy_hal::wifi_radio_combination* radio_combinations;
|
||||
|
||||
// Prepare a legacy wifi_radio_combination_matrix
|
||||
legacy_matrix->num_radio_combinations = 3;
|
||||
// Insert first combination
|
||||
radio_combinations =
|
||||
(legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations);
|
||||
insertRadioCombination(
|
||||
radio_combinations,
|
||||
sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]),
|
||||
radio_configurations_array1);
|
||||
num_combinations++;
|
||||
num_radio_configs +=
|
||||
sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]);
|
||||
|
||||
// Insert second combination
|
||||
radio_combinations =
|
||||
(legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations +
|
||||
(num_combinations *
|
||||
sizeof(legacy_hal::wifi_radio_combination)) +
|
||||
(num_radio_configs *
|
||||
sizeof(wifi_radio_configuration)));
|
||||
insertRadioCombination(
|
||||
radio_combinations,
|
||||
sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]),
|
||||
radio_configurations_array2);
|
||||
num_combinations++;
|
||||
num_radio_configs +=
|
||||
sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]);
|
||||
|
||||
// Insert third combination
|
||||
radio_combinations =
|
||||
(legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations +
|
||||
(num_combinations *
|
||||
sizeof(legacy_hal::wifi_radio_combination)) +
|
||||
(num_radio_configs *
|
||||
sizeof(wifi_radio_configuration)));
|
||||
insertRadioCombination(
|
||||
radio_combinations,
|
||||
sizeof(radio_configurations_array3) / sizeof(radio_configurations_array3[0]),
|
||||
radio_configurations_array3);
|
||||
|
||||
WifiRadioCombinationMatrix converted_matrix{};
|
||||
aidl_struct_util::convertLegacyRadioCombinationsMatrixToAidl(legacy_matrix, &converted_matrix);
|
||||
|
||||
// Verify the conversion
|
||||
EXPECT_EQ(legacy_matrix->num_radio_combinations, converted_matrix.radioCombinations.size());
|
||||
verifyRadioCombination(
|
||||
&converted_matrix.radioCombinations[0],
|
||||
sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]),
|
||||
radio_configurations_array1);
|
||||
verifyRadioCombination(
|
||||
&converted_matrix.radioCombinations[1],
|
||||
sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]),
|
||||
radio_configurations_array2);
|
||||
verifyRadioCombination(
|
||||
&converted_matrix.radioCombinations[2],
|
||||
sizeof(radio_configurations_array3) / sizeof(radio_configurations_array3[0]),
|
||||
radio_configurations_array3);
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
28
wifi/aidl/default/tests/main.cpp
Normal file
28
wifi/aidl/default/tests/main.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
::testing::InitGoogleMock(&argc, argv);
|
||||
// Force ourselves to always log to stderr
|
||||
android::base::InitLogging(argv, android::base::StderrLogger);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
28
wifi/aidl/default/tests/mock_interface_tool.cpp
Normal file
28
wifi/aidl/default/tests/mock_interface_tool.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "mock_interface_tool.h"
|
||||
|
||||
namespace android {
|
||||
namespace wifi_system {
|
||||
|
||||
MockInterfaceTool::MockInterfaceTool() {}
|
||||
|
||||
} // namespace wifi_system
|
||||
} // namespace android
|
||||
42
wifi/aidl/default/tests/mock_interface_tool.h
Normal file
42
wifi/aidl/default/tests/mock_interface_tool.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef MOCK_INTERFACE_TOOL_H
|
||||
#define MOCK_INTERFACE_TOOL_H
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <wifi_system/interface_tool.h>
|
||||
|
||||
namespace android {
|
||||
namespace wifi_system {
|
||||
|
||||
class MockInterfaceTool : public InterfaceTool {
|
||||
public:
|
||||
MockInterfaceTool();
|
||||
|
||||
MOCK_METHOD1(GetUpState, bool(const char* if_name));
|
||||
MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up));
|
||||
MOCK_METHOD1(SetWifiUpState, bool(bool request_up));
|
||||
MOCK_METHOD2(SetMacAddress,
|
||||
bool(const char* if_name, const std::array<uint8_t, ETH_ALEN>& address));
|
||||
MOCK_METHOD1(GetFactoryMacAddress, std::array<uint8_t, ETH_ALEN>(const char* if_name));
|
||||
|
||||
}; // class MockInterfaceTool
|
||||
|
||||
} // namespace wifi_system
|
||||
} // namespace android
|
||||
|
||||
#endif // MOCK_INTERFACE_TOOL_H
|
||||
33
wifi/aidl/default/tests/mock_wifi_feature_flags.cpp
Normal file
33
wifi/aidl/default/tests/mock_wifi_feature_flags.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "mock_wifi_feature_flags.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace feature_flags {
|
||||
|
||||
MockWifiFeatureFlags::MockWifiFeatureFlags() {}
|
||||
|
||||
} // namespace feature_flags
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
44
wifi/aidl/default/tests/mock_wifi_feature_flags.h
Normal file
44
wifi/aidl/default/tests/mock_wifi_feature_flags.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef MOCK_WIFI_FEATURE_FLAGS_H_
|
||||
#define MOCK_WIFI_FEATURE_FLAGS_H_
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "wifi_feature_flags.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace feature_flags {
|
||||
|
||||
class MockWifiFeatureFlags : public WifiFeatureFlags {
|
||||
public:
|
||||
MockWifiFeatureFlags();
|
||||
|
||||
MOCK_METHOD1(getChipModes, std::vector<IWifiChip::ChipMode>(bool is_primary));
|
||||
MOCK_METHOD0(isApMacRandomizationDisabled, bool());
|
||||
};
|
||||
|
||||
} // namespace feature_flags
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // MOCK_WIFI_FEATURE_FLAGS_H_
|
||||
38
wifi/aidl/default/tests/mock_wifi_iface_util.cpp
Normal file
38
wifi/aidl/default/tests/mock_wifi_iface_util.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "mock_wifi_iface_util.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace iface_util {
|
||||
|
||||
MockWifiIfaceUtil::MockWifiIfaceUtil(
|
||||
const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
|
||||
: WifiIfaceUtil(iface_tool, legacy_hal) {}
|
||||
|
||||
} // namespace iface_util
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
50
wifi/aidl/default/tests/mock_wifi_iface_util.h
Normal file
50
wifi/aidl/default/tests/mock_wifi_iface_util.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef MOCK_WIFI_IFACE_UTIL_H_
|
||||
#define MOCK_WIFI_IFACE_UTIL_H_
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "wifi_iface_util.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace iface_util {
|
||||
|
||||
class MockWifiIfaceUtil : public iface_util::WifiIfaceUtil {
|
||||
public:
|
||||
MockWifiIfaceUtil(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
|
||||
MOCK_METHOD1(getFactoryMacAddress, std::array<uint8_t, 6>(const std::string&));
|
||||
MOCK_METHOD2(setMacAddress, bool(const std::string&, const std::array<uint8_t, 6>&));
|
||||
MOCK_METHOD0(getOrCreateRandomMacAddress, std::array<uint8_t, 6>());
|
||||
MOCK_METHOD2(registerIfaceEventHandlers,
|
||||
void(const std::string&, iface_util::IfaceEventHandlers));
|
||||
MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&));
|
||||
MOCK_METHOD2(setUpState, bool(const std::string&, bool));
|
||||
MOCK_METHOD1(ifNameToIndex, unsigned(const std::string&));
|
||||
};
|
||||
|
||||
} // namespace iface_util
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // MOCK_WIFI_IFACE_UTIL_H_
|
||||
37
wifi/aidl/default/tests/mock_wifi_legacy_hal.cpp
Normal file
37
wifi/aidl/default/tests/mock_wifi_legacy_hal.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "mock_wifi_legacy_hal.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace legacy_hal {
|
||||
|
||||
MockWifiLegacyHal::MockWifiLegacyHal(
|
||||
const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
|
||||
const wifi_hal_fn& fn, bool is_primary)
|
||||
: WifiLegacyHal(iface_tool, fn, is_primary) {}
|
||||
} // namespace legacy_hal
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
69
wifi/aidl/default/tests/mock_wifi_legacy_hal.h
Normal file
69
wifi/aidl/default/tests/mock_wifi_legacy_hal.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef MOCK_WIFI_LEGACY_HAL_H_
|
||||
#define MOCK_WIFI_LEGACY_HAL_H_
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace legacy_hal {
|
||||
|
||||
class MockWifiLegacyHal : public WifiLegacyHal {
|
||||
public:
|
||||
MockWifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
|
||||
const wifi_hal_fn& fn, bool is_primary);
|
||||
MOCK_METHOD0(initialize, wifi_error());
|
||||
MOCK_METHOD0(start, wifi_error());
|
||||
MOCK_METHOD2(stop,
|
||||
wifi_error(std::unique_lock<std::recursive_mutex>*, const std::function<void()>&));
|
||||
MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool));
|
||||
MOCK_METHOD2(registerRadioModeChangeCallbackHandler,
|
||||
wifi_error(const std::string&, const on_radio_mode_change_callback&));
|
||||
MOCK_METHOD1(getFirmwareVersion,
|
||||
std::pair<wifi_error, std::string>(const std::string& iface_name));
|
||||
MOCK_METHOD1(getDriverVersion,
|
||||
std::pair<wifi_error, std::string>(const std::string& iface_name));
|
||||
|
||||
MOCK_METHOD2(selectTxPowerScenario,
|
||||
wifi_error(const std::string& iface_name, wifi_power_scenario scenario));
|
||||
MOCK_METHOD1(resetTxPowerScenario, wifi_error(const std::string& iface_name));
|
||||
MOCK_METHOD2(nanRegisterCallbackHandlers,
|
||||
wifi_error(const std::string&, const NanCallbackHandlers&));
|
||||
MOCK_METHOD2(nanDisableRequest, wifi_error(const std::string&, transaction_id));
|
||||
MOCK_METHOD3(nanDataInterfaceDelete,
|
||||
wifi_error(const std::string&, transaction_id, const std::string&));
|
||||
MOCK_METHOD2(createVirtualInterface,
|
||||
wifi_error(const std::string& ifname, wifi_interface_type iftype));
|
||||
MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname));
|
||||
MOCK_METHOD0(waitForDriverReady, wifi_error());
|
||||
MOCK_METHOD2(getSupportedIfaceName, wifi_error(uint32_t, std::string&));
|
||||
MOCK_METHOD1(registerSubsystemRestartCallbackHandler,
|
||||
wifi_error(const on_subsystem_restart_callback&));
|
||||
MOCK_METHOD1(getSupportedFeatureSet, std::pair<wifi_error, uint64_t>(const std::string&));
|
||||
};
|
||||
} // namespace legacy_hal
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // MOCK_WIFI_LEGACY_HAL_H_
|
||||
36
wifi/aidl/default/tests/mock_wifi_mode_controller.cpp
Normal file
36
wifi/aidl/default/tests/mock_wifi_mode_controller.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38
|
||||
#include "mock_wifi_mode_controller.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace mode_controller {
|
||||
|
||||
MockWifiModeController::MockWifiModeController() : WifiModeController() {}
|
||||
|
||||
} // namespace mode_controller
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
44
wifi/aidl/default/tests/mock_wifi_mode_controller.h
Normal file
44
wifi/aidl/default/tests/mock_wifi_mode_controller.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef MOCK_WIFI_MODE_CONTROLLER_H_
|
||||
#define MOCK_WIFI_MODE_CONTROLLER_H_
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "wifi_mode_controller.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace mode_controller {
|
||||
|
||||
class MockWifiModeController : public WifiModeController {
|
||||
public:
|
||||
MockWifiModeController();
|
||||
MOCK_METHOD0(initialize, bool());
|
||||
MOCK_METHOD1(changeFirmwareMode, bool(IfaceType));
|
||||
MOCK_METHOD1(isFirmwareModeChangeNeeded, bool(IfaceType));
|
||||
MOCK_METHOD0(deinitialize, bool());
|
||||
};
|
||||
} // namespace mode_controller
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // MOCK_WIFI_MODE_CONTROLLER_H_
|
||||
96
wifi/aidl/default/tests/ringbuffer_unit_tests.cpp
Normal file
96
wifi/aidl/default/tests/ringbuffer_unit_tests.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "ringbuffer.h"
|
||||
|
||||
using testing::Return;
|
||||
using testing::Test;
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
class RingbufferTest : public Test {
|
||||
public:
|
||||
const uint32_t maxBufferSize_ = 10;
|
||||
Ringbuffer buffer_{maxBufferSize_};
|
||||
};
|
||||
|
||||
TEST_F(RingbufferTest, CreateEmptyBuffer) {
|
||||
ASSERT_TRUE(buffer_.getData().empty());
|
||||
}
|
||||
|
||||
TEST_F(RingbufferTest, CanUseFullBufferCapacity) {
|
||||
const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
|
||||
const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
|
||||
buffer_.append(input);
|
||||
buffer_.append(input2);
|
||||
ASSERT_EQ(2u, buffer_.getData().size());
|
||||
EXPECT_EQ(input, buffer_.getData().front());
|
||||
EXPECT_EQ(input2, buffer_.getData().back());
|
||||
}
|
||||
|
||||
TEST_F(RingbufferTest, OldDataIsRemovedOnOverflow) {
|
||||
const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
|
||||
const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
|
||||
const std::vector<uint8_t> input3 = {'G'};
|
||||
buffer_.append(input);
|
||||
buffer_.append(input2);
|
||||
buffer_.append(input3);
|
||||
ASSERT_EQ(2u, buffer_.getData().size());
|
||||
EXPECT_EQ(input2, buffer_.getData().front());
|
||||
EXPECT_EQ(input3, buffer_.getData().back());
|
||||
}
|
||||
|
||||
TEST_F(RingbufferTest, MultipleOldDataIsRemovedOnOverflow) {
|
||||
const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
|
||||
const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
|
||||
const std::vector<uint8_t> input3(maxBufferSize_, '2');
|
||||
buffer_.append(input);
|
||||
buffer_.append(input2);
|
||||
buffer_.append(input3);
|
||||
ASSERT_EQ(1u, buffer_.getData().size());
|
||||
EXPECT_EQ(input3, buffer_.getData().front());
|
||||
}
|
||||
|
||||
TEST_F(RingbufferTest, AppendingEmptyBufferDoesNotAddGarbage) {
|
||||
const std::vector<uint8_t> input = {};
|
||||
buffer_.append(input);
|
||||
ASSERT_TRUE(buffer_.getData().empty());
|
||||
}
|
||||
|
||||
TEST_F(RingbufferTest, OversizedAppendIsDropped) {
|
||||
const std::vector<uint8_t> input(maxBufferSize_ + 1, '0');
|
||||
buffer_.append(input);
|
||||
ASSERT_TRUE(buffer_.getData().empty());
|
||||
}
|
||||
|
||||
TEST_F(RingbufferTest, OversizedAppendDoesNotDropExistingData) {
|
||||
const std::vector<uint8_t> input(maxBufferSize_, '0');
|
||||
const std::vector<uint8_t> input2(maxBufferSize_ + 1, '1');
|
||||
buffer_.append(input);
|
||||
buffer_.append(input2);
|
||||
ASSERT_EQ(1u, buffer_.getData().size());
|
||||
EXPECT_EQ(input, buffer_.getData().front());
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
26
wifi/aidl/default/tests/runtests.sh
Executable file
26
wifi/aidl/default/tests/runtests.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright(C) 2022 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.
|
||||
|
||||
if [ -z $ANDROID_BUILD_TOP ]; then
|
||||
echo "You need to source and lunch before you can use this script"
|
||||
exit 1
|
||||
fi
|
||||
set -e
|
||||
|
||||
$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode android.hardware.wifi-service-tests
|
||||
adb root
|
||||
adb sync data
|
||||
adb shell /data/nativetest64/vendor/android.hardware.wifi-service-tests/android.hardware.wifi-service-tests
|
||||
855
wifi/aidl/default/tests/wifi_chip_unit_tests.cpp
Normal file
855
wifi/aidl/default/tests/wifi_chip_unit_tests.cpp
Normal file
@@ -0,0 +1,855 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "wifi_chip.h"
|
||||
|
||||
#include "mock_interface_tool.h"
|
||||
#include "mock_wifi_feature_flags.h"
|
||||
#include "mock_wifi_iface_util.h"
|
||||
#include "mock_wifi_legacy_hal.h"
|
||||
#include "mock_wifi_mode_controller.h"
|
||||
|
||||
using testing::NiceMock;
|
||||
using testing::Return;
|
||||
using testing::Test;
|
||||
|
||||
namespace {
|
||||
constexpr int kFakeChipId = 5;
|
||||
} // namespace
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
class WifiChipTest : public Test {
|
||||
protected:
|
||||
void setupV1IfaceCombination() {
|
||||
// clang-format off
|
||||
// 1 STA + 1 P2P
|
||||
const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsSta =
|
||||
{
|
||||
{
|
||||
{
|
||||
{{IfaceConcurrencyType::STA}, 1},
|
||||
{{IfaceConcurrencyType::P2P}, 1}
|
||||
}
|
||||
}
|
||||
};
|
||||
// 1 AP
|
||||
const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsAp =
|
||||
{
|
||||
{
|
||||
{
|
||||
{{IfaceConcurrencyType::AP}, 1}
|
||||
}
|
||||
}
|
||||
};
|
||||
const std::vector<IWifiChip::ChipMode> modes = {
|
||||
{feature_flags::chip_mode_ids::kV1Sta, combinationsSta},
|
||||
{feature_flags::chip_mode_ids::kV1Ap, combinationsAp}
|
||||
};
|
||||
// clang-format on
|
||||
EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
|
||||
}
|
||||
|
||||
void setupV1_AwareIfaceCombination() {
|
||||
// clang-format off
|
||||
// 1 STA + 1 of (P2P or NAN)
|
||||
const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsSta =
|
||||
{
|
||||
{
|
||||
{
|
||||
{{IfaceConcurrencyType::STA}, 1},
|
||||
{{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
|
||||
}
|
||||
}
|
||||
};
|
||||
// 1 AP
|
||||
const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsAp =
|
||||
{
|
||||
{
|
||||
{
|
||||
{{IfaceConcurrencyType::AP}, 1}
|
||||
}
|
||||
}
|
||||
};
|
||||
const std::vector<IWifiChip::ChipMode> modes = {
|
||||
{feature_flags::chip_mode_ids::kV1Sta, combinationsSta},
|
||||
{feature_flags::chip_mode_ids::kV1Ap, combinationsAp}
|
||||
};
|
||||
// clang-format on
|
||||
EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
|
||||
}
|
||||
|
||||
void setupV1_AwareDisabledApIfaceCombination() {
|
||||
// clang-format off
|
||||
// 1 STA + 1 of (P2P or NAN)
|
||||
const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsSta =
|
||||
{
|
||||
{
|
||||
{
|
||||
{{IfaceConcurrencyType::STA}, 1},
|
||||
{{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
|
||||
}
|
||||
}
|
||||
};
|
||||
const std::vector<IWifiChip::ChipMode> modes = {
|
||||
{feature_flags::chip_mode_ids::kV1Sta, combinationsSta}
|
||||
};
|
||||
// clang-format on
|
||||
EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
|
||||
}
|
||||
|
||||
void setupV2_AwareIfaceCombination() {
|
||||
// clang-format off
|
||||
// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
|
||||
const std::vector<IWifiChip::ChipConcurrencyCombination> combinations =
|
||||
{
|
||||
{
|
||||
{
|
||||
{{IfaceConcurrencyType::STA}, 1},
|
||||
{{IfaceConcurrencyType::AP}, 1}
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
{{IfaceConcurrencyType::STA}, 1},
|
||||
{{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
|
||||
}
|
||||
}
|
||||
};
|
||||
const std::vector<IWifiChip::ChipMode> modes = {
|
||||
{feature_flags::chip_mode_ids::kV3, combinations}
|
||||
};
|
||||
// clang-format on
|
||||
EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
|
||||
}
|
||||
|
||||
void setupV2_AwareDisabledApIfaceCombination() {
|
||||
// clang-format off
|
||||
// 1 STA + 1 of (P2P or NAN)
|
||||
const std::vector<IWifiChip::ChipConcurrencyCombination> combinations =
|
||||
{
|
||||
{
|
||||
{
|
||||
{{IfaceConcurrencyType::STA}, 1},
|
||||
{{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
|
||||
}
|
||||
}
|
||||
};
|
||||
const std::vector<IWifiChip::ChipMode> modes = {
|
||||
{feature_flags::chip_mode_ids::kV3, combinations}
|
||||
};
|
||||
// clang-format on
|
||||
EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
|
||||
}
|
||||
|
||||
void setup_MultiIfaceCombination() {
|
||||
// clang-format off
|
||||
// 3 STA + 1 AP
|
||||
const std::vector<IWifiChip::ChipConcurrencyCombination> combinations =
|
||||
{
|
||||
{
|
||||
{
|
||||
{{IfaceConcurrencyType::STA}, 3},
|
||||
{{IfaceConcurrencyType::AP}, 1}
|
||||
}
|
||||
}
|
||||
};
|
||||
const std::vector<IWifiChip::ChipMode> modes = {
|
||||
{feature_flags::chip_mode_ids::kV3, combinations}
|
||||
};
|
||||
// clang-format on
|
||||
EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
|
||||
}
|
||||
|
||||
void assertNumberOfModes(uint32_t num_modes) {
|
||||
std::vector<IWifiChip::ChipMode> modes;
|
||||
ASSERT_TRUE(chip_->getAvailableModes(&modes).isOk());
|
||||
// V2_Aware has 1 mode of operation.
|
||||
ASSERT_EQ(num_modes, modes.size());
|
||||
}
|
||||
|
||||
void findModeAndConfigureForIfaceType(const IfaceConcurrencyType& type) {
|
||||
// This should be aligned with kInvalidModeId in wifi_chip.cpp
|
||||
int32_t mode_id = INT32_MAX;
|
||||
std::vector<IWifiChip::ChipMode> modes;
|
||||
ASSERT_TRUE(chip_->getAvailableModes(&modes).isOk());
|
||||
|
||||
for (const auto& mode : modes) {
|
||||
for (const auto& combination : mode.availableCombinations) {
|
||||
for (const auto& limit : combination.limits) {
|
||||
if (limit.types.end() !=
|
||||
std::find(limit.types.begin(), limit.types.end(), type)) {
|
||||
mode_id = mode.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_NE(INT32_MAX, mode_id);
|
||||
ASSERT_TRUE(chip_->configureChip(mode_id).isOk());
|
||||
}
|
||||
|
||||
// Returns an empty string on error.
|
||||
std::string createIface(const IfaceType& type) {
|
||||
std::string iface_name;
|
||||
if (type == IfaceType::AP) {
|
||||
std::shared_ptr<IWifiApIface> iface;
|
||||
if (!chip_->createApIface(&iface).isOk()) {
|
||||
return "";
|
||||
}
|
||||
EXPECT_NE(iface.get(), nullptr);
|
||||
EXPECT_TRUE(iface->getName(&iface_name).isOk());
|
||||
} else if (type == IfaceType::NAN_IFACE) {
|
||||
std::shared_ptr<IWifiNanIface> iface;
|
||||
if (!chip_->createNanIface(&iface).isOk()) {
|
||||
return "";
|
||||
}
|
||||
EXPECT_NE(iface.get(), nullptr);
|
||||
EXPECT_TRUE(iface->getName(&iface_name).isOk());
|
||||
} else if (type == IfaceType::P2P) {
|
||||
std::shared_ptr<IWifiP2pIface> iface;
|
||||
if (!chip_->createP2pIface(&iface).isOk()) {
|
||||
return "";
|
||||
}
|
||||
EXPECT_NE(iface.get(), nullptr);
|
||||
EXPECT_TRUE(iface->getName(&iface_name).isOk());
|
||||
} else if (type == IfaceType::STA) {
|
||||
std::shared_ptr<IWifiStaIface> iface;
|
||||
if (!chip_->createStaIface(&iface).isOk()) {
|
||||
return "";
|
||||
}
|
||||
EXPECT_NE(iface.get(), nullptr);
|
||||
EXPECT_TRUE(iface->getName(&iface_name).isOk());
|
||||
}
|
||||
return iface_name;
|
||||
}
|
||||
|
||||
void removeIface(const IfaceType& type, const std::string& iface_name) {
|
||||
if (type == IfaceType::AP) {
|
||||
ASSERT_TRUE(chip_->removeApIface(iface_name).isOk());
|
||||
} else if (type == IfaceType::NAN_IFACE) {
|
||||
ASSERT_TRUE(chip_->removeNanIface(iface_name).isOk());
|
||||
} else if (type == IfaceType::P2P) {
|
||||
ASSERT_TRUE(chip_->removeP2pIface(iface_name).isOk());
|
||||
} else if (type == IfaceType::STA) {
|
||||
ASSERT_TRUE(chip_->removeStaIface(iface_name).isOk());
|
||||
}
|
||||
}
|
||||
|
||||
bool createRttController() {
|
||||
std::shared_ptr<IWifiRttController> rtt_controller;
|
||||
auto status = chip_->createRttController(nullptr, &rtt_controller);
|
||||
return status.isOk();
|
||||
}
|
||||
|
||||
static void subsystemRestartHandler(const std::string& /*error*/) {}
|
||||
|
||||
std::shared_ptr<WifiChip> chip_;
|
||||
int chip_id_ = kFakeChipId;
|
||||
legacy_hal::wifi_hal_fn fake_func_table_;
|
||||
std::shared_ptr<NiceMock<::android::wifi_system::MockInterfaceTool>> iface_tool_{
|
||||
new NiceMock<::android::wifi_system::MockInterfaceTool>};
|
||||
std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
|
||||
new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
|
||||
std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>> mode_controller_{
|
||||
new NiceMock<mode_controller::MockWifiModeController>};
|
||||
std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
|
||||
new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
|
||||
std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>> feature_flags_{
|
||||
new NiceMock<feature_flags::MockWifiFeatureFlags>};
|
||||
|
||||
public:
|
||||
void SetUp() override {
|
||||
chip_ = WifiChip::create(chip_id_, true, legacy_hal_, mode_controller_, iface_util_,
|
||||
feature_flags_, subsystemRestartHandler);
|
||||
|
||||
EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_))
|
||||
.WillRepeatedly(testing::Return(true));
|
||||
EXPECT_CALL(*legacy_hal_, start())
|
||||
.WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS));
|
||||
// Vendor HAL does not override the name by default.
|
||||
EXPECT_CALL(*legacy_hal_, getSupportedIfaceName(testing::_, testing::_))
|
||||
.WillRepeatedly(testing::Return(legacy_hal::WIFI_ERROR_UNKNOWN));
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
// Restore default system iface names (This should ideally be using a
|
||||
// mock).
|
||||
property_set("wifi.interface", "wlan0");
|
||||
property_set("wifi.concurrent.interface", "wlan1");
|
||||
property_set("wifi.aware.interface", nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
////////// V1 Iface Combinations ////////////
|
||||
// Mode 1 - STA + P2P
|
||||
// Mode 2 - AP
|
||||
class WifiChipV1IfaceCombinationTest : public WifiChipTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
setupV1IfaceCombination();
|
||||
WifiChipTest::SetUp();
|
||||
// V1 has 2 modes of operation.
|
||||
assertNumberOfModes(2);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateNan_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_TRUE(createIface(IfaceType::AP).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_TRUE(createIface(IfaceType::STA).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_TRUE(createIface(IfaceType::STA).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
////////// V1 + Aware Iface Combinations ////////////
|
||||
// Mode 1 - STA + P2P/NAN
|
||||
// Mode 2 - AP
|
||||
class WifiChipV1_AwareIfaceCombinationTest : public WifiChipTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
setupV1_AwareIfaceCombination();
|
||||
WifiChipTest::SetUp();
|
||||
// V1_Aware has 2 modes of operation.
|
||||
assertNumberOfModes(2u);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateNan_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_TRUE(createIface(IfaceType::AP).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2PNan_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
std::string p2p_iface_name = createIface(IfaceType::P2P);
|
||||
ASSERT_FALSE(p2p_iface_name.empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
|
||||
// After removing P2P iface, NAN iface creation should succeed.
|
||||
removeIface(IfaceType::P2P, p2p_iface_name);
|
||||
ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
std::string nan_iface_name = createIface(IfaceType::NAN_IFACE);
|
||||
ASSERT_FALSE(nan_iface_name.empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::P2P).empty());
|
||||
|
||||
// After removing NAN iface, P2P iface creation should succeed.
|
||||
removeIface(IfaceType::NAN_IFACE, nan_iface_name);
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_TRUE(createIface(IfaceType::STA).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_TRUE(createIface(IfaceType::STA).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_TRUE(createRttController());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_TRUE(createRttController());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowApToSta) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
std::string ap_iface_name = createIface(IfaceType::AP);
|
||||
ASSERT_FALSE(ap_iface_name.empty());
|
||||
ASSERT_FALSE(createRttController());
|
||||
|
||||
removeIface(IfaceType::AP, ap_iface_name);
|
||||
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_TRUE(createRttController());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
|
||||
.WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
|
||||
ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
|
||||
EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
|
||||
.WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
|
||||
ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
|
||||
}
|
||||
|
||||
////////// V2 + Aware Iface Combinations ////////////
|
||||
// Mode 1 - STA + STA/AP
|
||||
// - STA + P2P/NAN
|
||||
class WifiChipV2_AwareIfaceCombinationTest : public WifiChipTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
setupV2_AwareIfaceCombination();
|
||||
WifiChipTest::SetUp();
|
||||
// V2_Aware has 1 mode of operation.
|
||||
assertNumberOfModes(1u);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateP2p_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNan_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateAp_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
ASSERT_TRUE(createIface(IfaceType::STA).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApSta_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_AfterStaApRemove_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
std::string sta_iface_name = createIface(IfaceType::STA);
|
||||
ASSERT_FALSE(sta_iface_name.empty());
|
||||
std::string ap_iface_name = createIface(IfaceType::AP);
|
||||
ASSERT_FALSE(ap_iface_name.empty());
|
||||
|
||||
ASSERT_TRUE(createIface(IfaceType::STA).empty());
|
||||
|
||||
// After removing AP & STA iface, STA iface creation should succeed.
|
||||
removeIface(IfaceType::STA, sta_iface_name);
|
||||
removeIface(IfaceType::AP, ap_iface_name);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2PNan_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_AfterP2pRemove_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
std::string p2p_iface_name = createIface(IfaceType::P2P);
|
||||
ASSERT_FALSE(p2p_iface_name.empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
|
||||
// After removing P2P iface, NAN iface creation should succeed.
|
||||
removeIface(IfaceType::P2P, p2p_iface_name);
|
||||
ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_AfterNanRemove_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
std::string nan_iface_name = createIface(IfaceType::NAN_IFACE);
|
||||
ASSERT_FALSE(nan_iface_name.empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::P2P).empty());
|
||||
|
||||
// After removing NAN iface, P2P iface creation should succeed.
|
||||
removeIface(IfaceType::NAN_IFACE, nan_iface_name);
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApNan_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_FALSE(createIface(IfaceType::AP).empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApP2p_ShouldFail) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_FALSE(createIface(IfaceType::AP).empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::P2P).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
std::string p2p_iface_name = createIface(IfaceType::P2P);
|
||||
ASSERT_FALSE(p2p_iface_name.empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
|
||||
// After removing P2P iface, NAN iface creation should succeed.
|
||||
removeIface(IfaceType::P2P, p2p_iface_name);
|
||||
ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
std::string nan_iface_name = createIface(IfaceType::NAN_IFACE);
|
||||
ASSERT_FALSE(nan_iface_name.empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::P2P).empty());
|
||||
|
||||
// After removing NAN iface, P2P iface creation should succeed.
|
||||
removeIface(IfaceType::NAN_IFACE, nan_iface_name);
|
||||
ASSERT_FALSE(createIface(IfaceType::P2P).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_EnsureDifferentIfaceNames) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
std::string sta_iface_name = createIface(IfaceType::STA);
|
||||
std::string ap_iface_name = createIface(IfaceType::AP);
|
||||
ASSERT_FALSE(sta_iface_name.empty());
|
||||
ASSERT_FALSE(ap_iface_name.empty());
|
||||
ASSERT_NE(sta_iface_name, ap_iface_name);
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_TRUE(createRttController());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_TRUE(createRttController());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlow) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_FALSE(createIface(IfaceType::AP).empty());
|
||||
ASSERT_TRUE(createRttController());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
|
||||
.WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
|
||||
ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
|
||||
ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
|
||||
EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan1", testing::_))
|
||||
.WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
|
||||
ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveNanOnStaRemove) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
|
||||
// Create NAN iface
|
||||
ASSERT_EQ(createIface(IfaceType::NAN_IFACE), "wlan0");
|
||||
|
||||
// We should have 1 nan iface.
|
||||
std::vector<std::string> iface_names;
|
||||
ASSERT_TRUE(chip_->getNanIfaceNames(&iface_names).isOk());
|
||||
ASSERT_EQ(iface_names.size(), 1u);
|
||||
ASSERT_EQ(iface_names[0], "wlan0");
|
||||
|
||||
// Retrieve the nan iface object.
|
||||
std::shared_ptr<IWifiNanIface> nan_iface;
|
||||
ASSERT_TRUE(chip_->getNanIface("wlan0", &nan_iface).isOk());
|
||||
ASSERT_NE(nan_iface.get(), nullptr);
|
||||
|
||||
// Remove the STA iface. We should have 0 nan ifaces now.
|
||||
removeIface(IfaceType::STA, "wlan0");
|
||||
ASSERT_TRUE(chip_->getNanIfaceNames(&iface_names).isOk());
|
||||
ASSERT_EQ(iface_names.size(), 0u);
|
||||
|
||||
// Any operation on the nan iface object should now return an error.
|
||||
std::string name;
|
||||
auto status = nan_iface->getName(&name);
|
||||
ASSERT_EQ(status.getServiceSpecificError(),
|
||||
static_cast<int32_t>(WifiStatusCode::ERROR_WIFI_IFACE_INVALID));
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveRttControllerOnStaRemove) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
|
||||
// Create RTT controller
|
||||
std::shared_ptr<IWifiRttController> rtt_controller;
|
||||
ASSERT_TRUE(chip_->createRttController(nullptr, &rtt_controller).isOk());
|
||||
|
||||
// Remove the STA iface.
|
||||
removeIface(IfaceType::STA, "wlan0");
|
||||
|
||||
// Any operation on the rtt controller object should now return an error.
|
||||
std::shared_ptr<IWifiStaIface> bound_iface;
|
||||
auto status = rtt_controller->getBoundIface(&bound_iface);
|
||||
ASSERT_EQ(status.getServiceSpecificError(),
|
||||
static_cast<int32_t>(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID));
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithSharedNanIface) {
|
||||
property_set("wifi.aware.interface", nullptr);
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
ASSERT_EQ(createIface(IfaceType::NAN_IFACE), "wlan0");
|
||||
removeIface(IfaceType::NAN_IFACE, "wlan0");
|
||||
EXPECT_CALL(*iface_util_, setUpState(testing::_, testing::_)).Times(0);
|
||||
}
|
||||
|
||||
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithDedicatedNanIface) {
|
||||
property_set("wifi.aware.interface", "aware0");
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
EXPECT_CALL(*iface_util_, ifNameToIndex("aware0")).WillOnce(testing::Return(4));
|
||||
EXPECT_CALL(*iface_util_, setUpState("aware0", true)).WillOnce(testing::Return(true));
|
||||
ASSERT_EQ(createIface(IfaceType::NAN_IFACE), "aware0");
|
||||
|
||||
EXPECT_CALL(*iface_util_, setUpState("aware0", false)).WillOnce(testing::Return(true));
|
||||
removeIface(IfaceType::NAN_IFACE, "aware0");
|
||||
}
|
||||
|
||||
////////// V1 Iface Combinations when AP creation is disabled //////////
|
||||
class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
setupV1_AwareDisabledApIfaceCombination();
|
||||
WifiChipTest::SetUp();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::AP).empty());
|
||||
}
|
||||
|
||||
////////// V2 Iface Combinations when AP creation is disabled //////////
|
||||
class WifiChipV2_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
setupV2_AwareDisabledApIfaceCombination();
|
||||
WifiChipTest::SetUp();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, CreateSta_ShouldSucceed) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::AP).empty());
|
||||
}
|
||||
|
||||
////////// Hypothetical Iface Combination with multiple ifaces //////////
|
||||
class WifiChip_MultiIfaceTest : public WifiChipTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
setup_MultiIfaceCombination();
|
||||
WifiChipTest::SetUp();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(WifiChip_MultiIfaceTest, Create3Sta) {
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_FALSE(createIface(IfaceType::STA).empty());
|
||||
ASSERT_TRUE(createIface(IfaceType::STA).empty());
|
||||
}
|
||||
|
||||
TEST_F(WifiChip_MultiIfaceTest, CreateStaWithDefaultNames) {
|
||||
property_set("wifi.interface.0", "");
|
||||
property_set("wifi.interface.1", "");
|
||||
property_set("wifi.interface.2", "");
|
||||
property_set("wifi.interface", "");
|
||||
property_set("wifi.concurrent.interface", "");
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan1");
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
|
||||
}
|
||||
|
||||
TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomNames) {
|
||||
property_set("wifi.interface.0", "test0");
|
||||
property_set("wifi.interface.1", "test1");
|
||||
property_set("wifi.interface.2", "test2");
|
||||
property_set("wifi.interface", "bad0");
|
||||
property_set("wifi.concurrent.interface", "bad1");
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "bad0");
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "bad1");
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "test2");
|
||||
}
|
||||
|
||||
TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomAltNames) {
|
||||
property_set("wifi.interface.0", "");
|
||||
property_set("wifi.interface.1", "");
|
||||
property_set("wifi.interface.2", "");
|
||||
property_set("wifi.interface", "testA0");
|
||||
property_set("wifi.concurrent.interface", "testA1");
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "testA0");
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "testA1");
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
|
||||
}
|
||||
|
||||
TEST_F(WifiChip_MultiIfaceTest, CreateApStartsWithIdx1) {
|
||||
// WifiChip_MultiIfaceTest iface combo: STAx3 + APx1
|
||||
// When the HAL support dual STAs, AP should start with idx 2.
|
||||
findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
|
||||
// First AP will be slotted to wlan1.
|
||||
ASSERT_EQ(createIface(IfaceType::AP), "wlan2");
|
||||
// First STA will be slotted to wlan0.
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
|
||||
// All further STA will be slotted to the remaining free indices.
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan1");
|
||||
ASSERT_EQ(createIface(IfaceType::STA), "wlan3");
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
94
wifi/aidl/default/tests/wifi_iface_util_unit_tests.cpp
Normal file
94
wifi/aidl/default/tests/wifi_iface_util_unit_tests.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "wifi_iface_util.h"
|
||||
|
||||
#include "mock_interface_tool.h"
|
||||
#include "mock_wifi_legacy_hal.h"
|
||||
|
||||
using testing::NiceMock;
|
||||
using testing::Test;
|
||||
|
||||
namespace {
|
||||
constexpr uint8_t kValidUnicastLocallyAssignedMacAddressMask = 0x02;
|
||||
constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc};
|
||||
constexpr char kIfaceName[] = "test-wlan0";
|
||||
|
||||
bool isValidUnicastLocallyAssignedMacAddress(const std::array<uint8_t, 6>& mac_address) {
|
||||
uint8_t first_byte = mac_address[0];
|
||||
return (first_byte & 0x3) == kValidUnicastLocallyAssignedMacAddressMask;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace iface_util {
|
||||
|
||||
class WifiIfaceUtilTest : public Test {
|
||||
protected:
|
||||
std::shared_ptr<NiceMock<::android::wifi_system::MockInterfaceTool>> iface_tool_{
|
||||
new NiceMock<::android::wifi_system::MockInterfaceTool>};
|
||||
legacy_hal::wifi_hal_fn fake_func_table_;
|
||||
std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
|
||||
new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
|
||||
WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_);
|
||||
};
|
||||
|
||||
TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) {
|
||||
auto mac_address = iface_util_->getOrCreateRandomMacAddress();
|
||||
ASSERT_TRUE(isValidUnicastLocallyAssignedMacAddress(mac_address));
|
||||
|
||||
// All further calls should return the same MAC address.
|
||||
ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
|
||||
ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
|
||||
}
|
||||
|
||||
TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) {
|
||||
std::array<uint8_t, 6> mac_address = {};
|
||||
std::copy(std::begin(kMacAddress), std::end(kMacAddress), std::begin(mac_address));
|
||||
EXPECT_CALL(*iface_tool_, SetMacAddress(testing::_, testing::_))
|
||||
.WillRepeatedly(testing::Return(true));
|
||||
EXPECT_CALL(*iface_tool_, SetUpState(testing::_, testing::_))
|
||||
.WillRepeatedly(testing::Return(true));
|
||||
|
||||
// Register for iface state toggle events.
|
||||
bool callback_invoked = false;
|
||||
iface_util::IfaceEventHandlers event_handlers = {};
|
||||
event_handlers.on_state_toggle_off_on =
|
||||
[&callback_invoked](const std::string& /* iface_name */) { callback_invoked = true; };
|
||||
iface_util_->registerIfaceEventHandlers(kIfaceName, event_handlers);
|
||||
// Invoke setMacAddress and ensure that the cb is invoked.
|
||||
ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
|
||||
ASSERT_TRUE(callback_invoked);
|
||||
|
||||
// Unregister for iface state toggle events.
|
||||
callback_invoked = false;
|
||||
iface_util_->unregisterIfaceEventHandlers(kIfaceName);
|
||||
// Invoke setMacAddress and ensure that the cb is not invoked.
|
||||
ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
|
||||
ASSERT_FALSE(callback_invoked);
|
||||
}
|
||||
} // namespace iface_util
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
168
wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp
Normal file
168
wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "wifi_nan_iface.h"
|
||||
|
||||
#include "mock_interface_tool.h"
|
||||
#include "mock_wifi_feature_flags.h"
|
||||
#include "mock_wifi_iface_util.h"
|
||||
#include "mock_wifi_legacy_hal.h"
|
||||
|
||||
using testing::NiceMock;
|
||||
using testing::Return;
|
||||
using testing::Test;
|
||||
|
||||
namespace {
|
||||
constexpr char kIfaceName[] = "mockWlan0";
|
||||
} // namespace
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
bool CaptureIfaceEventHandlers(const std::string& /* iface_name*/,
|
||||
iface_util::IfaceEventHandlers in_iface_event_handlers,
|
||||
iface_util::IfaceEventHandlers* out_iface_event_handlers) {
|
||||
*out_iface_event_handlers = in_iface_event_handlers;
|
||||
return true;
|
||||
}
|
||||
|
||||
class MockNanIface : public WifiNanIface {
|
||||
public:
|
||||
MockNanIface(const std::string& ifname, bool is_dedicated_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
|
||||
: WifiNanIface(ifname, is_dedicated_iface, legacy_hal, iface_util) {}
|
||||
|
||||
static std::shared_ptr<MockNanIface> createMock(
|
||||
const std::string& ifname, bool is_dedicated_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) {
|
||||
std::shared_ptr<MockNanIface> ptr = ndk::SharedRefBase::make<MockNanIface>(
|
||||
ifname, is_dedicated_iface, legacy_hal, iface_util);
|
||||
std::weak_ptr<MockNanIface> weak_ptr_this(ptr);
|
||||
ptr->setWeakPtr(weak_ptr_this);
|
||||
ptr->registerCallbackHandlers();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// Override getEventCallbacks() so that we can return a mocked callback object.
|
||||
std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> getEventCallbacks() override {
|
||||
return {callback_};
|
||||
}
|
||||
|
||||
void setMockCallback(std::shared_ptr<IWifiNanIfaceEventCallback> cb) { callback_ = cb; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<IWifiNanIfaceEventCallback> callback_;
|
||||
};
|
||||
|
||||
class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback {
|
||||
public:
|
||||
ndk::SpAIBinder asBinder() override { return ::ndk::SpAIBinder{}; }
|
||||
bool isRemote() override { return false; }
|
||||
|
||||
::ndk::ScopedAStatus getInterfaceVersion(int32_t* _aidl_return) override {
|
||||
*_aidl_return = 1;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus getInterfaceHash(std::string* _aidl_return) override {
|
||||
*_aidl_return = "some_hash";
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
MOCK_METHOD3(notifyCapabilitiesResponse,
|
||||
ndk::ScopedAStatus(char16_t, const NanStatus&, const NanCapabilities&));
|
||||
MOCK_METHOD2(notifyEnableResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD2(notifyConfigResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD2(notifyDisableResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD3(notifyStartPublishResponse,
|
||||
ndk::ScopedAStatus(char16_t, const NanStatus&, int8_t));
|
||||
MOCK_METHOD2(notifyStopPublishResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD3(notifyStartSubscribeResponse,
|
||||
ndk::ScopedAStatus(char16_t, const NanStatus&, int8_t));
|
||||
MOCK_METHOD2(notifyStopSubscribeResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD2(notifyTransmitFollowupResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD2(notifyCreateDataInterfaceResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD2(notifyDeleteDataInterfaceResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD3(notifyInitiateDataPathResponse,
|
||||
ndk::ScopedAStatus(char16_t, const NanStatus&, int32_t));
|
||||
MOCK_METHOD2(notifyRespondToDataPathIndicationResponse,
|
||||
ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD2(notifyTerminateDataPathResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD1(eventClusterEvent, ndk::ScopedAStatus(const NanClusterEventInd&));
|
||||
MOCK_METHOD1(eventDisabled, ndk::ScopedAStatus(const NanStatus&));
|
||||
MOCK_METHOD2(eventPublishTerminated, ndk::ScopedAStatus(int8_t, const NanStatus&));
|
||||
MOCK_METHOD2(eventSubscribeTerminated, ndk::ScopedAStatus(int8_t, const NanStatus&));
|
||||
MOCK_METHOD1(eventMatch, ndk::ScopedAStatus(const NanMatchInd&));
|
||||
MOCK_METHOD2(eventMatchExpired, ndk::ScopedAStatus(int8_t, int32_t));
|
||||
MOCK_METHOD1(eventFollowupReceived, ndk::ScopedAStatus(const NanFollowupReceivedInd&));
|
||||
MOCK_METHOD2(eventTransmitFollowup, ndk::ScopedAStatus(char16_t, const NanStatus&));
|
||||
MOCK_METHOD1(eventDataPathRequest, ndk::ScopedAStatus(const NanDataPathRequestInd&));
|
||||
MOCK_METHOD1(eventDataPathConfirm, ndk::ScopedAStatus(const NanDataPathConfirmInd&));
|
||||
MOCK_METHOD1(eventDataPathTerminated, ndk::ScopedAStatus(int32_t));
|
||||
MOCK_METHOD1(eventDataPathScheduleUpdate,
|
||||
ndk::ScopedAStatus(const NanDataPathScheduleUpdateInd&));
|
||||
};
|
||||
|
||||
class WifiNanIfaceTest : public Test {
|
||||
protected:
|
||||
legacy_hal::wifi_hal_fn fake_func_table_;
|
||||
std::shared_ptr<NiceMock<::android::wifi_system::MockInterfaceTool>> iface_tool_{
|
||||
new NiceMock<::android::wifi_system::MockInterfaceTool>};
|
||||
std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
|
||||
new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
|
||||
std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
|
||||
new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
|
||||
};
|
||||
|
||||
TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
|
||||
// Ensure that event handlers are registered during nan iface creation.
|
||||
iface_util::IfaceEventHandlers captured_iface_event_handlers = {};
|
||||
EXPECT_CALL(*legacy_hal_, nanRegisterCallbackHandlers(testing::_, testing::_))
|
||||
.WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
|
||||
EXPECT_CALL(*iface_util_, registerIfaceEventHandlers(testing::_, testing::_))
|
||||
.WillOnce(testing::Invoke(bind(CaptureIfaceEventHandlers, std::placeholders::_1,
|
||||
std::placeholders::_2, &captured_iface_event_handlers)));
|
||||
|
||||
// Create nan iface and register a callback.
|
||||
// Note: Since we can't register a callback directly (gTest fails on
|
||||
// AIBinder_linkToDeath), simulate the registration by overriding
|
||||
// getEventCallbacks() to return our mock callback object.
|
||||
std::shared_ptr<MockNanIface> mock_nan_iface =
|
||||
MockNanIface::createMock(kIfaceName, false, legacy_hal_, iface_util_);
|
||||
std::shared_ptr<MockNanIfaceEventCallback> mock_event_callback =
|
||||
ndk::SharedRefBase::make<MockNanIfaceEventCallback>();
|
||||
mock_nan_iface->setMockCallback(mock_event_callback);
|
||||
|
||||
// Ensure that the eventDisabled() function in the mock callback will be invoked.
|
||||
NanStatus expected_nan_status = {NanStatusCode::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
|
||||
EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status)).Times(1);
|
||||
|
||||
// Trigger the iface state toggle callback.
|
||||
captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName);
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
284
wifi/aidl/default/wifi.cpp
Normal file
284
wifi/aidl/default/wifi.cpp
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "aidl_return_util.h"
|
||||
#include "wifi_status_util.h"
|
||||
|
||||
namespace {
|
||||
// Starting Chip ID, will be assigned to primary chip
|
||||
static constexpr int32_t kPrimaryChipId = 0;
|
||||
} // namespace
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
using aidl_return_util::validateAndCall;
|
||||
using aidl_return_util::validateAndCallWithLock;
|
||||
|
||||
Wifi::Wifi(const std::shared_ptr<::android::wifi_system::InterfaceTool> iface_tool,
|
||||
const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
|
||||
const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
|
||||
const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
|
||||
: iface_tool_(iface_tool),
|
||||
legacy_hal_factory_(legacy_hal_factory),
|
||||
mode_controller_(mode_controller),
|
||||
feature_flags_(feature_flags),
|
||||
run_state_(RunState::STOPPED) {}
|
||||
|
||||
bool Wifi::isValid() {
|
||||
// This object is always valid.
|
||||
return true;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::registerEventCallback(
|
||||
const std::shared_ptr<IWifiEventCallback>& in_callback) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
|
||||
&Wifi::registerEventCallbackInternal, in_callback);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::isStarted(bool* _aidl_return) {
|
||||
*_aidl_return = (run_state_ != RunState::STOPPED);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::start() {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::stop() {
|
||||
return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::getChipIds(std::vector<int32_t>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipIdsInternal,
|
||||
_aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::getChip(int32_t in_chipId, std::shared_ptr<IWifiChip>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipInternal,
|
||||
_aidl_return, in_chipId);
|
||||
}
|
||||
|
||||
binder_status_t Wifi::dump(int fd, const char** args, uint32_t numArgs) {
|
||||
LOG(INFO) << "-----------Debug was called----------------";
|
||||
if (chips_.size() == 0) {
|
||||
LOG(INFO) << "No chips to display.";
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
for (std::shared_ptr<WifiChip> chip : chips_) {
|
||||
if (!chip.get()) continue;
|
||||
chip->dump(fd, args, numArgs);
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::registerEventCallbackInternal(
|
||||
const std::shared_ptr<IWifiEventCallback>& event_callback) {
|
||||
if (!event_cb_handler_.addCallback(event_callback)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::startInternal() {
|
||||
if (run_state_ == RunState::STARTED) {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
} else if (run_state_ == RunState::STOPPING) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
|
||||
}
|
||||
ndk::ScopedAStatus wifi_status = initializeModeControllerAndLegacyHal();
|
||||
if (wifi_status.isOk()) {
|
||||
// Register the callback for subsystem restart
|
||||
const auto& on_subsystem_restart_callback = [this](const std::string& error) {
|
||||
ndk::ScopedAStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
|
||||
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
||||
LOG(INFO) << "Attempting to invoke onSubsystemRestart "
|
||||
"callback";
|
||||
WifiStatusCode errorCode =
|
||||
static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
|
||||
if (!callback->onSubsystemRestart(errorCode).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke onSubsystemRestart callback";
|
||||
} else {
|
||||
LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
|
||||
"callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Create the chip instance once the HAL is started.
|
||||
int32_t chipId = kPrimaryChipId;
|
||||
for (auto& hal : legacy_hals_) {
|
||||
chips_.push_back(
|
||||
WifiChip::create(chipId, chipId == kPrimaryChipId, hal, mode_controller_,
|
||||
std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
|
||||
feature_flags_, on_subsystem_restart_callback));
|
||||
chipId++;
|
||||
}
|
||||
run_state_ = RunState::STARTED;
|
||||
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
||||
if (!callback->onStart().isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke onStart callback";
|
||||
};
|
||||
}
|
||||
LOG(INFO) << "Wifi HAL started";
|
||||
} else {
|
||||
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
||||
WifiStatusCode errorCode =
|
||||
static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
|
||||
if (!callback->onFailure(errorCode).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke onFailure callback";
|
||||
}
|
||||
}
|
||||
LOG(ERROR) << "Wifi HAL start failed";
|
||||
// Clear the event callback objects since the HAL start failed.
|
||||
event_cb_handler_.invalidate();
|
||||
}
|
||||
return wifi_status;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::stopInternal(
|
||||
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
|
||||
if (run_state_ == RunState::STOPPED) {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
} else if (run_state_ == RunState::STOPPING) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
|
||||
}
|
||||
// Clear the chip object and its child objects since the HAL is now
|
||||
// stopped.
|
||||
for (auto& chip : chips_) {
|
||||
if (chip.get()) {
|
||||
chip->invalidate();
|
||||
chip.reset();
|
||||
}
|
||||
}
|
||||
chips_.clear();
|
||||
ndk::ScopedAStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock);
|
||||
if (wifi_status.isOk()) {
|
||||
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
||||
if (!callback->onStop().isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke onStop callback";
|
||||
};
|
||||
}
|
||||
LOG(INFO) << "Wifi HAL stopped";
|
||||
} else {
|
||||
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
||||
WifiStatusCode errorCode =
|
||||
static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
|
||||
if (!callback->onFailure(errorCode).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke onFailure callback";
|
||||
}
|
||||
}
|
||||
LOG(ERROR) << "Wifi HAL stop failed";
|
||||
}
|
||||
// Clear the event callback objects since the HAL is now stopped.
|
||||
event_cb_handler_.invalidate();
|
||||
return wifi_status;
|
||||
}
|
||||
|
||||
std::pair<std::vector<int32_t>, ndk::ScopedAStatus> Wifi::getChipIdsInternal() {
|
||||
std::vector<int32_t> chip_ids;
|
||||
|
||||
for (auto& chip : chips_) {
|
||||
int32_t chip_id = getChipIdFromWifiChip(chip);
|
||||
if (chip_id != INT32_MAX) chip_ids.emplace_back(chip_id);
|
||||
}
|
||||
return {std::move(chip_ids), ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
std::pair<std::shared_ptr<IWifiChip>, ndk::ScopedAStatus> Wifi::getChipInternal(int32_t chip_id) {
|
||||
for (auto& chip : chips_) {
|
||||
int32_t cand_id = getChipIdFromWifiChip(chip);
|
||||
if ((cand_id != INT32_MAX) && (cand_id == chip_id)) return {chip, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::initializeModeControllerAndLegacyHal() {
|
||||
if (!mode_controller_->initialize()) {
|
||||
LOG(ERROR) << "Failed to initialize firmware mode controller";
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
|
||||
legacy_hals_ = legacy_hal_factory_->getHals();
|
||||
if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
int index = 0; // for failure log
|
||||
for (auto& hal : legacy_hals_) {
|
||||
legacy_hal::wifi_error legacy_status = hal->initialize();
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
// Currently WifiLegacyHal::initialize does not allocate extra mem,
|
||||
// only initializes the function table. If this changes, need to
|
||||
// implement WifiLegacyHal::deinitialize and deinitalize the
|
||||
// HALs already initialized
|
||||
LOG(ERROR) << "Failed to initialize legacy HAL index: " << index
|
||||
<< " error: " << legacyErrorToString(legacy_status);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Wifi::stopLegacyHalAndDeinitializeModeController(
|
||||
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal::WIFI_SUCCESS;
|
||||
int index = 0;
|
||||
|
||||
run_state_ = RunState::STOPPING;
|
||||
for (auto& hal : legacy_hals_) {
|
||||
legacy_hal::wifi_error tmp = hal->stop(lock, [&]() {});
|
||||
if (tmp != legacy_hal::WIFI_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to stop legacy HAL index: " << index
|
||||
<< " error: " << legacyErrorToString(legacy_status);
|
||||
legacy_status = tmp;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
run_state_ = RunState::STOPPED;
|
||||
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
LOG(ERROR) << "One or more legacy HALs failed to stop";
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
if (!mode_controller_->deinitialize()) {
|
||||
LOG(ERROR) << "Failed to deinitialize firmware mode controller";
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
int32_t Wifi::getChipIdFromWifiChip(std::shared_ptr<WifiChip>& chip) {
|
||||
int32_t chip_id = INT32_MAX;
|
||||
if (chip.get()) {
|
||||
ndk::ScopedAStatus status = chip->getId(&chip_id);
|
||||
if (!status.isOk()) {
|
||||
// Reset value if operation failed.
|
||||
chip_id = INT32_MAX;
|
||||
}
|
||||
}
|
||||
return chip_id;
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
96
wifi/aidl/default/wifi.h
Normal file
96
wifi/aidl/default/wifi.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_H_
|
||||
#define WIFI_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/BnWifi.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <utils/Looper.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "aidl_callback_util.h"
|
||||
#include "wifi_chip.h"
|
||||
#include "wifi_feature_flags.h"
|
||||
#include "wifi_legacy_hal.h"
|
||||
#include "wifi_legacy_hal_factory.h"
|
||||
#include "wifi_mode_controller.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
/**
|
||||
* Root AIDL interface object used to control the Wifi HAL.
|
||||
*/
|
||||
class Wifi : public BnWifi {
|
||||
public:
|
||||
Wifi(const std::shared_ptr<::android::wifi_system::InterfaceTool> iface_tool,
|
||||
const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
|
||||
const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
|
||||
const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags);
|
||||
|
||||
bool isValid();
|
||||
|
||||
// AIDL methods exposed.
|
||||
ndk::ScopedAStatus registerEventCallback(
|
||||
const std::shared_ptr<IWifiEventCallback>& in_callback) override;
|
||||
ndk::ScopedAStatus isStarted(bool* _aidl_return) override;
|
||||
ndk::ScopedAStatus start() override;
|
||||
ndk::ScopedAStatus stop() override;
|
||||
ndk::ScopedAStatus getChipIds(std::vector<int32_t>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getChip(int32_t in_chipId,
|
||||
std::shared_ptr<IWifiChip>* _aidl_return) override;
|
||||
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
|
||||
|
||||
private:
|
||||
enum class RunState { STOPPED, STARTED, STOPPING };
|
||||
|
||||
// Corresponding worker functions for the AIDL methods.
|
||||
ndk::ScopedAStatus registerEventCallbackInternal(
|
||||
const std::shared_ptr<IWifiEventCallback>& event_callback __unused);
|
||||
ndk::ScopedAStatus startInternal();
|
||||
ndk::ScopedAStatus stopInternal(std::unique_lock<std::recursive_mutex>* lock);
|
||||
std::pair<std::vector<int32_t>, ndk::ScopedAStatus> getChipIdsInternal();
|
||||
std::pair<std::shared_ptr<IWifiChip>, ndk::ScopedAStatus> getChipInternal(int32_t chip_id);
|
||||
|
||||
ndk::ScopedAStatus initializeModeControllerAndLegacyHal();
|
||||
ndk::ScopedAStatus stopLegacyHalAndDeinitializeModeController(
|
||||
std::unique_lock<std::recursive_mutex>* lock);
|
||||
int32_t getChipIdFromWifiChip(std::shared_ptr<WifiChip>& chip);
|
||||
|
||||
// Instance is created in this root level |IWifi| AIDL interface object
|
||||
// and shared with all the child AIDL interface objects.
|
||||
std::shared_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
|
||||
std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory_;
|
||||
std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
|
||||
std::vector<std::shared_ptr<legacy_hal::WifiLegacyHal>> legacy_hals_;
|
||||
std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
|
||||
RunState run_state_;
|
||||
std::vector<std::shared_ptr<WifiChip>> chips_;
|
||||
aidl_callback_util::AidlCallbackHandler<IWifiEventCallback> event_cb_handler_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Wifi);
|
||||
};
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_H_
|
||||
190
wifi/aidl/default/wifi_ap_iface.cpp
Normal file
190
wifi/aidl/default/wifi_ap_iface.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi_ap_iface.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "aidl_return_util.h"
|
||||
#include "aidl_struct_util.h"
|
||||
#include "wifi_status_util.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
using aidl_return_util::validateAndCall;
|
||||
|
||||
WifiApIface::WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
|
||||
: ifname_(ifname),
|
||||
instances_(instances),
|
||||
legacy_hal_(legacy_hal),
|
||||
iface_util_(iface_util),
|
||||
is_valid_(true) {}
|
||||
|
||||
void WifiApIface::invalidate() {
|
||||
legacy_hal_.reset();
|
||||
is_valid_ = false;
|
||||
}
|
||||
|
||||
bool WifiApIface::isValid() {
|
||||
return is_valid_;
|
||||
}
|
||||
|
||||
std::string WifiApIface::getName() {
|
||||
return ifname_;
|
||||
}
|
||||
|
||||
void WifiApIface::removeInstance(std::string instance) {
|
||||
instances_.erase(std::remove(instances_.begin(), instances_.end(), instance), instances_.end());
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiApIface::getName(std::string* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiApIface::getNameInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiApIface::setCountryCode(const std::array<uint8_t, 2>& in_code) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiApIface::setCountryCodeInternal, in_code);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiApIface::getValidFrequenciesForBand(WifiBand in_band,
|
||||
std::vector<int32_t>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiApIface::getValidFrequenciesForBandInternal, _aidl_return, in_band);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiApIface::setMacAddress(const std::array<uint8_t, 6>& in_mac) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiApIface::setMacAddressInternal, in_mac);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiApIface::getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiApIface::getFactoryMacAddressInternal, _aidl_return,
|
||||
instances_.size() > 0 ? instances_[0] : ifname_);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiApIface::resetToFactoryMacAddress() {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiApIface::resetToFactoryMacAddressInternal);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiApIface::getBridgedInstances(std::vector<std::string>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiApIface::getBridgedInstancesInternal, _aidl_return);
|
||||
}
|
||||
|
||||
std::pair<std::string, ndk::ScopedAStatus> WifiApIface::getNameInternal() {
|
||||
return {ifname_, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiApIface::setCountryCodeInternal(const std::array<uint8_t, 2>& code) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode(
|
||||
instances_.size() > 0 ? instances_[0] : ifname_, code);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
std::pair<std::vector<int32_t>, ndk::ScopedAStatus> WifiApIface::getValidFrequenciesForBandInternal(
|
||||
WifiBand band) {
|
||||
static_assert(sizeof(WifiChannelWidthInMhz) == sizeof(int32_t), "Size mismatch");
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
std::vector<uint32_t> valid_frequencies;
|
||||
std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand(
|
||||
instances_.size() > 0 ? instances_[0] : ifname_,
|
||||
aidl_struct_util::convertAidlWifiBandToLegacy(band));
|
||||
return {std::vector<int32_t>(valid_frequencies.begin(), valid_frequencies.end()),
|
||||
createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiApIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
|
||||
// Support random MAC up to 2 interfaces
|
||||
if (instances_.size() == 2) {
|
||||
int rbyte = 1;
|
||||
for (auto const& intf : instances_) {
|
||||
std::array<uint8_t, 6> rmac = mac;
|
||||
// reverse the bits to avoid collision
|
||||
rmac[rbyte] = 0xff - rmac[rbyte];
|
||||
if (!iface_util_.lock()->setMacAddress(intf, rmac)) {
|
||||
LOG(INFO) << "Failed to set random mac address on " << intf;
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
rbyte++;
|
||||
}
|
||||
}
|
||||
// It also needs to set mac address for bridged interface, otherwise the mac
|
||||
// address of bridged interface will be changed after one of instance
|
||||
// down.
|
||||
if (!iface_util_.lock()->setMacAddress(ifname_, mac)) {
|
||||
LOG(ERROR) << "Fail to config MAC for interface " << ifname_;
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> WifiApIface::getFactoryMacAddressInternal(
|
||||
const std::string& ifaceName) {
|
||||
std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifaceName);
|
||||
if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
|
||||
return {mac, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {mac, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiApIface::resetToFactoryMacAddressInternal() {
|
||||
std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getMacResult;
|
||||
if (instances_.size() == 2) {
|
||||
for (auto const& intf : instances_) {
|
||||
getMacResult = getFactoryMacAddressInternal(intf);
|
||||
LOG(DEBUG) << "Reset MAC to factory MAC on " << intf;
|
||||
if (!getMacResult.second.isOk() ||
|
||||
!iface_util_.lock()->setMacAddress(intf, getMacResult.first)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
}
|
||||
// We need to set mac address for bridged interface, otherwise the mac
|
||||
// address of the bridged interface will be changed after one of the
|
||||
// instances goes down. Thus we are generating a random MAC address for
|
||||
// the bridged interface even if we got the request to reset the Factory
|
||||
// MAC. This is because the bridged interface is an internal interface
|
||||
// for the operation of bpf and other networking operations.
|
||||
if (!iface_util_.lock()->setMacAddress(ifname_,
|
||||
iface_util_.lock()->createRandomMacAddress())) {
|
||||
LOG(ERROR) << "Fail to config MAC for bridged interface " << ifname_;
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
} else {
|
||||
getMacResult = getFactoryMacAddressInternal(ifname_);
|
||||
LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_;
|
||||
if (!getMacResult.second.isOk() ||
|
||||
!iface_util_.lock()->setMacAddress(ifname_, getMacResult.first)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiApIface::getBridgedInstancesInternal() {
|
||||
return {instances_, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
81
wifi/aidl/default/wifi_ap_iface.h
Normal file
81
wifi/aidl/default/wifi_ap_iface.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_AP_IFACE_H_
|
||||
#define WIFI_AP_IFACE_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/BnWifiApIface.h>
|
||||
#include <android-base/macros.h>
|
||||
|
||||
#include "wifi_iface_util.h"
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
/**
|
||||
* AIDL interface object used to control an AP Iface instance.
|
||||
*/
|
||||
class WifiApIface : public BnWifiApIface {
|
||||
public:
|
||||
WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
|
||||
// Refer to |WifiChip::invalidate()|.
|
||||
void invalidate();
|
||||
bool isValid();
|
||||
std::string getName();
|
||||
void removeInstance(std::string instance);
|
||||
|
||||
// AIDL methods exposed.
|
||||
ndk::ScopedAStatus getName(std::string* _aidl_return) override;
|
||||
ndk::ScopedAStatus setCountryCode(const std::array<uint8_t, 2>& in_code) override;
|
||||
ndk::ScopedAStatus getValidFrequenciesForBand(WifiBand in_band,
|
||||
std::vector<int32_t>* _aidl_return) override;
|
||||
ndk::ScopedAStatus setMacAddress(const std::array<uint8_t, 6>& in_mac) override;
|
||||
ndk::ScopedAStatus getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) override;
|
||||
ndk::ScopedAStatus resetToFactoryMacAddress() override;
|
||||
ndk::ScopedAStatus getBridgedInstances(std::vector<std::string>* _aidl_return) override;
|
||||
|
||||
private:
|
||||
// Corresponding worker functions for the AIDL methods.
|
||||
std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
|
||||
ndk::ScopedAStatus setCountryCodeInternal(const std::array<uint8_t, 2>& code);
|
||||
std::pair<std::vector<int32_t>, ndk::ScopedAStatus> getValidFrequenciesForBandInternal(
|
||||
WifiBand band);
|
||||
ndk::ScopedAStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
|
||||
std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getFactoryMacAddressInternal(
|
||||
const std::string& ifaceName);
|
||||
ndk::ScopedAStatus resetToFactoryMacAddressInternal();
|
||||
std::pair<std::vector<std::string>, ndk::ScopedAStatus> getBridgedInstancesInternal();
|
||||
|
||||
std::string ifname_;
|
||||
std::vector<std::string> instances_;
|
||||
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
|
||||
std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
|
||||
bool is_valid_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WifiApIface);
|
||||
};
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_AP_IFACE_H_
|
||||
1910
wifi/aidl/default/wifi_chip.cpp
Normal file
1910
wifi/aidl/default/wifi_chip.cpp
Normal file
File diff suppressed because it is too large
Load Diff
287
wifi/aidl/default/wifi_chip.h
Normal file
287
wifi/aidl/default/wifi_chip.h
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_CHIP_H_
|
||||
#define WIFI_CHIP_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/BnWifiChip.h>
|
||||
#include <aidl/android/hardware/wifi/IWifiRttController.h>
|
||||
#include <android-base/macros.h>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
#include "aidl_callback_util.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "wifi_ap_iface.h"
|
||||
#include "wifi_feature_flags.h"
|
||||
#include "wifi_legacy_hal.h"
|
||||
#include "wifi_mode_controller.h"
|
||||
#include "wifi_nan_iface.h"
|
||||
#include "wifi_p2p_iface.h"
|
||||
#include "wifi_rtt_controller.h"
|
||||
#include "wifi_sta_iface.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
/**
|
||||
* AIDL interface object used to control a Wifi HAL chip instance.
|
||||
* Since there is only a single chip instance used today, there is no
|
||||
* identifying handle information stored here.
|
||||
*/
|
||||
class WifiChip : public BnWifiChip {
|
||||
public:
|
||||
WifiChip(int32_t chip_id, bool is_primary,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
|
||||
const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
|
||||
const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
|
||||
const std::function<void(const std::string&)>& subsystemCallbackHandler);
|
||||
|
||||
// Factory method - use instead of default constructor.
|
||||
static std::shared_ptr<WifiChip> create(
|
||||
int32_t chip_id, bool is_primary,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
|
||||
const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
|
||||
const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
|
||||
const std::function<void(const std::string&)>& subsystemCallbackHandler);
|
||||
|
||||
// AIDL does not provide a built-in mechanism to let the server invalidate
|
||||
// an AIDL interface object after creation. If any client process holds onto
|
||||
// a reference to the object in their context, any method calls on that
|
||||
// reference will continue to be directed to the server.
|
||||
//
|
||||
// However Wifi HAL needs to control the lifetime of these objects. So, add
|
||||
// a public |invalidate| method to |WifiChip| and its child objects. This
|
||||
// will be used to mark an object invalid when either:
|
||||
// a) Wifi HAL is stopped, or
|
||||
// b) Wifi Chip is reconfigured.
|
||||
//
|
||||
// All AIDL method implementations should check if the object is still
|
||||
// marked valid before processing them.
|
||||
void invalidate();
|
||||
bool isValid();
|
||||
std::set<std::shared_ptr<IWifiChipEventCallback>> getEventCallbacks();
|
||||
|
||||
// AIDL methods exposed.
|
||||
ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
|
||||
ndk::ScopedAStatus registerEventCallback(
|
||||
const std::shared_ptr<IWifiChipEventCallback>& in_callback) override;
|
||||
ndk::ScopedAStatus getCapabilities(IWifiChip::ChipCapabilityMask* _aidl_return) override;
|
||||
ndk::ScopedAStatus getAvailableModes(std::vector<IWifiChip::ChipMode>* _aidl_return) override;
|
||||
ndk::ScopedAStatus configureChip(int32_t in_modeId) override;
|
||||
ndk::ScopedAStatus getMode(int32_t* _aidl_return) override;
|
||||
ndk::ScopedAStatus requestChipDebugInfo(IWifiChip::ChipDebugInfo* _aidl_return) override;
|
||||
ndk::ScopedAStatus requestDriverDebugDump(std::vector<uint8_t>* _aidl_return) override;
|
||||
ndk::ScopedAStatus requestFirmwareDebugDump(std::vector<uint8_t>* _aidl_return) override;
|
||||
ndk::ScopedAStatus createApIface(std::shared_ptr<IWifiApIface>* _aidl_return) override;
|
||||
ndk::ScopedAStatus createBridgedApIface(std::shared_ptr<IWifiApIface>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getApIfaceNames(std::vector<std::string>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getApIface(const std::string& in_ifname,
|
||||
std::shared_ptr<IWifiApIface>* _aidl_return) override;
|
||||
ndk::ScopedAStatus removeApIface(const std::string& in_ifname) override;
|
||||
ndk::ScopedAStatus removeIfaceInstanceFromBridgedApIface(
|
||||
const std::string& in_brIfaceName, const std::string& in_ifaceInstanceName) override;
|
||||
ndk::ScopedAStatus createNanIface(std::shared_ptr<IWifiNanIface>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getNanIfaceNames(std::vector<std::string>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getNanIface(const std::string& in_ifname,
|
||||
std::shared_ptr<IWifiNanIface>* _aidl_return) override;
|
||||
ndk::ScopedAStatus removeNanIface(const std::string& in_ifname) override;
|
||||
ndk::ScopedAStatus createP2pIface(std::shared_ptr<IWifiP2pIface>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getP2pIfaceNames(std::vector<std::string>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getP2pIface(const std::string& in_ifname,
|
||||
std::shared_ptr<IWifiP2pIface>* _aidl_return) override;
|
||||
ndk::ScopedAStatus removeP2pIface(const std::string& in_ifname) override;
|
||||
ndk::ScopedAStatus createStaIface(std::shared_ptr<IWifiStaIface>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getStaIfaceNames(std::vector<std::string>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getStaIface(const std::string& in_ifname,
|
||||
std::shared_ptr<IWifiStaIface>* _aidl_return) override;
|
||||
ndk::ScopedAStatus removeStaIface(const std::string& in_ifname) override;
|
||||
ndk::ScopedAStatus createRttController(
|
||||
const std::shared_ptr<IWifiStaIface>& in_boundIface,
|
||||
std::shared_ptr<IWifiRttController>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getDebugRingBuffersStatus(
|
||||
std::vector<WifiDebugRingBufferStatus>* _aidl_return) override;
|
||||
ndk::ScopedAStatus startLoggingToDebugRingBuffer(
|
||||
const std::string& in_ringName, WifiDebugRingBufferVerboseLevel in_verboseLevel,
|
||||
int32_t in_maxIntervalInSec, int32_t in_minDataSizeInBytes) override;
|
||||
ndk::ScopedAStatus forceDumpToDebugRingBuffer(const std::string& in_ringName) override;
|
||||
ndk::ScopedAStatus flushRingBufferToFile() override;
|
||||
ndk::ScopedAStatus stopLoggingToDebugRingBuffer() override;
|
||||
ndk::ScopedAStatus getDebugHostWakeReasonStats(
|
||||
WifiDebugHostWakeReasonStats* _aidl_return) override;
|
||||
ndk::ScopedAStatus enableDebugErrorAlerts(bool in_enable) override;
|
||||
ndk::ScopedAStatus selectTxPowerScenario(IWifiChip::TxPowerScenario in_scenario) override;
|
||||
ndk::ScopedAStatus resetTxPowerScenario() override;
|
||||
ndk::ScopedAStatus setLatencyMode(IWifiChip::LatencyMode in_mode) override;
|
||||
ndk::ScopedAStatus setMultiStaPrimaryConnection(const std::string& in_ifName) override;
|
||||
ndk::ScopedAStatus setMultiStaUseCase(IWifiChip::MultiStaUseCase in_useCase) override;
|
||||
ndk::ScopedAStatus setCoexUnsafeChannels(
|
||||
const std::vector<IWifiChip::CoexUnsafeChannel>& in_unsafeChannels,
|
||||
CoexRestriction in_restrictions) override;
|
||||
ndk::ScopedAStatus setCountryCode(const std::array<uint8_t, 2>& in_code) override;
|
||||
ndk::ScopedAStatus getUsableChannels(WifiBand in_band, WifiIfaceMode in_ifaceModeMask,
|
||||
UsableChannelFilter in_filterMask,
|
||||
std::vector<WifiUsableChannel>* _aidl_return) override;
|
||||
ndk::ScopedAStatus triggerSubsystemRestart() override;
|
||||
ndk::ScopedAStatus getSupportedRadioCombinationsMatrix(
|
||||
WifiRadioCombinationMatrix* _aidl_return) override;
|
||||
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
|
||||
|
||||
private:
|
||||
void invalidateAndRemoveAllIfaces();
|
||||
// When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are
|
||||
// invalidated & removed.
|
||||
void invalidateAndRemoveDependencies(const std::string& removed_iface_name);
|
||||
|
||||
// Corresponding worker functions for the AIDL methods.
|
||||
std::pair<int32_t, ndk::ScopedAStatus> getIdInternal();
|
||||
ndk::ScopedAStatus registerEventCallbackInternal(
|
||||
const std::shared_ptr<IWifiChipEventCallback>& event_callback);
|
||||
std::pair<IWifiChip::ChipCapabilityMask, ndk::ScopedAStatus> getCapabilitiesInternal();
|
||||
std::pair<std::vector<IWifiChip::ChipMode>, ndk::ScopedAStatus> getAvailableModesInternal();
|
||||
ndk::ScopedAStatus configureChipInternal(std::unique_lock<std::recursive_mutex>* lock,
|
||||
int32_t mode_id);
|
||||
std::pair<int32_t, ndk::ScopedAStatus> getModeInternal();
|
||||
std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> requestChipDebugInfoInternal();
|
||||
std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> requestDriverDebugDumpInternal();
|
||||
std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> requestFirmwareDebugDumpInternal();
|
||||
std::shared_ptr<WifiApIface> newWifiApIface(std::string& ifname);
|
||||
ndk::ScopedAStatus createVirtualApInterface(const std::string& apVirtIf);
|
||||
std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> createApIfaceInternal();
|
||||
std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> createBridgedApIfaceInternal();
|
||||
std::pair<std::vector<std::string>, ndk::ScopedAStatus> getApIfaceNamesInternal();
|
||||
std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> getApIfaceInternal(
|
||||
const std::string& ifname);
|
||||
ndk::ScopedAStatus removeApIfaceInternal(const std::string& ifname);
|
||||
ndk::ScopedAStatus removeIfaceInstanceFromBridgedApIfaceInternal(
|
||||
const std::string& brIfaceName, const std::string& ifInstanceName);
|
||||
std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> createNanIfaceInternal();
|
||||
std::pair<std::vector<std::string>, ndk::ScopedAStatus> getNanIfaceNamesInternal();
|
||||
std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> getNanIfaceInternal(
|
||||
const std::string& ifname);
|
||||
ndk::ScopedAStatus removeNanIfaceInternal(const std::string& ifname);
|
||||
std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> createP2pIfaceInternal();
|
||||
std::pair<std::vector<std::string>, ndk::ScopedAStatus> getP2pIfaceNamesInternal();
|
||||
std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> getP2pIfaceInternal(
|
||||
const std::string& ifname);
|
||||
ndk::ScopedAStatus removeP2pIfaceInternal(const std::string& ifname);
|
||||
std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> createStaIfaceInternal();
|
||||
std::pair<std::vector<std::string>, ndk::ScopedAStatus> getStaIfaceNamesInternal();
|
||||
std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> getStaIfaceInternal(
|
||||
const std::string& ifname);
|
||||
ndk::ScopedAStatus removeStaIfaceInternal(const std::string& ifname);
|
||||
std::pair<std::shared_ptr<IWifiRttController>, ndk::ScopedAStatus> createRttControllerInternal(
|
||||
const std::shared_ptr<IWifiStaIface>& bound_iface);
|
||||
std::pair<std::vector<WifiDebugRingBufferStatus>, ndk::ScopedAStatus>
|
||||
getDebugRingBuffersStatusInternal();
|
||||
ndk::ScopedAStatus startLoggingToDebugRingBufferInternal(
|
||||
const std::string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
|
||||
uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes);
|
||||
ndk::ScopedAStatus forceDumpToDebugRingBufferInternal(const std::string& ring_name);
|
||||
ndk::ScopedAStatus flushRingBufferToFileInternal();
|
||||
ndk::ScopedAStatus stopLoggingToDebugRingBufferInternal();
|
||||
std::pair<WifiDebugHostWakeReasonStats, ndk::ScopedAStatus>
|
||||
getDebugHostWakeReasonStatsInternal();
|
||||
ndk::ScopedAStatus enableDebugErrorAlertsInternal(bool enable);
|
||||
ndk::ScopedAStatus selectTxPowerScenarioInternal(IWifiChip::TxPowerScenario scenario);
|
||||
ndk::ScopedAStatus resetTxPowerScenarioInternal();
|
||||
ndk::ScopedAStatus setLatencyModeInternal(IWifiChip::LatencyMode mode);
|
||||
ndk::ScopedAStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname);
|
||||
ndk::ScopedAStatus setMultiStaUseCaseInternal(IWifiChip::MultiStaUseCase use_case);
|
||||
ndk::ScopedAStatus setCoexUnsafeChannelsInternal(
|
||||
std::vector<IWifiChip::CoexUnsafeChannel> unsafe_channels,
|
||||
CoexRestriction restrictions);
|
||||
ndk::ScopedAStatus setCountryCodeInternal(const std::array<uint8_t, 2>& in_code);
|
||||
std::pair<std::vector<WifiUsableChannel>, ndk::ScopedAStatus> getUsableChannelsInternal(
|
||||
WifiBand band, WifiIfaceMode ifaceModeMask, UsableChannelFilter filterMask);
|
||||
ndk::ScopedAStatus handleChipConfiguration(std::unique_lock<std::recursive_mutex>* lock,
|
||||
int32_t mode_id);
|
||||
ndk::ScopedAStatus registerDebugRingBufferCallback();
|
||||
ndk::ScopedAStatus registerRadioModeChangeCallback();
|
||||
|
||||
std::vector<ChipConcurrencyCombination> getCurrentModeConcurrencyCombinations();
|
||||
std::map<IfaceConcurrencyType, size_t> getCurrentConcurrencyCombination();
|
||||
std::vector<std::map<IfaceConcurrencyType, size_t>> expandConcurrencyCombinations(
|
||||
const ChipConcurrencyCombination& combination);
|
||||
bool canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
|
||||
const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
|
||||
IfaceConcurrencyType requested_type);
|
||||
bool canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType requested_type);
|
||||
bool canExpandedConcurrencyComboSupportConcurrencyCombo(
|
||||
const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
|
||||
const std::map<IfaceConcurrencyType, size_t>& req_combo);
|
||||
bool canCurrentModeSupportConcurrencyCombo(
|
||||
const std::map<IfaceConcurrencyType, size_t>& req_combo);
|
||||
bool canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type);
|
||||
|
||||
bool isValidModeId(int32_t mode_id);
|
||||
bool isStaApConcurrencyAllowedInCurrentMode();
|
||||
bool isDualStaConcurrencyAllowedInCurrentMode();
|
||||
uint32_t startIdxOfApIface();
|
||||
std::string getFirstActiveWlanIfaceName();
|
||||
std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx);
|
||||
std::string allocateApIfaceName();
|
||||
std::vector<std::string> allocateBridgedApInstanceNames();
|
||||
std::string allocateStaIfaceName();
|
||||
bool writeRingbufferFilesInternal();
|
||||
std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx);
|
||||
void invalidateAndClearBridgedApAll();
|
||||
void invalidateAndClearBridgedAp(const std::string& br_name);
|
||||
bool findUsingNameFromBridgedApInstances(const std::string& name);
|
||||
ndk::ScopedAStatus triggerSubsystemRestartInternal();
|
||||
std::pair<WifiRadioCombinationMatrix, ndk::ScopedAStatus>
|
||||
getSupportedRadioCombinationsMatrixInternal();
|
||||
void setWeakPtr(std::weak_ptr<WifiChip> ptr);
|
||||
|
||||
int32_t chip_id_;
|
||||
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
|
||||
std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
|
||||
std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
|
||||
std::vector<std::shared_ptr<WifiApIface>> ap_ifaces_;
|
||||
std::vector<std::shared_ptr<WifiNanIface>> nan_ifaces_;
|
||||
std::vector<std::shared_ptr<WifiP2pIface>> p2p_ifaces_;
|
||||
std::vector<std::shared_ptr<WifiStaIface>> sta_ifaces_;
|
||||
std::vector<std::shared_ptr<WifiRttController>> rtt_controllers_;
|
||||
std::map<std::string, Ringbuffer> ringbuffer_map_;
|
||||
bool is_valid_;
|
||||
// Members pertaining to chip configuration.
|
||||
int32_t current_mode_id_;
|
||||
std::mutex lock_t;
|
||||
std::vector<IWifiChip::ChipMode> modes_;
|
||||
// The legacy ring buffer callback API has only a global callback
|
||||
// registration mechanism. Use this to check if we have already
|
||||
// registered a callback.
|
||||
bool debug_ring_buffer_cb_registered_;
|
||||
aidl_callback_util::AidlCallbackHandler<IWifiChipEventCallback> event_cb_handler_;
|
||||
std::weak_ptr<WifiChip> weak_ptr_this_;
|
||||
|
||||
const std::function<void(const std::string&)> subsystemCallbackHandler_;
|
||||
std::map<std::string, std::vector<std::string>> br_ifaces_ap_instances_;
|
||||
DISALLOW_COPY_AND_ASSIGN(WifiChip);
|
||||
};
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_CHIP_H_
|
||||
228
wifi/aidl/default/wifi_feature_flags.cpp
Normal file
228
wifi/aidl/default/wifi_feature_flags.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
#include "wifi_feature_flags.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace feature_flags {
|
||||
|
||||
/* The chip may either have a single mode supporting any number of combinations,
|
||||
* or a fixed dual-mode (so it involves firmware loading to switch between
|
||||
* modes) setting. If there is a need to support more modes, it needs to be
|
||||
* implemented manually in WiFi HAL (see changeFirmwareMode in
|
||||
* WifiChip::handleChipConfiguration).
|
||||
*
|
||||
* Supported combinations are defined in device's makefile, for example:
|
||||
* WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}},
|
||||
* WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}}
|
||||
* What this means:
|
||||
* Interface concurrency combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface
|
||||
* operations.
|
||||
* Interface concurrency combination 2: 1 STA and 2 AP concurrent iface operations.
|
||||
*
|
||||
* For backward compatibility, the following makefile flags can be used to
|
||||
* generate combinations list:
|
||||
* - WIFI_HIDL_FEATURE_DUAL_INTERFACE
|
||||
* - WIFI_HIDL_FEATURE_DISABLE_AP
|
||||
* - WIFI_HIDL_FEATURE_AWARE
|
||||
* However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided.
|
||||
* With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with
|
||||
* two concurrency combinations:
|
||||
* Interface Concurrency Combination 1: Will support 1 STA and 1 P2P or NAN (optional)
|
||||
* concurrent iface operations.
|
||||
* Interface Concurrency Combination 2: Will support 1 STA and 1 AP concurrent
|
||||
* iface operations.
|
||||
*
|
||||
* The only dual-mode configuration supported is for alternating STA and AP
|
||||
* mode, that may involve firmware reloading. In such case, there are 2 separate
|
||||
* modes of operation with 1 concurrency combination each:
|
||||
* Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional)
|
||||
* concurrent iface operations.
|
||||
* Mode 2 (AP mode): Will support 1 AP iface operation.
|
||||
*
|
||||
* If Aware is enabled, the concurrency combination will be modified to support either
|
||||
* P2P or NAN in place of just P2P.
|
||||
*/
|
||||
// clang-format off
|
||||
#ifdef WIFI_HAL_INTERFACE_COMBINATIONS
|
||||
constexpr int kMainModeId = chip_mode_ids::kV3;
|
||||
#elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE)
|
||||
// former V2 (fixed dual interface) setup expressed as V3
|
||||
constexpr int kMainModeId = chip_mode_ids::kV3;
|
||||
# ifdef WIFI_HIDL_FEATURE_DISABLE_AP
|
||||
# ifdef WIFI_HIDL_FEATURE_AWARE
|
||||
// 1 STA + 1 of (P2P or NAN)
|
||||
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
|
||||
# else
|
||||
// 1 STA + 1 P2P
|
||||
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
|
||||
# endif
|
||||
# else
|
||||
# ifdef WIFI_HIDL_FEATURE_AWARE
|
||||
// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
|
||||
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
|
||||
{{{STA}, 1}, {{P2P, NAN}, 1}}
|
||||
# else
|
||||
// (1 STA + 1 AP) or (1 STA + 1 P2P)
|
||||
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
|
||||
{{{STA}, 1}, {{P2P}, 1}}
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
// V1 (fixed single interface, dual-mode chip)
|
||||
constexpr int kMainModeId = chip_mode_ids::kV1Sta;
|
||||
# ifdef WIFI_HIDL_FEATURE_AWARE
|
||||
// 1 STA + 1 of (P2P or NAN)
|
||||
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
|
||||
# else
|
||||
// 1 STA + 1 P2P
|
||||
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
|
||||
# endif
|
||||
|
||||
# ifndef WIFI_HIDL_FEATURE_DISABLE_AP
|
||||
# define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}}
|
||||
# endif
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
// Convert from the legacy format (used by the WIFI_HAL_INTERFACE_COMBINATIONS
|
||||
// config variable) to a list of ChipConcurrencyCombination objects.
|
||||
std::vector<IWifiChip::ChipConcurrencyCombination> legacyToChipConcurrencyComboList(
|
||||
std::vector<std::vector<IWifiChip::ChipConcurrencyCombinationLimit>> legacyLimits) {
|
||||
std::vector<IWifiChip::ChipConcurrencyCombination> combos;
|
||||
for (auto& legacyLimit : legacyLimits) {
|
||||
IWifiChip::ChipConcurrencyCombination combo = {legacyLimit};
|
||||
combos.push_back(combo);
|
||||
}
|
||||
return combos;
|
||||
}
|
||||
|
||||
#define STA IfaceConcurrencyType::STA
|
||||
#define AP IfaceConcurrencyType::AP
|
||||
#define AP_BRIDGED IfaceConcurrencyType::AP_BRIDGED
|
||||
#define P2P IfaceConcurrencyType::P2P
|
||||
#define NAN IfaceConcurrencyType::NAN_IFACE
|
||||
static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
|
||||
{kMainModeId, legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS})},
|
||||
#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
|
||||
{chip_mode_ids::kV1Ap,
|
||||
legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
|
||||
#endif
|
||||
};
|
||||
|
||||
static const std::vector<IWifiChip::ChipMode> kChipModesSecondary{
|
||||
#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP
|
||||
{chip_mode_ids::kV3,
|
||||
legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
|
||||
#endif
|
||||
};
|
||||
|
||||
constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
|
||||
"persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
|
||||
// List of pre-defined concurrency combinations that can be enabled at runtime via
|
||||
// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
|
||||
// corresponding index value.
|
||||
static const std::vector<std::pair<std::string, std::vector<IWifiChip::ChipMode>>> kDebugChipModes{
|
||||
// Legacy combination - No STA/AP concurrencies.
|
||||
// 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
|
||||
{"No STA/AP Concurrency",
|
||||
{{kMainModeId,
|
||||
legacyToChipConcurrencyComboList({{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
|
||||
|
||||
// STA + AP concurrency
|
||||
// 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
|
||||
{"STA + AP Concurrency",
|
||||
{{kMainModeId, legacyToChipConcurrencyComboList(
|
||||
{{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
|
||||
|
||||
// STA + STA concurrency
|
||||
// 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
|
||||
{"Dual STA Concurrency",
|
||||
{{kMainModeId, legacyToChipConcurrencyComboList(
|
||||
{{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
|
||||
|
||||
// AP + AP + STA concurrency
|
||||
// 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
|
||||
{"Dual AP Concurrency",
|
||||
{{kMainModeId, legacyToChipConcurrencyComboList(
|
||||
{{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
|
||||
|
||||
// STA + STA concurrency and AP + AP + STA concurrency
|
||||
// 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
|
||||
{"Dual STA & Dual AP Concurrency",
|
||||
{{kMainModeId, legacyToChipConcurrencyComboList(
|
||||
{{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
|
||||
|
||||
// STA + STA concurrency
|
||||
// 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA))
|
||||
{"Dual STA or STA plus single other interface",
|
||||
{{kMainModeId, legacyToChipConcurrencyComboList(
|
||||
{{{{STA}, 1}, {{P2P, NAN, AP, AP_BRIDGED}, 1}}, {{{STA}, 2}}})}}}};
|
||||
|
||||
#undef STA
|
||||
#undef AP
|
||||
#undef AP_BRIDGED
|
||||
#undef P2P
|
||||
#undef NAN
|
||||
|
||||
#ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
|
||||
#pragma message \
|
||||
"WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
|
||||
"'config_wifi_ap_randomization_supported' in " \
|
||||
"frameworks/base/core/res/res/values/config.xml in the device overlay " \
|
||||
"instead"
|
||||
#endif // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
|
||||
|
||||
WifiFeatureFlags::WifiFeatureFlags() {}
|
||||
|
||||
std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
|
||||
std::array<char, PROPERTY_VALUE_MAX> buffer;
|
||||
auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr);
|
||||
// Debug property not set, use the device preset concurrency combination.
|
||||
if (res <= 0) return kChipModesPrimary;
|
||||
|
||||
// Debug property set, use one of the debug preset concurrency combination.
|
||||
unsigned long idx = std::stoul(buffer.data());
|
||||
if (idx >= kDebugChipModes.size()) {
|
||||
LOG(ERROR) << "Invalid index set in property: "
|
||||
<< kDebugPresetInterfaceCombinationIdxProperty;
|
||||
return kChipModesPrimary;
|
||||
}
|
||||
std::string name;
|
||||
std::vector<IWifiChip::ChipMode> chip_modes;
|
||||
std::tie(name, chip_modes) = kDebugChipModes[idx];
|
||||
LOG(INFO) << "Using debug chip mode: <" << name
|
||||
<< "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty;
|
||||
return chip_modes;
|
||||
}
|
||||
|
||||
std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) {
|
||||
return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
|
||||
}
|
||||
|
||||
} // namespace feature_flags
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
56
wifi/aidl/default/wifi_feature_flags.h
Normal file
56
wifi/aidl/default/wifi_feature_flags.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_FEATURE_FLAGS_H_
|
||||
#define WIFI_FEATURE_FLAGS_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/IWifiChip.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace feature_flags {
|
||||
|
||||
namespace chip_mode_ids {
|
||||
// These mode ID's should be unique (even across combo versions). Refer to
|
||||
// handleChipConfiguration() for its usage.
|
||||
constexpr uint32_t kInvalid = UINT32_MAX;
|
||||
// Mode ID's for V1
|
||||
constexpr uint32_t kV1Sta = 0;
|
||||
constexpr uint32_t kV1Ap = 1;
|
||||
// Mode ID for V3
|
||||
constexpr uint32_t kV3 = 3;
|
||||
} // namespace chip_mode_ids
|
||||
|
||||
class WifiFeatureFlags {
|
||||
public:
|
||||
WifiFeatureFlags();
|
||||
virtual ~WifiFeatureFlags() = default;
|
||||
|
||||
virtual std::vector<IWifiChip::ChipMode> getChipModes(bool is_primary);
|
||||
|
||||
private:
|
||||
std::vector<IWifiChip::ChipMode> getChipModesForPrimary();
|
||||
};
|
||||
|
||||
} // namespace feature_flags
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_FEATURE_FLAGS_H_
|
||||
174
wifi/aidl/default/wifi_iface_util.cpp
Normal file
174
wifi/aidl/default/wifi_iface_util.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <net/if.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
|
||||
#include "wifi_iface_util.h"
|
||||
|
||||
namespace {
|
||||
// Constants to set the local bit & clear the multicast bit.
|
||||
constexpr uint8_t kMacAddressMulticastMask = 0x01;
|
||||
constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace iface_util {
|
||||
|
||||
WifiIfaceUtil::WifiIfaceUtil(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
|
||||
: iface_tool_(iface_tool),
|
||||
legacy_hal_(legacy_hal),
|
||||
random_mac_address_(nullptr),
|
||||
event_handlers_map_() {}
|
||||
|
||||
std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(const std::string& iface_name) {
|
||||
return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str());
|
||||
}
|
||||
|
||||
bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
|
||||
const std::array<uint8_t, 6>& mac) {
|
||||
#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
uint64_t legacy_feature_set;
|
||||
std::tie(legacy_status, legacy_feature_set) =
|
||||
legacy_hal_.lock()->getSupportedFeatureSet(iface_name);
|
||||
|
||||
if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
|
||||
!iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) {
|
||||
LOG(ERROR) << "SetUpState(false) failed.";
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac);
|
||||
#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
|
||||
if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
|
||||
!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
|
||||
LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready.";
|
||||
// Wait for driver ready and try to set iface UP again
|
||||
if (legacy_hal_.lock()->waitForDriverReady() != legacy_hal::WIFI_SUCCESS) {
|
||||
LOG(ERROR) << "SetUpState(true) wait for driver ready failed.";
|
||||
return false;
|
||||
}
|
||||
if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
|
||||
LOG(ERROR) << "SetUpState(true) failed after retry.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
IfaceEventHandlers event_handlers = {};
|
||||
const auto it = event_handlers_map_.find(iface_name);
|
||||
if (it != event_handlers_map_.end()) {
|
||||
event_handlers = it->second;
|
||||
}
|
||||
if (event_handlers.on_state_toggle_off_on != nullptr) {
|
||||
event_handlers.on_state_toggle_off_on(iface_name);
|
||||
}
|
||||
if (!success) {
|
||||
LOG(ERROR) << "SetMacAddress failed on " << iface_name;
|
||||
} else {
|
||||
LOG(DEBUG) << "SetMacAddress succeeded on " << iface_name;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() {
|
||||
if (random_mac_address_) {
|
||||
return *random_mac_address_.get();
|
||||
}
|
||||
random_mac_address_ = std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress());
|
||||
return *random_mac_address_.get();
|
||||
}
|
||||
|
||||
void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name,
|
||||
IfaceEventHandlers handlers) {
|
||||
event_handlers_map_[iface_name] = handlers;
|
||||
}
|
||||
|
||||
void WifiIfaceUtil::unregisterIfaceEventHandlers(const std::string& iface_name) {
|
||||
event_handlers_map_.erase(iface_name);
|
||||
}
|
||||
|
||||
std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
|
||||
std::array<uint8_t, 6> address = {};
|
||||
std::random_device rd;
|
||||
std::default_random_engine engine(rd());
|
||||
std::uniform_int_distribution<uint8_t> dist(std::numeric_limits<uint8_t>::min(),
|
||||
std::numeric_limits<uint8_t>::max());
|
||||
for (size_t i = 0; i < address.size(); i++) {
|
||||
address[i] = dist(engine);
|
||||
}
|
||||
// Set the local bit and clear the multicast bit.
|
||||
address[0] |= kMacAddressLocallyAssignedMask;
|
||||
address[0] &= ~kMacAddressMulticastMask;
|
||||
return address;
|
||||
}
|
||||
|
||||
bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) {
|
||||
if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), request_up)) {
|
||||
LOG(ERROR) << "SetUpState to " << request_up << " failed";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned WifiIfaceUtil::ifNameToIndex(const std::string& iface_name) {
|
||||
return if_nametoindex(iface_name.c_str());
|
||||
}
|
||||
|
||||
bool WifiIfaceUtil::createBridge(const std::string& br_name) {
|
||||
if (!iface_tool_.lock()->createBridge(br_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!iface_tool_.lock()->SetUpState(br_name.c_str(), true)) {
|
||||
LOG(ERROR) << "bridge SetUpState(true) failed.";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiIfaceUtil::deleteBridge(const std::string& br_name) {
|
||||
if (!iface_tool_.lock()->SetUpState(br_name.c_str(), false)) {
|
||||
LOG(INFO) << "SetUpState(false) failed for bridge=" << br_name.c_str();
|
||||
}
|
||||
|
||||
return iface_tool_.lock()->deleteBridge(br_name);
|
||||
}
|
||||
|
||||
bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name, const std::string& if_name) {
|
||||
return iface_tool_.lock()->addIfaceToBridge(br_name, if_name);
|
||||
}
|
||||
|
||||
bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name, const std::string& if_name) {
|
||||
return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name);
|
||||
}
|
||||
|
||||
} // namespace iface_util
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
84
wifi/aidl/default/wifi_iface_util.h
Normal file
84
wifi/aidl/default/wifi_iface_util.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_IFACE_UTIL_H_
|
||||
#define WIFI_IFACE_UTIL_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/IWifi.h>
|
||||
#include <wifi_system/interface_tool.h>
|
||||
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace iface_util {
|
||||
|
||||
// Iface event handlers.
|
||||
struct IfaceEventHandlers {
|
||||
// Callback to be invoked when the iface is set down & up for MAC address
|
||||
// change.
|
||||
std::function<void(const std::string& iface_name)> on_state_toggle_off_on;
|
||||
};
|
||||
|
||||
/**
|
||||
* Util class for common iface operations.
|
||||
*/
|
||||
class WifiIfaceUtil {
|
||||
public:
|
||||
WifiIfaceUtil(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
|
||||
virtual ~WifiIfaceUtil() = default;
|
||||
|
||||
virtual std::array<uint8_t, 6> getFactoryMacAddress(const std::string& iface_name);
|
||||
virtual bool setMacAddress(const std::string& iface_name, const std::array<uint8_t, 6>& mac);
|
||||
// Get or create a random MAC address. The MAC address returned from
|
||||
// this method will remain the same throughout the lifetime of the HAL
|
||||
// daemon. (So, changes on every reboot)
|
||||
virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress();
|
||||
|
||||
// Register for any iface event callbacks for the provided interface.
|
||||
virtual void registerIfaceEventHandlers(const std::string& iface_name,
|
||||
IfaceEventHandlers handlers);
|
||||
virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
|
||||
virtual bool setUpState(const std::string& iface_name, bool request_up);
|
||||
virtual unsigned ifNameToIndex(const std::string& iface_name);
|
||||
|
||||
virtual bool createBridge(const std::string& br_name);
|
||||
|
||||
virtual bool deleteBridge(const std::string& br_name);
|
||||
|
||||
virtual bool addIfaceToBridge(const std::string& br_name, const std::string& if_name);
|
||||
|
||||
virtual bool removeIfaceFromBridge(const std::string& br_name, const std::string& if_name);
|
||||
// Get a random MAC address.
|
||||
virtual std::array<uint8_t, 6> createRandomMacAddress();
|
||||
|
||||
private:
|
||||
std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
|
||||
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
|
||||
std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
|
||||
std::map<std::string, IfaceEventHandlers> event_handlers_map_;
|
||||
};
|
||||
|
||||
} // namespace iface_util
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_IFACE_UTIL_H_
|
||||
1654
wifi/aidl/default/wifi_legacy_hal.cpp
Normal file
1654
wifi/aidl/default/wifi_legacy_hal.cpp
Normal file
File diff suppressed because it is too large
Load Diff
738
wifi/aidl/default/wifi_legacy_hal.h
Normal file
738
wifi/aidl/default/wifi_legacy_hal.h
Normal file
@@ -0,0 +1,738 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_LEGACY_HAL_H_
|
||||
#define WIFI_LEGACY_HAL_H_
|
||||
|
||||
#include <hardware_legacy/wifi_hal.h>
|
||||
#include <wifi_system/interface_tool.h>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
// This is in a separate namespace to prevent typename conflicts between
|
||||
// the legacy HAL types and the AIDL interface types.
|
||||
namespace legacy_hal {
|
||||
// Import all the types defined inside the legacy HAL header files into this
|
||||
// namespace.
|
||||
using ::chre_nan_rtt_state;
|
||||
using ::frame_info;
|
||||
using ::frame_type;
|
||||
using ::FRAME_TYPE_80211_MGMT;
|
||||
using ::FRAME_TYPE_ETHERNET_II;
|
||||
using ::FRAME_TYPE_UNKNOWN;
|
||||
using ::fw_roaming_state_t;
|
||||
using ::mac_addr;
|
||||
using ::NAN_CHANNEL_24G_BAND;
|
||||
using ::NAN_CHANNEL_5G_BAND_HIGH;
|
||||
using ::NAN_CHANNEL_5G_BAND_LOW;
|
||||
using ::NAN_DISABLE_RANGE_REPORT;
|
||||
using ::NAN_DO_NOT_USE_SRF;
|
||||
using ::NAN_DP_CHANNEL_NOT_REQUESTED;
|
||||
using ::NAN_DP_CONFIG_NO_SECURITY;
|
||||
using ::NAN_DP_CONFIG_SECURITY;
|
||||
using ::NAN_DP_END;
|
||||
using ::NAN_DP_FORCE_CHANNEL_SETUP;
|
||||
using ::NAN_DP_INITIATOR_RESPONSE;
|
||||
using ::NAN_DP_INTERFACE_CREATE;
|
||||
using ::NAN_DP_INTERFACE_DELETE;
|
||||
using ::NAN_DP_REQUEST_ACCEPT;
|
||||
using ::NAN_DP_REQUEST_CHANNEL_SETUP;
|
||||
using ::NAN_DP_REQUEST_REJECT;
|
||||
using ::NAN_DP_RESPONDER_RESPONSE;
|
||||
using ::NAN_GET_CAPABILITIES;
|
||||
using ::NAN_MATCH_ALG_MATCH_CONTINUOUS;
|
||||
using ::NAN_MATCH_ALG_MATCH_NEVER;
|
||||
using ::NAN_MATCH_ALG_MATCH_ONCE;
|
||||
using ::NAN_PUBLISH_TYPE_SOLICITED;
|
||||
using ::NAN_PUBLISH_TYPE_UNSOLICITED;
|
||||
using ::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
|
||||
using ::NAN_RANGING_AUTO_RESPONSE_DISABLE;
|
||||
using ::NAN_RANGING_AUTO_RESPONSE_ENABLE;
|
||||
using ::NAN_RANGING_DISABLE;
|
||||
using ::NAN_RANGING_ENABLE;
|
||||
using ::NAN_RESPONSE_BEACON_SDF_PAYLOAD;
|
||||
using ::NAN_RESPONSE_CONFIG;
|
||||
using ::NAN_RESPONSE_DISABLED;
|
||||
using ::NAN_RESPONSE_ENABLED;
|
||||
using ::NAN_RESPONSE_ERROR;
|
||||
using ::NAN_RESPONSE_PUBLISH;
|
||||
using ::NAN_RESPONSE_PUBLISH_CANCEL;
|
||||
using ::NAN_RESPONSE_STATS;
|
||||
using ::NAN_RESPONSE_SUBSCRIBE;
|
||||
using ::NAN_RESPONSE_SUBSCRIBE_CANCEL;
|
||||
using ::NAN_RESPONSE_TCA;
|
||||
using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP;
|
||||
using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
|
||||
using ::NAN_SECURITY_KEY_INPUT_PMK;
|
||||
using ::NAN_SERVICE_ACCEPT_POLICY_ALL;
|
||||
using ::NAN_SERVICE_ACCEPT_POLICY_NONE;
|
||||
using ::NAN_SRF_ATTR_BLOOM_FILTER;
|
||||
using ::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
|
||||
using ::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
|
||||
using ::NAN_SRF_INCLUDE_RESPOND;
|
||||
using ::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
|
||||
using ::NAN_SSI_REQUIRED_IN_MATCH_IND;
|
||||
using ::NAN_STATUS_ALREADY_ENABLED;
|
||||
using ::NAN_STATUS_FOLLOWUP_QUEUE_FULL;
|
||||
using ::NAN_STATUS_INTERNAL_FAILURE;
|
||||
using ::NAN_STATUS_INVALID_NDP_ID;
|
||||
using ::NAN_STATUS_INVALID_PARAM;
|
||||
using ::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
|
||||
using ::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID;
|
||||
using ::NAN_STATUS_NAN_NOT_ALLOWED;
|
||||
using ::NAN_STATUS_NO_OTA_ACK;
|
||||
using ::NAN_STATUS_NO_RESOURCE_AVAILABLE;
|
||||
using ::NAN_STATUS_PROTOCOL_FAILURE;
|
||||
using ::NAN_STATUS_SUCCESS;
|
||||
using ::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
|
||||
using ::NAN_SUBSCRIBE_TYPE_ACTIVE;
|
||||
using ::NAN_SUBSCRIBE_TYPE_PASSIVE;
|
||||
using ::NAN_TRANSMIT_IN_DW;
|
||||
using ::NAN_TRANSMIT_IN_FAW;
|
||||
using ::NAN_TX_PRIORITY_HIGH;
|
||||
using ::NAN_TX_PRIORITY_NORMAL;
|
||||
using ::NAN_TX_TYPE_BROADCAST;
|
||||
using ::NAN_TX_TYPE_UNICAST;
|
||||
using ::NAN_USE_SRF;
|
||||
using ::NanBeaconSdfPayloadInd;
|
||||
using ::NanCapabilities;
|
||||
using ::NanChannelInfo;
|
||||
using ::NanConfigRequest;
|
||||
using ::NanDataPathChannelCfg;
|
||||
using ::NanDataPathConfirmInd;
|
||||
using ::NanDataPathEndInd;
|
||||
using ::NanDataPathIndicationResponse;
|
||||
using ::NanDataPathInitiatorRequest;
|
||||
using ::NanDataPathRequestInd;
|
||||
using ::NanDataPathScheduleUpdateInd;
|
||||
using ::NanDisabledInd;
|
||||
using ::NanDiscEngEventInd;
|
||||
using ::NanEnableRequest;
|
||||
using ::NanFollowupInd;
|
||||
using ::NanMatchAlg;
|
||||
using ::NanMatchExpiredInd;
|
||||
using ::NanMatchInd;
|
||||
using ::NanPublishCancelRequest;
|
||||
using ::NanPublishRequest;
|
||||
using ::NanPublishTerminatedInd;
|
||||
using ::NanPublishType;
|
||||
using ::NanRangeReportInd;
|
||||
using ::NanRangeRequestInd;
|
||||
using ::NanResponseMsg;
|
||||
using ::NanSRFType;
|
||||
using ::NanStatusType;
|
||||
using ::NanSubscribeCancelRequest;
|
||||
using ::NanSubscribeRequest;
|
||||
using ::NanSubscribeTerminatedInd;
|
||||
using ::NanSubscribeType;
|
||||
using ::NanTransmitFollowupInd;
|
||||
using ::NanTransmitFollowupRequest;
|
||||
using ::NanTxType;
|
||||
using ::ROAMING_DISABLE;
|
||||
using ::ROAMING_ENABLE;
|
||||
using ::RTT_PEER_AP;
|
||||
using ::RTT_PEER_NAN;
|
||||
using ::RTT_PEER_P2P_CLIENT;
|
||||
using ::RTT_PEER_P2P_GO;
|
||||
using ::RTT_PEER_STA;
|
||||
using ::rtt_peer_type;
|
||||
using ::RTT_STATUS_ABORTED;
|
||||
using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL;
|
||||
using ::RTT_STATUS_FAIL_BUSY_TRY_LATER;
|
||||
using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE;
|
||||
using ::RTT_STATUS_FAIL_INVALID_TS;
|
||||
using ::RTT_STATUS_FAIL_NO_CAPABILITY;
|
||||
using ::RTT_STATUS_FAIL_NO_RSP;
|
||||
using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
|
||||
using ::RTT_STATUS_FAIL_PROTOCOL;
|
||||
using ::RTT_STATUS_FAIL_REJECTED;
|
||||
using ::RTT_STATUS_FAIL_SCHEDULE;
|
||||
using ::RTT_STATUS_FAIL_TM_TIMEOUT;
|
||||
using ::RTT_STATUS_FAILURE;
|
||||
using ::RTT_STATUS_INVALID_REQ;
|
||||
using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
|
||||
using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE;
|
||||
using ::RTT_STATUS_NO_WIFI;
|
||||
using ::RTT_STATUS_SUCCESS;
|
||||
using ::RTT_TYPE_1_SIDED;
|
||||
using ::RTT_TYPE_2_SIDED;
|
||||
using ::RX_PKT_FATE_DRV_DROP_FILTER;
|
||||
using ::RX_PKT_FATE_DRV_DROP_INVALID;
|
||||
using ::RX_PKT_FATE_DRV_DROP_NOBUFS;
|
||||
using ::RX_PKT_FATE_DRV_DROP_OTHER;
|
||||
using ::RX_PKT_FATE_DRV_QUEUED;
|
||||
using ::RX_PKT_FATE_FW_DROP_FILTER;
|
||||
using ::RX_PKT_FATE_FW_DROP_INVALID;
|
||||
using ::RX_PKT_FATE_FW_DROP_NOBUFS;
|
||||
using ::RX_PKT_FATE_FW_DROP_OTHER;
|
||||
using ::RX_PKT_FATE_FW_QUEUED;
|
||||
using ::RX_PKT_FATE_SUCCESS;
|
||||
using ::ssid_t;
|
||||
using ::transaction_id;
|
||||
using ::TX_PKT_FATE_ACKED;
|
||||
using ::TX_PKT_FATE_DRV_DROP_INVALID;
|
||||
using ::TX_PKT_FATE_DRV_DROP_NOBUFS;
|
||||
using ::TX_PKT_FATE_DRV_DROP_OTHER;
|
||||
using ::TX_PKT_FATE_DRV_QUEUED;
|
||||
using ::TX_PKT_FATE_FW_DROP_INVALID;
|
||||
using ::TX_PKT_FATE_FW_DROP_NOBUFS;
|
||||
using ::TX_PKT_FATE_FW_DROP_OTHER;
|
||||
using ::TX_PKT_FATE_FW_QUEUED;
|
||||
using ::TX_PKT_FATE_SENT;
|
||||
using ::WIFI_AC_BE;
|
||||
using ::WIFI_AC_BK;
|
||||
using ::WIFI_AC_VI;
|
||||
using ::WIFI_AC_VO;
|
||||
using ::WIFI_ANTENNA_1X1;
|
||||
using ::WIFI_ANTENNA_2X2;
|
||||
using ::WIFI_ANTENNA_3X3;
|
||||
using ::WIFI_ANTENNA_4X4;
|
||||
using ::WIFI_ANTENNA_UNSPECIFIED;
|
||||
using ::wifi_band;
|
||||
using ::WIFI_BAND_A;
|
||||
using ::WIFI_BAND_A_DFS;
|
||||
using ::WIFI_BAND_A_WITH_DFS;
|
||||
using ::WIFI_BAND_ABG;
|
||||
using ::WIFI_BAND_ABG_WITH_DFS;
|
||||
using ::WIFI_BAND_BG;
|
||||
using ::WIFI_BAND_UNSPECIFIED;
|
||||
using ::wifi_cached_scan_report;
|
||||
using ::wifi_cached_scan_results;
|
||||
using ::WIFI_CHAN_WIDTH_10;
|
||||
using ::WIFI_CHAN_WIDTH_160;
|
||||
using ::WIFI_CHAN_WIDTH_20;
|
||||
using ::WIFI_CHAN_WIDTH_320;
|
||||
using ::WIFI_CHAN_WIDTH_40;
|
||||
using ::WIFI_CHAN_WIDTH_5;
|
||||
using ::WIFI_CHAN_WIDTH_80;
|
||||
using ::WIFI_CHAN_WIDTH_80P80;
|
||||
using ::WIFI_CHAN_WIDTH_INVALID;
|
||||
using ::wifi_channel_info;
|
||||
using ::wifi_channel_stat;
|
||||
using ::wifi_channel_width;
|
||||
using ::wifi_coex_restriction;
|
||||
using ::wifi_coex_unsafe_channel;
|
||||
using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
|
||||
using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
|
||||
using ::wifi_error;
|
||||
using ::WIFI_ERROR_BUSY;
|
||||
using ::WIFI_ERROR_INVALID_ARGS;
|
||||
using ::WIFI_ERROR_INVALID_REQUEST_ID;
|
||||
using ::WIFI_ERROR_NONE;
|
||||
using ::WIFI_ERROR_NOT_AVAILABLE;
|
||||
using ::WIFI_ERROR_NOT_SUPPORTED;
|
||||
using ::WIFI_ERROR_OUT_OF_MEMORY;
|
||||
using ::WIFI_ERROR_TIMED_OUT;
|
||||
using ::WIFI_ERROR_TOO_MANY_REQUESTS;
|
||||
using ::WIFI_ERROR_UNINITIALIZED;
|
||||
using ::WIFI_ERROR_UNKNOWN;
|
||||
using ::wifi_gscan_capabilities;
|
||||
using ::wifi_hal_fn;
|
||||
using ::wifi_information_element;
|
||||
using ::WIFI_INTERFACE_IBSS;
|
||||
using ::WIFI_INTERFACE_MESH;
|
||||
using ::wifi_interface_mode;
|
||||
using ::WIFI_INTERFACE_NAN;
|
||||
using ::WIFI_INTERFACE_P2P_CLIENT;
|
||||
using ::WIFI_INTERFACE_P2P_GO;
|
||||
using ::WIFI_INTERFACE_SOFTAP;
|
||||
using ::WIFI_INTERFACE_STA;
|
||||
using ::WIFI_INTERFACE_TDLS;
|
||||
using ::wifi_interface_type;
|
||||
using ::WIFI_INTERFACE_TYPE_AP;
|
||||
using ::WIFI_INTERFACE_TYPE_NAN;
|
||||
using ::WIFI_INTERFACE_TYPE_P2P;
|
||||
using ::WIFI_INTERFACE_TYPE_STA;
|
||||
using ::WIFI_INTERFACE_UNKNOWN;
|
||||
using ::wifi_latency_mode;
|
||||
using ::WIFI_LATENCY_MODE_LOW;
|
||||
using ::WIFI_LATENCY_MODE_NORMAL;
|
||||
using ::wifi_lci_information;
|
||||
using ::wifi_lcr_information;
|
||||
using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
|
||||
using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
|
||||
using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
|
||||
using ::WIFI_LOGGER_PACKET_FATE_SUPPORTED;
|
||||
using ::WIFI_LOGGER_POWER_EVENT_SUPPORTED;
|
||||
using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED;
|
||||
using ::WIFI_MOTION_EXPECTED;
|
||||
using ::WIFI_MOTION_NOT_EXPECTED;
|
||||
using ::wifi_motion_pattern;
|
||||
using ::WIFI_MOTION_UNKNOWN;
|
||||
using ::wifi_multi_sta_use_case;
|
||||
using ::wifi_power_scenario;
|
||||
using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
|
||||
using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
|
||||
using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
|
||||
using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
|
||||
using ::WIFI_POWER_SCENARIO_VOICE_CALL;
|
||||
using ::wifi_radio_combination;
|
||||
using ::wifi_radio_combination_matrix;
|
||||
using ::wifi_radio_configuration;
|
||||
using ::wifi_rate;
|
||||
using ::wifi_request_id;
|
||||
using ::wifi_ring_buffer_status;
|
||||
using ::wifi_roaming_capabilities;
|
||||
using ::wifi_roaming_config;
|
||||
using ::wifi_rtt_bw;
|
||||
using ::WIFI_RTT_BW_10;
|
||||
using ::WIFI_RTT_BW_160;
|
||||
using ::WIFI_RTT_BW_20;
|
||||
using ::WIFI_RTT_BW_320;
|
||||
using ::WIFI_RTT_BW_40;
|
||||
using ::WIFI_RTT_BW_5;
|
||||
using ::WIFI_RTT_BW_80;
|
||||
using ::wifi_rtt_capabilities;
|
||||
using ::wifi_rtt_config;
|
||||
using ::wifi_rtt_preamble;
|
||||
using ::WIFI_RTT_PREAMBLE_EHT;
|
||||
using ::WIFI_RTT_PREAMBLE_HE;
|
||||
using ::WIFI_RTT_PREAMBLE_HT;
|
||||
using ::WIFI_RTT_PREAMBLE_LEGACY;
|
||||
using ::WIFI_RTT_PREAMBLE_VHT;
|
||||
using ::wifi_rtt_responder;
|
||||
using ::wifi_rtt_result;
|
||||
using ::wifi_rtt_status;
|
||||
using ::wifi_rtt_type;
|
||||
using ::wifi_rx_packet_fate;
|
||||
using ::wifi_rx_report;
|
||||
using ::wifi_scan_bucket_spec;
|
||||
using ::wifi_scan_cmd_params;
|
||||
using ::WIFI_SCAN_FLAG_INTERRUPTED;
|
||||
using ::wifi_scan_result;
|
||||
using ::WIFI_SUCCESS;
|
||||
using ::wifi_tx_packet_fate;
|
||||
using ::wifi_tx_report;
|
||||
using ::wifi_usable_channel;
|
||||
using ::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
|
||||
using ::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
|
||||
using ::WLAN_MAC_2_4_BAND;
|
||||
using ::WLAN_MAC_5_0_BAND;
|
||||
using ::WLAN_MAC_60_0_BAND;
|
||||
using ::WLAN_MAC_6_0_BAND;
|
||||
|
||||
// APF capabilities supported by the iface.
|
||||
struct PacketFilterCapabilities {
|
||||
uint32_t version;
|
||||
uint32_t max_len;
|
||||
};
|
||||
|
||||
// WARNING: We don't care about the variable sized members of either
|
||||
// |wifi_iface_stat|, |wifi_radio_stat| structures. So, using the pragma
|
||||
// to escape the compiler warnings regarding this.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wgnu-variable-sized-type-not-at-end"
|
||||
// The |wifi_radio_stat.tx_time_per_levels| stats is provided as a pointer in
|
||||
// |wifi_radio_stat| structure in the legacy HAL API. Separate that out
|
||||
// into a separate return element to avoid passing pointers around.
|
||||
struct LinkLayerRadioStats {
|
||||
wifi_radio_stat stats;
|
||||
std::vector<uint32_t> tx_time_per_levels;
|
||||
std::vector<wifi_channel_stat> channel_stats;
|
||||
};
|
||||
|
||||
struct WifiPeerInfo {
|
||||
wifi_peer_info peer_info;
|
||||
std::vector<wifi_rate_stat> rate_stats;
|
||||
};
|
||||
|
||||
struct LinkLayerStats {
|
||||
wifi_iface_stat iface;
|
||||
std::vector<LinkLayerRadioStats> radios;
|
||||
std::vector<WifiPeerInfo> peers;
|
||||
};
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and
|
||||
// |WLAN_DRIVER_WAKE_REASON_CNT.driver_fw_local_wake_cnt| stats is provided
|
||||
// as a pointer in |WLAN_DRIVER_WAKE_REASON_CNT| structure in the legacy HAL
|
||||
// API. Separate that out into a separate return elements to avoid passing
|
||||
// pointers around.
|
||||
struct WakeReasonStats {
|
||||
WLAN_DRIVER_WAKE_REASON_CNT wake_reason_cnt;
|
||||
std::vector<uint32_t> cmd_event_wake_cnt;
|
||||
std::vector<uint32_t> driver_fw_local_wake_cnt;
|
||||
};
|
||||
|
||||
// NAN response and event callbacks struct.
|
||||
struct NanCallbackHandlers {
|
||||
// NotifyResponse invoked to notify the status of the Request.
|
||||
std::function<void(transaction_id, const NanResponseMsg&)> on_notify_response;
|
||||
// Various event callbacks.
|
||||
std::function<void(const NanPublishTerminatedInd&)> on_event_publish_terminated;
|
||||
std::function<void(const NanMatchInd&)> on_event_match;
|
||||
std::function<void(const NanMatchExpiredInd&)> on_event_match_expired;
|
||||
std::function<void(const NanSubscribeTerminatedInd&)> on_event_subscribe_terminated;
|
||||
std::function<void(const NanFollowupInd&)> on_event_followup;
|
||||
std::function<void(const NanDiscEngEventInd&)> on_event_disc_eng_event;
|
||||
std::function<void(const NanDisabledInd&)> on_event_disabled;
|
||||
std::function<void(const NanTCAInd&)> on_event_tca;
|
||||
std::function<void(const NanBeaconSdfPayloadInd&)> on_event_beacon_sdf_payload;
|
||||
std::function<void(const NanDataPathRequestInd&)> on_event_data_path_request;
|
||||
std::function<void(const NanDataPathConfirmInd&)> on_event_data_path_confirm;
|
||||
std::function<void(const NanDataPathEndInd&)> on_event_data_path_end;
|
||||
std::function<void(const NanTransmitFollowupInd&)> on_event_transmit_follow_up;
|
||||
std::function<void(const NanRangeRequestInd&)> on_event_range_request;
|
||||
std::function<void(const NanRangeReportInd&)> on_event_range_report;
|
||||
std::function<void(const NanDataPathScheduleUpdateInd&)> on_event_schedule_update;
|
||||
};
|
||||
|
||||
// Full scan results contain IE info and are hence passed by reference, to
|
||||
// preserve the variable length array member |ie_data|. Callee must not retain
|
||||
// the pointer.
|
||||
using on_gscan_full_result_callback =
|
||||
std::function<void(wifi_request_id, const wifi_scan_result*, uint32_t)>;
|
||||
// These scan results don't contain any IE info, so no need to pass by
|
||||
// reference.
|
||||
using on_gscan_results_callback =
|
||||
std::function<void(wifi_request_id, const std::vector<wifi_cached_scan_results>&)>;
|
||||
|
||||
// Invoked when the rssi value breaches the thresholds set.
|
||||
using on_rssi_threshold_breached_callback =
|
||||
std::function<void(wifi_request_id, std::array<uint8_t, ETH_ALEN>, int8_t)>;
|
||||
|
||||
// Callback for RTT range request results.
|
||||
// Rtt results contain IE info and are hence passed by reference, to
|
||||
// preserve the |LCI| and |LCR| pointers. Callee must not retain
|
||||
// the pointer.
|
||||
using on_rtt_results_callback =
|
||||
std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result*>&)>;
|
||||
|
||||
// Callback for ring buffer data.
|
||||
using on_ring_buffer_data_callback = std::function<void(
|
||||
const std::string&, const std::vector<uint8_t>&, const wifi_ring_buffer_status&)>;
|
||||
|
||||
// Callback for alerts.
|
||||
using on_error_alert_callback = std::function<void(int32_t, const std::vector<uint8_t>&)>;
|
||||
|
||||
// Callback for subsystem restart
|
||||
using on_subsystem_restart_callback = std::function<void(const std::string&)>;
|
||||
|
||||
// Struct for the mac info from the legacy HAL. This is a cleaner version
|
||||
// of the |wifi_mac_info| & |wifi_iface_info|.
|
||||
typedef struct {
|
||||
std::string name;
|
||||
wifi_channel channel;
|
||||
} WifiIfaceInfo;
|
||||
|
||||
typedef struct {
|
||||
uint32_t wlan_mac_id;
|
||||
/* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */
|
||||
uint32_t mac_band;
|
||||
/* Represents the connected Wi-Fi interfaces associated with each MAC */
|
||||
std::vector<WifiIfaceInfo> iface_infos;
|
||||
} WifiMacInfo;
|
||||
|
||||
// Callback for radio mode change
|
||||
using on_radio_mode_change_callback = std::function<void(const std::vector<WifiMacInfo>&)>;
|
||||
|
||||
// TWT response and event callbacks struct.
|
||||
struct TwtCallbackHandlers {
|
||||
// Callback for TWT setup response
|
||||
std::function<void(const TwtSetupResponse&)> on_setup_response;
|
||||
// Callback for TWT teardown completion
|
||||
std::function<void(const TwtTeardownCompletion&)> on_teardown_completion;
|
||||
// Callback for TWT info frame received event
|
||||
std::function<void(const TwtInfoFrameReceived&)> on_info_frame_received;
|
||||
// Callback for TWT notification from the device
|
||||
std::function<void(const TwtDeviceNotify&)> on_device_notify;
|
||||
};
|
||||
|
||||
// CHRE response and event callbacks struct.
|
||||
struct ChreCallbackHandlers {
|
||||
// Callback for CHRE NAN RTT
|
||||
std::function<void(chre_nan_rtt_state)> on_wifi_chre_nan_rtt_state;
|
||||
};
|
||||
|
||||
// Cached Scan Results response and event callbacks struct.
|
||||
struct CachedScanResultsCallbackHandlers {
|
||||
// Callback for Cached Scan Results
|
||||
std::function<void(wifi_cached_scan_report*)> on_cached_scan_results;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class that encapsulates all legacy HAL interactions.
|
||||
* This class manages the lifetime of the event loop thread used by legacy HAL.
|
||||
*
|
||||
* Note: There will only be a single instance of this class created in the Wifi
|
||||
* object and will be valid for the lifetime of the process.
|
||||
*/
|
||||
class WifiLegacyHal {
|
||||
public:
|
||||
WifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
|
||||
const wifi_hal_fn& fn, bool is_primary);
|
||||
virtual ~WifiLegacyHal() = default;
|
||||
|
||||
// Initialize the legacy HAL function table.
|
||||
virtual wifi_error initialize();
|
||||
// Start the legacy HAL and the event looper thread.
|
||||
virtual wifi_error start();
|
||||
// Deinitialize the legacy HAL and wait for the event loop thread to exit
|
||||
// using a predefined timeout.
|
||||
virtual wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
|
||||
const std::function<void()>& on_complete_callback);
|
||||
virtual wifi_error waitForDriverReady();
|
||||
// Checks if legacy HAL has successfully started
|
||||
bool isStarted();
|
||||
// Wrappers for all the functions in the legacy HAL function table.
|
||||
virtual std::pair<wifi_error, std::string> getDriverVersion(const std::string& iface_name);
|
||||
virtual std::pair<wifi_error, std::string> getFirmwareVersion(const std::string& iface_name);
|
||||
std::pair<wifi_error, std::vector<uint8_t>> requestDriverMemoryDump(
|
||||
const std::string& iface_name);
|
||||
std::pair<wifi_error, std::vector<uint8_t>> requestFirmwareMemoryDump(
|
||||
const std::string& iface_name);
|
||||
virtual std::pair<wifi_error, uint64_t> getSupportedFeatureSet(const std::string& iface_name);
|
||||
// APF functions.
|
||||
std::pair<wifi_error, PacketFilterCapabilities> getPacketFilterCapabilities(
|
||||
const std::string& iface_name);
|
||||
wifi_error setPacketFilter(const std::string& iface_name, const std::vector<uint8_t>& program);
|
||||
std::pair<wifi_error, std::vector<uint8_t>> readApfPacketFilterData(
|
||||
const std::string& iface_name);
|
||||
// Gscan functions.
|
||||
std::pair<wifi_error, wifi_gscan_capabilities> getGscanCapabilities(
|
||||
const std::string& iface_name);
|
||||
// These API's provides a simplified interface over the legacy Gscan API's:
|
||||
// a) All scan events from the legacy HAL API other than the
|
||||
// |WIFI_SCAN_FAILED| are treated as notification of results.
|
||||
// This method then retrieves the cached scan results from the legacy
|
||||
// HAL API and triggers the externally provided
|
||||
// |on_results_user_callback| on success.
|
||||
// b) |WIFI_SCAN_FAILED| scan event or failure to retrieve cached scan
|
||||
// results
|
||||
// Triggers the externally provided |on_failure_user_callback|.
|
||||
// c) Full scan result event triggers the externally provided
|
||||
// |on_full_result_user_callback|.
|
||||
wifi_error startGscan(const std::string& iface_name, wifi_request_id id,
|
||||
const wifi_scan_cmd_params& params,
|
||||
const std::function<void(wifi_request_id)>& on_failure_callback,
|
||||
const on_gscan_results_callback& on_results_callback,
|
||||
const on_gscan_full_result_callback& on_full_result_callback);
|
||||
wifi_error stopGscan(const std::string& iface_name, wifi_request_id id);
|
||||
std::pair<wifi_error, std::vector<uint32_t>> getValidFrequenciesForBand(
|
||||
const std::string& iface_name, wifi_band band);
|
||||
virtual wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on);
|
||||
// Link layer stats functions.
|
||||
wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug);
|
||||
wifi_error disableLinkLayerStats(const std::string& iface_name);
|
||||
std::pair<wifi_error, LinkLayerStats> getLinkLayerStats(const std::string& iface_name);
|
||||
// RSSI monitor functions.
|
||||
wifi_error startRssiMonitoring(
|
||||
const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
|
||||
const on_rssi_threshold_breached_callback& on_threshold_breached_callback);
|
||||
wifi_error stopRssiMonitoring(const std::string& iface_name, wifi_request_id id);
|
||||
std::pair<wifi_error, wifi_roaming_capabilities> getRoamingCapabilities(
|
||||
const std::string& iface_name);
|
||||
wifi_error configureRoaming(const std::string& iface_name, const wifi_roaming_config& config);
|
||||
wifi_error enableFirmwareRoaming(const std::string& iface_name, fw_roaming_state_t state);
|
||||
wifi_error configureNdOffload(const std::string& iface_name, bool enable);
|
||||
wifi_error startSendingOffloadedPacket(const std::string& iface_name, int32_t cmd_id,
|
||||
uint16_t ether_type,
|
||||
const std::vector<uint8_t>& ip_packet_data,
|
||||
const std::array<uint8_t, 6>& src_address,
|
||||
const std::array<uint8_t, 6>& dst_address,
|
||||
int32_t period_in_ms);
|
||||
wifi_error stopSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id);
|
||||
virtual wifi_error selectTxPowerScenario(const std::string& iface_name,
|
||||
wifi_power_scenario scenario);
|
||||
virtual wifi_error resetTxPowerScenario(const std::string& iface_name);
|
||||
wifi_error setLatencyMode(const std::string& iface_name, wifi_latency_mode mode);
|
||||
wifi_error setThermalMitigationMode(wifi_thermal_mode mode, uint32_t completion_window);
|
||||
wifi_error setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
|
||||
uint32_t access_category);
|
||||
wifi_error resetDscpToAccessCategoryMapping();
|
||||
// Logger/debug functions.
|
||||
std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet(const std::string& iface_name);
|
||||
wifi_error startPktFateMonitoring(const std::string& iface_name);
|
||||
std::pair<wifi_error, std::vector<wifi_tx_report>> getTxPktFates(const std::string& iface_name);
|
||||
std::pair<wifi_error, std::vector<wifi_rx_report>> getRxPktFates(const std::string& iface_name);
|
||||
std::pair<wifi_error, WakeReasonStats> getWakeReasonStats(const std::string& iface_name);
|
||||
wifi_error registerRingBufferCallbackHandler(
|
||||
const std::string& iface_name, const on_ring_buffer_data_callback& on_data_callback);
|
||||
wifi_error deregisterRingBufferCallbackHandler(const std::string& iface_name);
|
||||
virtual wifi_error registerSubsystemRestartCallbackHandler(
|
||||
const on_subsystem_restart_callback& on_restart_callback);
|
||||
std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> getRingBuffersStatus(
|
||||
const std::string& iface_name);
|
||||
wifi_error startRingBufferLogging(const std::string& iface_name, const std::string& ring_name,
|
||||
uint32_t verbose_level, uint32_t max_interval_sec,
|
||||
uint32_t min_data_size);
|
||||
wifi_error getRingBufferData(const std::string& iface_name, const std::string& ring_name);
|
||||
wifi_error registerErrorAlertCallbackHandler(const std::string& iface_name,
|
||||
const on_error_alert_callback& on_alert_callback);
|
||||
wifi_error deregisterErrorAlertCallbackHandler(const std::string& iface_name);
|
||||
// Radio mode functions.
|
||||
virtual wifi_error registerRadioModeChangeCallbackHandler(
|
||||
const std::string& iface_name,
|
||||
const on_radio_mode_change_callback& on_user_change_callback);
|
||||
// RTT functions.
|
||||
wifi_error startRttRangeRequest(const std::string& iface_name, wifi_request_id id,
|
||||
const std::vector<wifi_rtt_config>& rtt_configs,
|
||||
const on_rtt_results_callback& on_results_callback);
|
||||
wifi_error cancelRttRangeRequest(const std::string& iface_name, wifi_request_id id,
|
||||
const std::vector<std::array<uint8_t, ETH_ALEN>>& mac_addrs);
|
||||
std::pair<wifi_error, wifi_rtt_capabilities> getRttCapabilities(const std::string& iface_name);
|
||||
std::pair<wifi_error, wifi_rtt_responder> getRttResponderInfo(const std::string& iface_name);
|
||||
wifi_error enableRttResponder(const std::string& iface_name, wifi_request_id id,
|
||||
const wifi_channel_info& channel_hint, uint32_t max_duration_secs,
|
||||
const wifi_rtt_responder& info);
|
||||
wifi_error disableRttResponder(const std::string& iface_name, wifi_request_id id);
|
||||
wifi_error setRttLci(const std::string& iface_name, wifi_request_id id,
|
||||
const wifi_lci_information& info);
|
||||
wifi_error setRttLcr(const std::string& iface_name, wifi_request_id id,
|
||||
const wifi_lcr_information& info);
|
||||
// NAN functions.
|
||||
virtual wifi_error nanRegisterCallbackHandlers(const std::string& iface_name,
|
||||
const NanCallbackHandlers& callbacks);
|
||||
wifi_error nanEnableRequest(const std::string& iface_name, transaction_id id,
|
||||
const NanEnableRequest& msg);
|
||||
virtual wifi_error nanDisableRequest(const std::string& iface_name, transaction_id id);
|
||||
wifi_error nanPublishRequest(const std::string& iface_name, transaction_id id,
|
||||
const NanPublishRequest& msg);
|
||||
wifi_error nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
|
||||
const NanPublishCancelRequest& msg);
|
||||
wifi_error nanSubscribeRequest(const std::string& iface_name, transaction_id id,
|
||||
const NanSubscribeRequest& msg);
|
||||
wifi_error nanSubscribeCancelRequest(const std::string& iface_name, transaction_id id,
|
||||
const NanSubscribeCancelRequest& msg);
|
||||
wifi_error nanTransmitFollowupRequest(const std::string& iface_name, transaction_id id,
|
||||
const NanTransmitFollowupRequest& msg);
|
||||
wifi_error nanStatsRequest(const std::string& iface_name, transaction_id id,
|
||||
const NanStatsRequest& msg);
|
||||
wifi_error nanConfigRequest(const std::string& iface_name, transaction_id id,
|
||||
const NanConfigRequest& msg);
|
||||
wifi_error nanTcaRequest(const std::string& iface_name, transaction_id id,
|
||||
const NanTCARequest& msg);
|
||||
wifi_error nanBeaconSdfPayloadRequest(const std::string& iface_name, transaction_id id,
|
||||
const NanBeaconSdfPayloadRequest& msg);
|
||||
std::pair<wifi_error, NanVersion> nanGetVersion();
|
||||
wifi_error nanGetCapabilities(const std::string& iface_name, transaction_id id);
|
||||
wifi_error nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
|
||||
const std::string& data_iface_name);
|
||||
virtual wifi_error nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
|
||||
const std::string& data_iface_name);
|
||||
wifi_error nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
|
||||
const NanDataPathInitiatorRequest& msg);
|
||||
wifi_error nanDataIndicationResponse(const std::string& iface_name, transaction_id id,
|
||||
const NanDataPathIndicationResponse& msg);
|
||||
wifi_error nanDataEnd(const std::string& iface_name, transaction_id id, uint32_t ndpInstanceId);
|
||||
// AP functions.
|
||||
wifi_error setCountryCode(const std::string& iface_name, const std::array<uint8_t, 2> code);
|
||||
|
||||
// Interface functions.
|
||||
virtual wifi_error createVirtualInterface(const std::string& ifname,
|
||||
wifi_interface_type iftype);
|
||||
virtual wifi_error deleteVirtualInterface(const std::string& ifname);
|
||||
virtual wifi_error getSupportedIfaceName(uint32_t iface_type, std::string& ifname);
|
||||
|
||||
// STA + STA functions
|
||||
virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname);
|
||||
virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case);
|
||||
|
||||
// Coex functions.
|
||||
virtual wifi_error setCoexUnsafeChannels(std::vector<wifi_coex_unsafe_channel> unsafe_channels,
|
||||
uint32_t restrictions);
|
||||
|
||||
wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode);
|
||||
|
||||
wifi_error twtRegisterHandler(const std::string& iface_name,
|
||||
const TwtCallbackHandlers& handler);
|
||||
|
||||
std::pair<wifi_error, TwtCapabilitySet> twtGetCapability(const std::string& iface_name);
|
||||
|
||||
wifi_error twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg);
|
||||
|
||||
wifi_error twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg);
|
||||
|
||||
wifi_error twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg);
|
||||
|
||||
std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name, uint8_t configId);
|
||||
|
||||
wifi_error twtClearStats(const std::string& iface_name, uint8_t configId);
|
||||
|
||||
wifi_error setDtimConfig(const std::string& iface_name, uint32_t multiplier);
|
||||
|
||||
// Retrieve the list of usable channels in the requested bands
|
||||
// for the requested modes
|
||||
std::pair<wifi_error, std::vector<wifi_usable_channel>> getUsableChannels(
|
||||
uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask);
|
||||
|
||||
wifi_error triggerSubsystemRestart();
|
||||
|
||||
wifi_error setIndoorState(bool isIndoor);
|
||||
|
||||
std::pair<wifi_error, wifi_radio_combination_matrix*> getSupportedRadioCombinationsMatrix();
|
||||
|
||||
// CHRE NAN RTT function
|
||||
wifi_error chreNanRttRequest(const std::string& iface_name, bool enable);
|
||||
|
||||
wifi_error chreRegisterHandler(const std::string& iface_name,
|
||||
const ChreCallbackHandlers& handler);
|
||||
|
||||
wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
|
||||
wifi_error getWifiCachedScanResults(const std::string& iface_name,
|
||||
const CachedScanResultsCallbackHandlers& handler);
|
||||
|
||||
private:
|
||||
// Retrieve interface handles for all the available interfaces.
|
||||
wifi_error retrieveIfaceHandles();
|
||||
wifi_interface_handle getIfaceHandle(const std::string& iface_name);
|
||||
// Run the legacy HAL event loop thread.
|
||||
void runEventLoop();
|
||||
// Retrieve the cached gscan results to pass the results back to the
|
||||
// external callbacks.
|
||||
std::pair<wifi_error, std::vector<wifi_cached_scan_results>> getGscanCachedResults(
|
||||
const std::string& iface_name);
|
||||
void invalidate();
|
||||
// Handles wifi (error) status of Virtual interface create/delete
|
||||
wifi_error handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
|
||||
wifi_error status);
|
||||
|
||||
// Global function table of legacy HAL.
|
||||
wifi_hal_fn global_func_table_;
|
||||
// Opaque handle to be used for all global operations.
|
||||
wifi_handle global_handle_;
|
||||
// Map of interface name to handle that is to be used for all interface
|
||||
// specific operations.
|
||||
std::map<std::string, wifi_interface_handle> iface_name_to_handle_;
|
||||
// Flag to indicate if we have initiated the cleanup of legacy HAL.
|
||||
std::atomic<bool> awaiting_event_loop_termination_;
|
||||
std::condition_variable_any stop_wait_cv_;
|
||||
// Flag to indicate if the legacy HAL has been started.
|
||||
bool is_started_;
|
||||
std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
|
||||
// Flag to indicate if this HAL is for the primary chip. This is used
|
||||
// in order to avoid some hard-coded behavior used with older HALs,
|
||||
// such as bring wlan0 interface up/down on start/stop HAL.
|
||||
// it may be removed once vendor HALs are updated.
|
||||
bool is_primary_;
|
||||
};
|
||||
|
||||
} // namespace legacy_hal
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_LEGACY_HAL_H_
|
||||
252
wifi/aidl/default/wifi_legacy_hal_factory.cpp
Normal file
252
wifi/aidl/default/wifi_legacy_hal_factory.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi_legacy_hal_factory.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "wifi_legacy_hal_stubs.h"
|
||||
|
||||
namespace {
|
||||
static constexpr char kVendorHalsDescPath[] = "/vendor/etc/wifi/vendor_hals";
|
||||
static constexpr char kVendorHalsDescExt[] = ".xml";
|
||||
static constexpr uint32_t kVendorHalsDescVersion = 1;
|
||||
|
||||
bool isDirectory(struct dirent* entryPtr) {
|
||||
bool isDir = false;
|
||||
if (entryPtr->d_type != DT_UNKNOWN && entryPtr->d_type != DT_LNK) {
|
||||
isDir = (entryPtr->d_type == DT_DIR);
|
||||
} else {
|
||||
struct stat entryStat;
|
||||
stat(entryPtr->d_name, &entryStat);
|
||||
isDir = S_ISDIR(entryStat.st_mode);
|
||||
}
|
||||
return isDir;
|
||||
}
|
||||
|
||||
bool isFileExtension(const char* name, const char* ext) {
|
||||
if (name == NULL) return false;
|
||||
if (ext == NULL) return false;
|
||||
|
||||
size_t extLen = strlen(ext);
|
||||
size_t nameLen = strlen(name);
|
||||
|
||||
if (extLen > nameLen) return false;
|
||||
|
||||
if (strncmp(name + nameLen - extLen, ext, extLen) != 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}; // namespace
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace legacy_hal {
|
||||
|
||||
WifiLegacyHalFactory::WifiLegacyHalFactory(
|
||||
const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool)
|
||||
: iface_tool_(iface_tool) {}
|
||||
|
||||
std::vector<std::shared_ptr<WifiLegacyHal>> WifiLegacyHalFactory::getHals() {
|
||||
if (legacy_hals_.empty()) {
|
||||
if (!initVendorHalDescriptorFromLinked()) initVendorHalsDescriptorList();
|
||||
for (auto& desc : descs_) {
|
||||
std::shared_ptr<WifiLegacyHal> hal =
|
||||
std::make_shared<WifiLegacyHal>(iface_tool_, desc.fn, desc.primary);
|
||||
legacy_hals_.push_back(hal);
|
||||
}
|
||||
}
|
||||
|
||||
return legacy_hals_;
|
||||
}
|
||||
|
||||
bool WifiLegacyHalFactory::initVendorHalDescriptorFromLinked() {
|
||||
wifi_hal_lib_desc desc;
|
||||
|
||||
if (!initLinkedHalFunctionTable(&desc.fn)) return false;
|
||||
|
||||
desc.primary = true;
|
||||
desc.handle = NULL;
|
||||
descs_.push_back(desc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiLegacyHalFactory::initLinkedHalFunctionTable(wifi_hal_fn* hal_fn) {
|
||||
init_wifi_vendor_hal_func_table_t initfn;
|
||||
|
||||
initfn = (init_wifi_vendor_hal_func_table_t)dlsym(RTLD_DEFAULT,
|
||||
"init_wifi_vendor_hal_func_table");
|
||||
if (!initfn) {
|
||||
LOG(INFO) << "no vendor HAL library linked, will try dynamic load";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!initHalFuncTableWithStubs(hal_fn)) {
|
||||
LOG(ERROR) << "Can not initialize the basic function pointer table";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (initfn(hal_fn) != WIFI_SUCCESS) {
|
||||
LOG(ERROR) << "Can not initialize the vendor function pointer table";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Overall structure of the HAL descriptor XML schema
|
||||
*
|
||||
* <?xml version="1.0" encoding="UTF-8"?>
|
||||
* <WifiVendorHal version="1">
|
||||
* <path>/vendor/lib64/libwifi-hal-qcom.so</path>
|
||||
* <primary>1</primary>
|
||||
* </WifiVendorHal>
|
||||
*/
|
||||
void WifiLegacyHalFactory::initVendorHalsDescriptorList() {
|
||||
xmlDocPtr xml;
|
||||
xmlNodePtr node, cnode;
|
||||
char* version;
|
||||
std::string path;
|
||||
xmlChar* value;
|
||||
wifi_hal_lib_desc desc;
|
||||
|
||||
LOG(INFO) << "processing vendor HALs descriptions in " << kVendorHalsDescPath;
|
||||
DIR* dirPtr = ::opendir(kVendorHalsDescPath);
|
||||
if (dirPtr == NULL) {
|
||||
LOG(ERROR) << "failed to open " << kVendorHalsDescPath;
|
||||
return;
|
||||
}
|
||||
for (struct dirent* entryPtr = ::readdir(dirPtr); entryPtr != NULL;
|
||||
entryPtr = ::readdir(dirPtr)) {
|
||||
if (isDirectory(entryPtr)) continue;
|
||||
|
||||
if (!isFileExtension(entryPtr->d_name, kVendorHalsDescExt))
|
||||
continue; // only process .xml files
|
||||
|
||||
LOG(INFO) << "processing config file: " << entryPtr->d_name;
|
||||
|
||||
std::string fullPath(kVendorHalsDescPath);
|
||||
fullPath.append("/");
|
||||
fullPath.append(entryPtr->d_name);
|
||||
xml = xmlReadFile(fullPath.c_str(), "UTF-8", XML_PARSE_RECOVER);
|
||||
if (!xml) {
|
||||
LOG(ERROR) << "failed to parse: " << entryPtr->d_name << " skipping...";
|
||||
continue;
|
||||
}
|
||||
node = xmlDocGetRootElement(xml);
|
||||
if (!node) {
|
||||
LOG(ERROR) << "empty config file: " << entryPtr->d_name << " skipping...";
|
||||
goto skip;
|
||||
}
|
||||
if (xmlStrcmp(node->name, BAD_CAST "WifiVendorHal")) {
|
||||
LOG(ERROR) << "bad config, root element not WifiVendorHal: " << entryPtr->d_name
|
||||
<< " skipping...";
|
||||
goto skip;
|
||||
}
|
||||
version = (char*)xmlGetProp(node, BAD_CAST "version");
|
||||
if (!version || strtoul(version, NULL, 0) != kVendorHalsDescVersion) {
|
||||
LOG(ERROR) << "conf file: " << entryPtr->d_name
|
||||
<< "must have version: " << kVendorHalsDescVersion << ", skipping...";
|
||||
goto skip;
|
||||
}
|
||||
cnode = node->children;
|
||||
path.clear();
|
||||
desc.primary = false;
|
||||
while (cnode) {
|
||||
if (!xmlStrcmp(cnode->name, BAD_CAST "path")) {
|
||||
value = xmlNodeListGetString(xml, cnode->children, 1);
|
||||
if (value) path = (char*)value;
|
||||
xmlFree(value);
|
||||
} else if (!xmlStrcmp(cnode->name, BAD_CAST "primary")) {
|
||||
value = xmlNodeListGetString(xml, cnode->children, 1);
|
||||
desc.primary = !xmlStrcmp(value, BAD_CAST "1");
|
||||
xmlFree(value);
|
||||
}
|
||||
cnode = cnode->next;
|
||||
}
|
||||
if (path.empty()) {
|
||||
LOG(ERROR) << "hal library path not provided in: " << entryPtr->d_name
|
||||
<< ", skipping...";
|
||||
goto skip;
|
||||
}
|
||||
if (loadVendorHalLib(path, desc)) {
|
||||
if (desc.primary)
|
||||
descs_.insert(descs_.begin(), desc);
|
||||
else
|
||||
descs_.push_back(desc);
|
||||
}
|
||||
skip:
|
||||
xmlFreeDoc(xml);
|
||||
}
|
||||
::closedir(dirPtr);
|
||||
}
|
||||
|
||||
bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc) {
|
||||
void* h = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
|
||||
init_wifi_vendor_hal_func_table_t initfn;
|
||||
wifi_error res;
|
||||
|
||||
if (!h) {
|
||||
LOG(ERROR) << "failed to open vendor hal library: " << path;
|
||||
return false;
|
||||
}
|
||||
initfn = (init_wifi_vendor_hal_func_table_t)dlsym(h, "init_wifi_vendor_hal_func_table");
|
||||
if (!initfn) {
|
||||
LOG(ERROR) << "init_wifi_vendor_hal_func_table not found in: " << path;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!initHalFuncTableWithStubs(&desc.fn)) {
|
||||
LOG(ERROR) << "Can not initialize the basic function pointer table";
|
||||
goto out_err;
|
||||
}
|
||||
res = initfn(&desc.fn);
|
||||
if (res != WIFI_SUCCESS) {
|
||||
LOG(ERROR) << "failed to initialize the vendor func table in: " << path
|
||||
<< " error: " << res;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
res = desc.fn.wifi_early_initialize();
|
||||
// vendor HALs which do not implement early_initialize will return
|
||||
// WIFI_ERROR_NOT_SUPPORTED, treat this as success.
|
||||
if (res != WIFI_SUCCESS && res != WIFI_ERROR_NOT_SUPPORTED) {
|
||||
LOG(ERROR) << "early initialization failed in: " << path << " error: " << res;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
desc.handle = h;
|
||||
return true;
|
||||
out_err:
|
||||
dlclose(h);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace legacy_hal
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
64
wifi/aidl/default/wifi_legacy_hal_factory.h
Normal file
64
wifi/aidl/default/wifi_legacy_hal_factory.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_LEGACY_HAL_FACTORY_H_
|
||||
#define WIFI_LEGACY_HAL_FACTORY_H_
|
||||
|
||||
#include <wifi_system/interface_tool.h>
|
||||
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
// This is in a separate namespace to prevent typename conflicts between
|
||||
// the legacy HAL types and the AIDL interface types.
|
||||
namespace legacy_hal {
|
||||
/**
|
||||
* Class that creates WifiLegacyHal objects for vendor HALs in the system.
|
||||
*/
|
||||
class WifiLegacyHalFactory {
|
||||
public:
|
||||
WifiLegacyHalFactory(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool);
|
||||
virtual ~WifiLegacyHalFactory() = default;
|
||||
|
||||
std::vector<std::shared_ptr<WifiLegacyHal>> getHals();
|
||||
|
||||
private:
|
||||
typedef struct {
|
||||
wifi_hal_fn fn;
|
||||
bool primary;
|
||||
void* handle;
|
||||
} wifi_hal_lib_desc;
|
||||
|
||||
bool initVendorHalDescriptorFromLinked();
|
||||
void initVendorHalsDescriptorList();
|
||||
bool initLinkedHalFunctionTable(wifi_hal_fn* hal_fn);
|
||||
bool loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc);
|
||||
|
||||
std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
|
||||
std::vector<wifi_hal_lib_desc> descs_;
|
||||
std::vector<std::shared_ptr<WifiLegacyHal>> legacy_hals_;
|
||||
};
|
||||
|
||||
} // namespace legacy_hal
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_LEGACY_HAL_FACTORY_H_
|
||||
177
wifi/aidl/default/wifi_legacy_hal_stubs.cpp
Normal file
177
wifi/aidl/default/wifi_legacy_hal_stubs.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi_legacy_hal_stubs.h"
|
||||
|
||||
// TODO: Remove these stubs from HalTool in libwifi-system.
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace legacy_hal {
|
||||
template <typename>
|
||||
struct stubFunction;
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct stubFunction<R (*)(Args...)> {
|
||||
static constexpr R invoke(Args...) { return WIFI_ERROR_NOT_SUPPORTED; }
|
||||
};
|
||||
template <typename... Args>
|
||||
struct stubFunction<void (*)(Args...)> {
|
||||
static constexpr void invoke(Args...) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void populateStubFor(T* val) {
|
||||
*val = &stubFunction<T>::invoke;
|
||||
}
|
||||
|
||||
bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) {
|
||||
if (hal_fn == nullptr) {
|
||||
return false;
|
||||
}
|
||||
populateStubFor(&hal_fn->wifi_initialize);
|
||||
populateStubFor(&hal_fn->wifi_wait_for_driver_ready);
|
||||
populateStubFor(&hal_fn->wifi_cleanup);
|
||||
populateStubFor(&hal_fn->wifi_event_loop);
|
||||
populateStubFor(&hal_fn->wifi_get_error_info);
|
||||
populateStubFor(&hal_fn->wifi_get_supported_feature_set);
|
||||
populateStubFor(&hal_fn->wifi_get_concurrency_matrix);
|
||||
populateStubFor(&hal_fn->wifi_set_scanning_mac_oui);
|
||||
populateStubFor(&hal_fn->wifi_get_supported_channels);
|
||||
populateStubFor(&hal_fn->wifi_is_epr_supported);
|
||||
populateStubFor(&hal_fn->wifi_get_ifaces);
|
||||
populateStubFor(&hal_fn->wifi_get_iface_name);
|
||||
populateStubFor(&hal_fn->wifi_set_iface_event_handler);
|
||||
populateStubFor(&hal_fn->wifi_reset_iface_event_handler);
|
||||
populateStubFor(&hal_fn->wifi_start_gscan);
|
||||
populateStubFor(&hal_fn->wifi_stop_gscan);
|
||||
populateStubFor(&hal_fn->wifi_get_cached_gscan_results);
|
||||
populateStubFor(&hal_fn->wifi_set_bssid_hotlist);
|
||||
populateStubFor(&hal_fn->wifi_reset_bssid_hotlist);
|
||||
populateStubFor(&hal_fn->wifi_set_significant_change_handler);
|
||||
populateStubFor(&hal_fn->wifi_reset_significant_change_handler);
|
||||
populateStubFor(&hal_fn->wifi_get_gscan_capabilities);
|
||||
populateStubFor(&hal_fn->wifi_set_link_stats);
|
||||
populateStubFor(&hal_fn->wifi_get_link_stats);
|
||||
populateStubFor(&hal_fn->wifi_clear_link_stats);
|
||||
populateStubFor(&hal_fn->wifi_get_valid_channels);
|
||||
populateStubFor(&hal_fn->wifi_rtt_range_request);
|
||||
populateStubFor(&hal_fn->wifi_rtt_range_cancel);
|
||||
populateStubFor(&hal_fn->wifi_get_rtt_capabilities);
|
||||
populateStubFor(&hal_fn->wifi_rtt_get_responder_info);
|
||||
populateStubFor(&hal_fn->wifi_enable_responder);
|
||||
populateStubFor(&hal_fn->wifi_disable_responder);
|
||||
populateStubFor(&hal_fn->wifi_set_nodfs_flag);
|
||||
populateStubFor(&hal_fn->wifi_start_logging);
|
||||
populateStubFor(&hal_fn->wifi_set_epno_list);
|
||||
populateStubFor(&hal_fn->wifi_reset_epno_list);
|
||||
populateStubFor(&hal_fn->wifi_set_country_code);
|
||||
populateStubFor(&hal_fn->wifi_get_firmware_memory_dump);
|
||||
populateStubFor(&hal_fn->wifi_set_log_handler);
|
||||
populateStubFor(&hal_fn->wifi_reset_log_handler);
|
||||
populateStubFor(&hal_fn->wifi_set_alert_handler);
|
||||
populateStubFor(&hal_fn->wifi_reset_alert_handler);
|
||||
populateStubFor(&hal_fn->wifi_get_firmware_version);
|
||||
populateStubFor(&hal_fn->wifi_get_ring_buffers_status);
|
||||
populateStubFor(&hal_fn->wifi_get_logger_supported_feature_set);
|
||||
populateStubFor(&hal_fn->wifi_get_ring_data);
|
||||
populateStubFor(&hal_fn->wifi_enable_tdls);
|
||||
populateStubFor(&hal_fn->wifi_disable_tdls);
|
||||
populateStubFor(&hal_fn->wifi_get_tdls_status);
|
||||
populateStubFor(&hal_fn->wifi_get_tdls_capabilities);
|
||||
populateStubFor(&hal_fn->wifi_get_driver_version);
|
||||
populateStubFor(&hal_fn->wifi_set_passpoint_list);
|
||||
populateStubFor(&hal_fn->wifi_reset_passpoint_list);
|
||||
populateStubFor(&hal_fn->wifi_set_lci);
|
||||
populateStubFor(&hal_fn->wifi_set_lcr);
|
||||
populateStubFor(&hal_fn->wifi_start_sending_offloaded_packet);
|
||||
populateStubFor(&hal_fn->wifi_stop_sending_offloaded_packet);
|
||||
populateStubFor(&hal_fn->wifi_start_rssi_monitoring);
|
||||
populateStubFor(&hal_fn->wifi_stop_rssi_monitoring);
|
||||
populateStubFor(&hal_fn->wifi_get_wake_reason_stats);
|
||||
populateStubFor(&hal_fn->wifi_configure_nd_offload);
|
||||
populateStubFor(&hal_fn->wifi_get_driver_memory_dump);
|
||||
populateStubFor(&hal_fn->wifi_start_pkt_fate_monitoring);
|
||||
populateStubFor(&hal_fn->wifi_get_tx_pkt_fates);
|
||||
populateStubFor(&hal_fn->wifi_get_rx_pkt_fates);
|
||||
populateStubFor(&hal_fn->wifi_nan_enable_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_disable_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_publish_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_publish_cancel_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_subscribe_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_subscribe_cancel_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_transmit_followup_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_stats_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_config_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_tca_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_beacon_sdf_payload_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_register_handler);
|
||||
populateStubFor(&hal_fn->wifi_nan_get_version);
|
||||
populateStubFor(&hal_fn->wifi_nan_get_capabilities);
|
||||
populateStubFor(&hal_fn->wifi_nan_data_interface_create);
|
||||
populateStubFor(&hal_fn->wifi_nan_data_interface_delete);
|
||||
populateStubFor(&hal_fn->wifi_nan_data_request_initiator);
|
||||
populateStubFor(&hal_fn->wifi_nan_data_indication_response);
|
||||
populateStubFor(&hal_fn->wifi_nan_data_end);
|
||||
populateStubFor(&hal_fn->wifi_get_packet_filter_capabilities);
|
||||
populateStubFor(&hal_fn->wifi_set_packet_filter);
|
||||
populateStubFor(&hal_fn->wifi_read_packet_filter);
|
||||
populateStubFor(&hal_fn->wifi_get_roaming_capabilities);
|
||||
populateStubFor(&hal_fn->wifi_enable_firmware_roaming);
|
||||
populateStubFor(&hal_fn->wifi_configure_roaming);
|
||||
populateStubFor(&hal_fn->wifi_select_tx_power_scenario);
|
||||
populateStubFor(&hal_fn->wifi_reset_tx_power_scenario);
|
||||
populateStubFor(&hal_fn->wifi_set_radio_mode_change_handler);
|
||||
populateStubFor(&hal_fn->wifi_set_latency_mode);
|
||||
populateStubFor(&hal_fn->wifi_set_thermal_mitigation_mode);
|
||||
populateStubFor(&hal_fn->wifi_virtual_interface_create);
|
||||
populateStubFor(&hal_fn->wifi_virtual_interface_delete);
|
||||
populateStubFor(&hal_fn->wifi_map_dscp_access_category);
|
||||
populateStubFor(&hal_fn->wifi_reset_dscp_mapping);
|
||||
populateStubFor(&hal_fn->wifi_set_subsystem_restart_handler);
|
||||
populateStubFor(&hal_fn->wifi_get_supported_iface_name);
|
||||
populateStubFor(&hal_fn->wifi_early_initialize);
|
||||
populateStubFor(&hal_fn->wifi_get_chip_feature_set);
|
||||
populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection);
|
||||
populateStubFor(&hal_fn->wifi_multi_sta_set_use_case);
|
||||
populateStubFor(&hal_fn->wifi_set_coex_unsafe_channels);
|
||||
populateStubFor(&hal_fn->wifi_set_voip_mode);
|
||||
populateStubFor(&hal_fn->wifi_twt_register_handler);
|
||||
populateStubFor(&hal_fn->wifi_twt_get_capability);
|
||||
populateStubFor(&hal_fn->wifi_twt_setup_request);
|
||||
populateStubFor(&hal_fn->wifi_twt_teardown_request);
|
||||
populateStubFor(&hal_fn->wifi_twt_info_frame_request);
|
||||
populateStubFor(&hal_fn->wifi_twt_get_stats);
|
||||
populateStubFor(&hal_fn->wifi_twt_clear_stats);
|
||||
populateStubFor(&hal_fn->wifi_set_dtim_config);
|
||||
populateStubFor(&hal_fn->wifi_get_usable_channels);
|
||||
populateStubFor(&hal_fn->wifi_trigger_subsystem_restart);
|
||||
populateStubFor(&hal_fn->wifi_set_indoor_state);
|
||||
populateStubFor(&hal_fn->wifi_get_supported_radio_combinations_matrix);
|
||||
populateStubFor(&hal_fn->wifi_nan_rtt_chre_enable_request);
|
||||
populateStubFor(&hal_fn->wifi_nan_rtt_chre_disable_request);
|
||||
populateStubFor(&hal_fn->wifi_chre_register_handler);
|
||||
populateStubFor(&hal_fn->wifi_enable_tx_power_limits);
|
||||
populateStubFor(&hal_fn->wifi_get_cached_scan_results);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace legacy_hal
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
35
wifi/aidl/default/wifi_legacy_hal_stubs.h
Normal file
35
wifi/aidl/default/wifi_legacy_hal_stubs.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_LEGACY_HAL_STUBS_H_
|
||||
#define WIFI_LEGACY_HAL_STUBS_H_
|
||||
|
||||
#include <hardware_legacy/wifi_hal.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace legacy_hal {
|
||||
|
||||
bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn);
|
||||
} // namespace legacy_hal
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_LEGACY_HAL_STUBS_H_
|
||||
88
wifi/aidl/default/wifi_mode_controller.cpp
Normal file
88
wifi/aidl/default/wifi_mode_controller.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi_mode_controller.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
|
||||
namespace {
|
||||
using aidl::android::hardware::wifi::IfaceType;
|
||||
using android::wifi_hal::DriverTool;
|
||||
|
||||
int convertIfaceTypeToFirmwareMode(IfaceType type) {
|
||||
int mode;
|
||||
switch (type) {
|
||||
case IfaceType::AP:
|
||||
mode = DriverTool::kFirmwareModeAp;
|
||||
break;
|
||||
case IfaceType::P2P:
|
||||
mode = DriverTool::kFirmwareModeP2p;
|
||||
break;
|
||||
case IfaceType::NAN_IFACE:
|
||||
// NAN is exposed in STA mode currently.
|
||||
mode = DriverTool::kFirmwareModeSta;
|
||||
break;
|
||||
case IfaceType::STA:
|
||||
mode = DriverTool::kFirmwareModeSta;
|
||||
break;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace mode_controller {
|
||||
|
||||
WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {}
|
||||
|
||||
bool WifiModeController::isFirmwareModeChangeNeeded(IfaceType type) {
|
||||
return driver_tool_->IsFirmwareModeChangeNeeded(convertIfaceTypeToFirmwareMode(type));
|
||||
}
|
||||
|
||||
bool WifiModeController::initialize() {
|
||||
if (!driver_tool_->LoadDriver()) {
|
||||
LOG(ERROR) << "Failed to load WiFi driver";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiModeController::changeFirmwareMode(IfaceType type) {
|
||||
if (!driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))) {
|
||||
LOG(ERROR) << "Failed to change firmware mode";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiModeController::deinitialize() {
|
||||
if (!driver_tool_->UnloadDriver()) {
|
||||
LOG(ERROR) << "Failed to unload WiFi driver";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mode_controller
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
59
wifi/aidl/default/wifi_mode_controller.h
Normal file
59
wifi/aidl/default/wifi_mode_controller.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_MODE_CONTROLLER_H_
|
||||
#define WIFI_MODE_CONTROLLER_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/IWifi.h>
|
||||
#include <wifi_hal/driver_tool.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
namespace mode_controller {
|
||||
|
||||
/**
|
||||
* Class that encapsulates all firmware mode configuration.
|
||||
* This class will perform the necessary firmware reloads to put the chip in the
|
||||
* required state (essentially a wrapper over DriverTool).
|
||||
*/
|
||||
class WifiModeController {
|
||||
public:
|
||||
WifiModeController();
|
||||
virtual ~WifiModeController() = default;
|
||||
|
||||
// Checks if a firmware mode change is necessary to support the specified
|
||||
// iface type operations.
|
||||
virtual bool isFirmwareModeChangeNeeded(IfaceType type);
|
||||
virtual bool initialize();
|
||||
// Change the firmware mode to support the specified iface type operations.
|
||||
virtual bool changeFirmwareMode(IfaceType type);
|
||||
// Unload the driver. This should be invoked whenever |IWifi.stop()| is
|
||||
// invoked.
|
||||
virtual bool deinitialize();
|
||||
|
||||
private:
|
||||
std::unique_ptr<::android::wifi_hal::DriverTool> driver_tool_;
|
||||
};
|
||||
|
||||
} // namespace mode_controller
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_MODE_CONTROLLER_H_
|
||||
751
wifi/aidl/default/wifi_nan_iface.cpp
Normal file
751
wifi/aidl/default/wifi_nan_iface.cpp
Normal file
@@ -0,0 +1,751 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi_nan_iface.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "aidl_return_util.h"
|
||||
#include "aidl_struct_util.h"
|
||||
#include "wifi_status_util.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
using aidl_return_util::validateAndCall;
|
||||
|
||||
WifiNanIface::WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
|
||||
: ifname_(ifname),
|
||||
is_dedicated_iface_(is_dedicated_iface),
|
||||
legacy_hal_(legacy_hal),
|
||||
iface_util_(iface_util),
|
||||
is_valid_(true) {}
|
||||
|
||||
std::shared_ptr<WifiNanIface> WifiNanIface::create(
|
||||
const std::string& ifname, bool is_dedicated_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) {
|
||||
std::shared_ptr<WifiNanIface> ptr = ndk::SharedRefBase::make<WifiNanIface>(
|
||||
ifname, is_dedicated_iface, legacy_hal, iface_util);
|
||||
if (is_dedicated_iface) {
|
||||
// If using a dedicated iface, set the iface up first.
|
||||
if (!iface_util.lock()->setUpState(ifname, true)) {
|
||||
// Fatal failure, invalidate the iface object.
|
||||
ptr->invalidate();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
std::weak_ptr<WifiNanIface> weak_ptr_this(ptr);
|
||||
ptr->setWeakPtr(weak_ptr_this);
|
||||
ptr->registerCallbackHandlers();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void WifiNanIface::registerCallbackHandlers() {
|
||||
// Register all the callbacks here. These should be valid for the lifetime
|
||||
// of the object. Whenever the mode changes legacy HAL will remove
|
||||
// all of these callbacks.
|
||||
legacy_hal::NanCallbackHandlers callback_handlers;
|
||||
std::weak_ptr<WifiNanIface> weak_ptr_this = weak_ptr_this_;
|
||||
|
||||
// Callback for response.
|
||||
callback_handlers.on_notify_response = [weak_ptr_this](legacy_hal::transaction_id id,
|
||||
const legacy_hal::NanResponseMsg& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanStatus nanStatus;
|
||||
if (!aidl_struct_util::convertLegacyNanResponseHeaderToAidl(msg, &nanStatus)) {
|
||||
LOG(ERROR) << "Failed to convert nan response header";
|
||||
return;
|
||||
}
|
||||
|
||||
switch (msg.response_type) {
|
||||
case legacy_hal::NAN_RESPONSE_ENABLED: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyEnableResponse(id, nanStatus).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_RESPONSE_DISABLED: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyDisableResponse(id, nanStatus).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_RESPONSE_PUBLISH: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyStartPublishResponse(id, nanStatus,
|
||||
msg.body.publish_response.publish_id)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyStopPublishResponse(id, nanStatus).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyTransmitFollowupResponse(id, nanStatus).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_RESPONSE_SUBSCRIBE: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyStartSubscribeResponse(
|
||||
id, nanStatus, msg.body.subscribe_response.subscribe_id)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyStopSubscribeResponse(id, nanStatus).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_RESPONSE_CONFIG: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyConfigResponse(id, nanStatus).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_GET_CAPABILITIES: {
|
||||
NanCapabilities aidl_struct;
|
||||
if (!aidl_struct_util::convertLegacyNanCapabilitiesResponseToAidl(
|
||||
msg.body.nan_capabilities, &aidl_struct)) {
|
||||
LOG(ERROR) << "Failed to convert nan capabilities response";
|
||||
return;
|
||||
}
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyCapabilitiesResponse(id, nanStatus, aidl_struct).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_DP_INTERFACE_CREATE: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyCreateDataInterfaceResponse(id, nanStatus).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_DP_INTERFACE_DELETE: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyDeleteDataInterfaceResponse(id, nanStatus).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_DP_INITIATOR_RESPONSE: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyInitiateDataPathResponse(
|
||||
id, nanStatus,
|
||||
msg.body.data_request_response.ndp_instance_id)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_DP_RESPONDER_RESPONSE: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyRespondToDataPathIndicationResponse(id, nanStatus)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_DP_END: {
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->notifyTerminateDataPathResponse(id, nanStatus).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD:
|
||||
/* fall through */
|
||||
case legacy_hal::NAN_RESPONSE_TCA:
|
||||
/* fall through */
|
||||
case legacy_hal::NAN_RESPONSE_STATS:
|
||||
/* fall through */
|
||||
case legacy_hal::NAN_RESPONSE_ERROR:
|
||||
/* fall through */
|
||||
default:
|
||||
LOG(ERROR) << "Unknown or unhandled response type: " << msg.response_type;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_disc_eng_event = [weak_ptr_this](
|
||||
const legacy_hal::NanDiscEngEventInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanClusterEventInd aidl_struct;
|
||||
// event types defined identically - hence can be cast
|
||||
aidl_struct.eventType = (NanClusterEventType)msg.event_type;
|
||||
aidl_struct.addr = std::array<uint8_t, 6>();
|
||||
std::copy(msg.data.mac_addr.addr, msg.data.mac_addr.addr + 6, std::begin(aidl_struct.addr));
|
||||
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventClusterEvent(aidl_struct).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_disabled = [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanStatus status;
|
||||
aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason),
|
||||
&status);
|
||||
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventDisabled(status).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_publish_terminated =
|
||||
[weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanStatus status;
|
||||
aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason,
|
||||
sizeof(msg.nan_reason), &status);
|
||||
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventPublishTerminated(msg.publish_id, status).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_subscribe_terminated =
|
||||
[weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanStatus status;
|
||||
aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason,
|
||||
sizeof(msg.nan_reason), &status);
|
||||
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventSubscribeTerminated(msg.subscribe_id, status).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_match = [weak_ptr_this](const legacy_hal::NanMatchInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanMatchInd aidl_struct;
|
||||
if (!aidl_struct_util::convertLegacyNanMatchIndToAidl(msg, &aidl_struct)) {
|
||||
LOG(ERROR) << "Failed to convert nan capabilities response";
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventMatch(aidl_struct).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_match_expired = [weak_ptr_this](
|
||||
const legacy_hal::NanMatchExpiredInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventMatchExpired(msg.publish_subscribe_id, msg.requestor_instance_id)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_followup = [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanFollowupReceivedInd aidl_struct;
|
||||
if (!aidl_struct_util::convertLegacyNanFollowupIndToAidl(msg, &aidl_struct)) {
|
||||
LOG(ERROR) << "Failed to convert nan capabilities response";
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventFollowupReceived(aidl_struct).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_transmit_follow_up =
|
||||
[weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanStatus status;
|
||||
aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason,
|
||||
sizeof(msg.nan_reason), &status);
|
||||
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventTransmitFollowup(msg.id, status).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_data_path_request =
|
||||
[weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanDataPathRequestInd aidl_struct;
|
||||
if (!aidl_struct_util::convertLegacyNanDataPathRequestIndToAidl(msg,
|
||||
&aidl_struct)) {
|
||||
LOG(ERROR) << "Failed to convert nan capabilities response";
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventDataPathRequest(aidl_struct).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_data_path_confirm =
|
||||
[weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanDataPathConfirmInd aidl_struct;
|
||||
if (!aidl_struct_util::convertLegacyNanDataPathConfirmIndToAidl(msg,
|
||||
&aidl_struct)) {
|
||||
LOG(ERROR) << "Failed to convert nan capabilities response";
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventDataPathConfirm(aidl_struct).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_data_path_end =
|
||||
[weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
for (int i = 0; i < msg.num_ndp_instances; ++i) {
|
||||
if (!callback->eventDataPathTerminated(msg.ndp_instance_id[i]).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
callback_handlers.on_event_beacon_sdf_payload =
|
||||
[](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) {
|
||||
LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called";
|
||||
};
|
||||
|
||||
callback_handlers.on_event_range_request = [](const legacy_hal::NanRangeRequestInd& /* msg */) {
|
||||
LOG(ERROR) << "on_event_range_request - should not be called";
|
||||
};
|
||||
|
||||
callback_handlers.on_event_range_report = [](const legacy_hal::NanRangeReportInd& /* msg */) {
|
||||
LOG(ERROR) << "on_event_range_report - should not be called";
|
||||
};
|
||||
|
||||
callback_handlers.on_event_schedule_update =
|
||||
[weak_ptr_this](const legacy_hal::NanDataPathScheduleUpdateInd& msg) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
NanDataPathScheduleUpdateInd aidl_struct;
|
||||
if (!aidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToAidl(
|
||||
msg, &aidl_struct)) {
|
||||
LOG(ERROR) << "Failed to convert nan capabilities response";
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventDataPathScheduleUpdate(aidl_struct).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, callback_handlers);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// Register for iface state toggle events.
|
||||
iface_util::IfaceEventHandlers event_handlers = {};
|
||||
event_handlers.on_state_toggle_off_on = [weak_ptr_this](const std::string& /* iface_name */) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
// Tell framework that NAN has been disabled.
|
||||
NanStatus status = {NanStatusCode::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->eventDisabled(status).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
|
||||
}
|
||||
|
||||
void WifiNanIface::setWeakPtr(std::weak_ptr<WifiNanIface> ptr) {
|
||||
weak_ptr_this_ = ptr;
|
||||
}
|
||||
|
||||
void WifiNanIface::invalidate() {
|
||||
if (!isValid()) {
|
||||
return;
|
||||
}
|
||||
// send commands to HAL to actually disable and destroy interfaces
|
||||
legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
|
||||
legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
|
||||
legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
|
||||
iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
|
||||
legacy_hal_.reset();
|
||||
event_cb_handler_.invalidate();
|
||||
is_valid_ = false;
|
||||
if (is_dedicated_iface_) {
|
||||
// If using a dedicated iface, set the iface down.
|
||||
iface_util_.lock()->setUpState(ifname_, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool WifiNanIface::isValid() {
|
||||
return is_valid_;
|
||||
}
|
||||
|
||||
std::string WifiNanIface::getName() {
|
||||
return ifname_;
|
||||
}
|
||||
|
||||
std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks() {
|
||||
LOG(ERROR) << "Using original getEventCallbacks";
|
||||
return event_cb_handler_.getCallbacks();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::getName(std::string* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::getNameInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::registerEventCallback(
|
||||
const std::shared_ptr<IWifiNanIfaceEventCallback>& callback) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::registerEventCallbackInternal, callback);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::getCapabilitiesRequest(char16_t in_cmdId) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::getCapabilitiesRequestInternal, in_cmdId);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::enableRequest(char16_t in_cmdId, const NanEnableRequest& in_msg1,
|
||||
const NanConfigRequestSupplemental& in_msg2) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::enableRequestInternal, in_cmdId, in_msg1, in_msg2);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::configRequest(char16_t in_cmdId, const NanConfigRequest& in_msg1,
|
||||
const NanConfigRequestSupplemental& in_msg2) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::configRequestInternal, in_cmdId, in_msg1, in_msg2);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::disableRequest(char16_t in_cmdId) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::disableRequestInternal, in_cmdId);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::startPublishRequest(char16_t in_cmdId,
|
||||
const NanPublishRequest& in_msg) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::startPublishRequestInternal, in_cmdId, in_msg);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::stopPublishRequest(char16_t in_cmdId, int8_t in_sessionId) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::stopPublishRequestInternal, in_cmdId, in_sessionId);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::startSubscribeRequest(char16_t in_cmdId,
|
||||
const NanSubscribeRequest& in_msg) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::startSubscribeRequestInternal, in_cmdId, in_msg);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::stopSubscribeRequest(char16_t in_cmdId, int8_t in_sessionId) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::stopSubscribeRequestInternal, in_cmdId, in_sessionId);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::transmitFollowupRequest(char16_t in_cmdId,
|
||||
const NanTransmitFollowupRequest& in_msg) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::transmitFollowupRequestInternal, in_cmdId, in_msg);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::createDataInterfaceRequest(char16_t in_cmdId,
|
||||
const std::string& in_ifaceName) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::createDataInterfaceRequestInternal, in_cmdId,
|
||||
in_ifaceName);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::deleteDataInterfaceRequest(char16_t in_cmdId,
|
||||
const std::string& in_ifaceName) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::deleteDataInterfaceRequestInternal, in_cmdId,
|
||||
in_ifaceName);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::initiateDataPathRequest(char16_t in_cmdId,
|
||||
const NanInitiateDataPathRequest& in_msg) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::initiateDataPathRequestInternal, in_cmdId, in_msg);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::respondToDataPathIndicationRequest(
|
||||
char16_t in_cmdId, const NanRespondToDataPathIndicationRequest& in_msg) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::respondToDataPathIndicationRequestInternal, in_cmdId,
|
||||
in_msg);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::terminateDataPathRequest(char16_t in_cmdId,
|
||||
int32_t in_ndpInstanceId) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiNanIface::terminateDataPathRequestInternal, in_cmdId,
|
||||
in_ndpInstanceId);
|
||||
}
|
||||
|
||||
std::pair<std::string, ndk::ScopedAStatus> WifiNanIface::getNameInternal() {
|
||||
return {ifname_, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::registerEventCallbackInternal(
|
||||
const std::shared_ptr<IWifiNanIfaceEventCallback>& callback) {
|
||||
if (!event_cb_handler_.addCallback(callback)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::getCapabilitiesRequestInternal(char16_t cmd_id) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::enableRequestInternal(char16_t cmd_id,
|
||||
const NanEnableRequest& msg1,
|
||||
const NanConfigRequestSupplemental& msg2) {
|
||||
legacy_hal::NanEnableRequest legacy_msg;
|
||||
if (!aidl_struct_util::convertAidlNanEnableRequestToLegacy(msg1, msg2, &legacy_msg)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::configRequestInternal(char16_t cmd_id,
|
||||
const NanConfigRequest& msg1,
|
||||
const NanConfigRequestSupplemental& msg2) {
|
||||
legacy_hal::NanConfigRequest legacy_msg;
|
||||
if (!aidl_struct_util::convertAidlNanConfigRequestToLegacy(msg1, msg2, &legacy_msg)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::disableRequestInternal(char16_t cmd_id) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::startPublishRequestInternal(char16_t cmd_id,
|
||||
const NanPublishRequest& msg) {
|
||||
legacy_hal::NanPublishRequest legacy_msg;
|
||||
if (!aidl_struct_util::convertAidlNanPublishRequestToLegacy(msg, &legacy_msg)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::stopPublishRequestInternal(char16_t cmd_id, int8_t sessionId) {
|
||||
legacy_hal::NanPublishCancelRequest legacy_msg;
|
||||
legacy_msg.publish_id = sessionId;
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id, legacy_msg);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::startSubscribeRequestInternal(char16_t cmd_id,
|
||||
const NanSubscribeRequest& msg) {
|
||||
legacy_hal::NanSubscribeRequest legacy_msg;
|
||||
if (!aidl_struct_util::convertAidlNanSubscribeRequestToLegacy(msg, &legacy_msg)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::stopSubscribeRequestInternal(char16_t cmd_id, int8_t sessionId) {
|
||||
legacy_hal::NanSubscribeCancelRequest legacy_msg;
|
||||
legacy_msg.subscribe_id = sessionId;
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id, legacy_msg);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::transmitFollowupRequestInternal(
|
||||
char16_t cmd_id, const NanTransmitFollowupRequest& msg) {
|
||||
legacy_hal::NanTransmitFollowupRequest legacy_msg;
|
||||
if (!aidl_struct_util::convertAidlNanTransmitFollowupRequestToLegacy(msg, &legacy_msg)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id, legacy_msg);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiNanIface::createDataInterfaceRequestInternal(char16_t cmd_id,
|
||||
const std::string& iface_name) {
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
ndk::ScopedAStatus WifiNanIface::deleteDataInterfaceRequestInternal(char16_t cmd_id,
|
||||
const std::string& iface_name) {
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
ndk::ScopedAStatus WifiNanIface::initiateDataPathRequestInternal(
|
||||
char16_t cmd_id, const NanInitiateDataPathRequest& msg) {
|
||||
legacy_hal::NanDataPathInitiatorRequest legacy_msg;
|
||||
if (!aidl_struct_util::convertAidlNanDataPathInitiatorRequestToLegacy(msg, &legacy_msg)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, legacy_msg);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
ndk::ScopedAStatus WifiNanIface::respondToDataPathIndicationRequestInternal(
|
||||
char16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg) {
|
||||
legacy_hal::NanDataPathIndicationResponse legacy_msg;
|
||||
if (!aidl_struct_util::convertAidlNanDataPathIndicationResponseToLegacy(msg, &legacy_msg)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, legacy_msg);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
ndk::ScopedAStatus WifiNanIface::terminateDataPathRequestInternal(char16_t cmd_id,
|
||||
int32_t ndpInstanceId) {
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
134
wifi/aidl/default/wifi_nan_iface.h
Normal file
134
wifi/aidl/default/wifi_nan_iface.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_NAN_IFACE_H_
|
||||
#define WIFI_NAN_IFACE_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/BnWifiNanIface.h>
|
||||
#include <aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.h>
|
||||
#include <android-base/macros.h>
|
||||
|
||||
#include "aidl_callback_util.h"
|
||||
#include "wifi_iface_util.h"
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
/**
|
||||
* AIDL interface object used to control a NAN Iface instance.
|
||||
*/
|
||||
class WifiNanIface : public BnWifiNanIface {
|
||||
public:
|
||||
WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
|
||||
|
||||
// Factory method - use instead of default constructor.
|
||||
static std::shared_ptr<WifiNanIface> create(
|
||||
const std::string& ifname, bool is_dedicated_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
|
||||
|
||||
// Refer to |WifiChip::invalidate()|.
|
||||
void invalidate();
|
||||
bool isValid();
|
||||
std::string getName();
|
||||
|
||||
// AIDL methods exposed.
|
||||
ndk::ScopedAStatus getName(std::string* _aidl_return) override;
|
||||
ndk::ScopedAStatus registerEventCallback(
|
||||
const std::shared_ptr<IWifiNanIfaceEventCallback>& in_callback) override;
|
||||
ndk::ScopedAStatus getCapabilitiesRequest(char16_t in_cmdId) override;
|
||||
ndk::ScopedAStatus enableRequest(char16_t in_cmdId, const NanEnableRequest& in_msg1,
|
||||
const NanConfigRequestSupplemental& in_msg2) override;
|
||||
ndk::ScopedAStatus configRequest(char16_t in_cmdId, const NanConfigRequest& in_msg1,
|
||||
const NanConfigRequestSupplemental& in_msg2) override;
|
||||
ndk::ScopedAStatus disableRequest(char16_t in_cmdId) override;
|
||||
ndk::ScopedAStatus startPublishRequest(char16_t in_cmdId,
|
||||
const NanPublishRequest& in_msg) override;
|
||||
ndk::ScopedAStatus stopPublishRequest(char16_t in_cmdId, int8_t in_sessionId) override;
|
||||
ndk::ScopedAStatus startSubscribeRequest(char16_t in_cmdId,
|
||||
const NanSubscribeRequest& in_msg) override;
|
||||
ndk::ScopedAStatus stopSubscribeRequest(char16_t in_cmdId, int8_t in_sessionId) override;
|
||||
ndk::ScopedAStatus transmitFollowupRequest(char16_t in_cmdId,
|
||||
const NanTransmitFollowupRequest& in_msg) override;
|
||||
ndk::ScopedAStatus createDataInterfaceRequest(char16_t in_cmdId,
|
||||
const std::string& in_ifaceName) override;
|
||||
ndk::ScopedAStatus deleteDataInterfaceRequest(char16_t in_cmdId,
|
||||
const std::string& in_ifaceName) override;
|
||||
ndk::ScopedAStatus initiateDataPathRequest(char16_t in_cmdId,
|
||||
const NanInitiateDataPathRequest& in_msg) override;
|
||||
ndk::ScopedAStatus respondToDataPathIndicationRequest(
|
||||
char16_t in_cmdId, const NanRespondToDataPathIndicationRequest& in_msg) override;
|
||||
ndk::ScopedAStatus terminateDataPathRequest(char16_t in_cmdId,
|
||||
int32_t in_ndpInstanceId) override;
|
||||
|
||||
protected:
|
||||
// Accessible to child class in the gTest suite.
|
||||
void setWeakPtr(std::weak_ptr<WifiNanIface> ptr);
|
||||
void registerCallbackHandlers();
|
||||
|
||||
private:
|
||||
// Corresponding worker functions for the AIDL methods.
|
||||
std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
|
||||
ndk::ScopedAStatus registerEventCallbackInternal(
|
||||
const std::shared_ptr<IWifiNanIfaceEventCallback>& callback);
|
||||
ndk::ScopedAStatus getCapabilitiesRequestInternal(char16_t cmd_id);
|
||||
ndk::ScopedAStatus enableRequestInternal(char16_t cmd_id, const NanEnableRequest& msg1,
|
||||
const NanConfigRequestSupplemental& msg2);
|
||||
ndk::ScopedAStatus configRequestInternal(char16_t cmd_id, const NanConfigRequest& msg1,
|
||||
const NanConfigRequestSupplemental& msg2);
|
||||
ndk::ScopedAStatus disableRequestInternal(char16_t cmd_id);
|
||||
ndk::ScopedAStatus startPublishRequestInternal(char16_t cmd_id, const NanPublishRequest& msg);
|
||||
ndk::ScopedAStatus stopPublishRequestInternal(char16_t cmd_id, int8_t sessionId);
|
||||
ndk::ScopedAStatus startSubscribeRequestInternal(char16_t cmd_id,
|
||||
const NanSubscribeRequest& msg);
|
||||
ndk::ScopedAStatus stopSubscribeRequestInternal(char16_t cmd_id, int8_t sessionId);
|
||||
ndk::ScopedAStatus transmitFollowupRequestInternal(char16_t cmd_id,
|
||||
const NanTransmitFollowupRequest& msg);
|
||||
ndk::ScopedAStatus createDataInterfaceRequestInternal(char16_t cmd_id,
|
||||
const std::string& iface_name);
|
||||
ndk::ScopedAStatus deleteDataInterfaceRequestInternal(char16_t cmd_id,
|
||||
const std::string& iface_name);
|
||||
ndk::ScopedAStatus initiateDataPathRequestInternal(char16_t cmd_id,
|
||||
const NanInitiateDataPathRequest& msg);
|
||||
ndk::ScopedAStatus respondToDataPathIndicationRequestInternal(
|
||||
char16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg);
|
||||
ndk::ScopedAStatus terminateDataPathRequestInternal(char16_t cmd_id, int32_t ndpInstanceId);
|
||||
|
||||
// Overridden in the gTest suite.
|
||||
virtual std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> getEventCallbacks();
|
||||
|
||||
std::string ifname_;
|
||||
bool is_dedicated_iface_;
|
||||
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
|
||||
std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
|
||||
bool is_valid_;
|
||||
std::weak_ptr<WifiNanIface> weak_ptr_this_;
|
||||
aidl_callback_util::AidlCallbackHandler<IWifiNanIfaceEventCallback> event_cb_handler_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WifiNanIface);
|
||||
};
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_NAN_IFACE_H_
|
||||
59
wifi/aidl/default/wifi_p2p_iface.cpp
Normal file
59
wifi/aidl/default/wifi_p2p_iface.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi_p2p_iface.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "aidl_return_util.h"
|
||||
#include "wifi_status_util.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
using aidl_return_util::validateAndCall;
|
||||
|
||||
WifiP2pIface::WifiP2pIface(const std::string& ifname,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
|
||||
: ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {}
|
||||
|
||||
void WifiP2pIface::invalidate() {
|
||||
legacy_hal_.reset();
|
||||
is_valid_ = false;
|
||||
}
|
||||
|
||||
bool WifiP2pIface::isValid() {
|
||||
return is_valid_;
|
||||
}
|
||||
|
||||
std::string WifiP2pIface::getName() {
|
||||
return ifname_;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiP2pIface::getName(std::string* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiP2pIface::getNameInternal, _aidl_return);
|
||||
}
|
||||
|
||||
std::pair<std::string, ndk::ScopedAStatus> WifiP2pIface::getNameInternal() {
|
||||
return {ifname_, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
61
wifi/aidl/default/wifi_p2p_iface.h
Normal file
61
wifi/aidl/default/wifi_p2p_iface.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_P2P_IFACE_H_
|
||||
#define WIFI_P2P_IFACE_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/BnWifiP2pIface.h>
|
||||
#include <android-base/macros.h>
|
||||
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
/**
|
||||
* AIDL interface object used to control a P2P Iface instance.
|
||||
*/
|
||||
class WifiP2pIface : public BnWifiP2pIface {
|
||||
public:
|
||||
WifiP2pIface(const std::string& ifname,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
|
||||
// Refer to |WifiChip::invalidate()|.
|
||||
void invalidate();
|
||||
bool isValid();
|
||||
std::string getName();
|
||||
|
||||
// AIDL methods exposed.
|
||||
ndk::ScopedAStatus getName(std::string* _aidl_return) override;
|
||||
|
||||
private:
|
||||
// Corresponding worker functions for the AIDL methods.
|
||||
std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
|
||||
|
||||
std::string ifname_;
|
||||
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
|
||||
bool is_valid_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WifiP2pIface);
|
||||
};
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_P2P_IFACE_H_
|
||||
255
wifi/aidl/default/wifi_rtt_controller.cpp
Normal file
255
wifi/aidl/default/wifi_rtt_controller.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi_rtt_controller.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "aidl_return_util.h"
|
||||
#include "aidl_struct_util.h"
|
||||
#include "wifi_status_util.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
using aidl_return_util::validateAndCall;
|
||||
|
||||
WifiRttController::WifiRttController(const std::string& iface_name,
|
||||
const std::shared_ptr<IWifiStaIface>& bound_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
|
||||
: ifname_(iface_name), bound_iface_(bound_iface), legacy_hal_(legacy_hal), is_valid_(true) {}
|
||||
|
||||
std::shared_ptr<WifiRttController> WifiRttController::create(
|
||||
const std::string& iface_name, const std::shared_ptr<IWifiStaIface>& bound_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) {
|
||||
std::shared_ptr<WifiRttController> ptr =
|
||||
ndk::SharedRefBase::make<WifiRttController>(iface_name, bound_iface, legacy_hal);
|
||||
std::weak_ptr<WifiRttController> weak_ptr_this(ptr);
|
||||
ptr->setWeakPtr(weak_ptr_this);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void WifiRttController::invalidate() {
|
||||
legacy_hal_.reset();
|
||||
event_callbacks_.clear();
|
||||
is_valid_ = false;
|
||||
};
|
||||
|
||||
bool WifiRttController::isValid() {
|
||||
return is_valid_;
|
||||
}
|
||||
|
||||
void WifiRttController::setWeakPtr(std::weak_ptr<WifiRttController> ptr) {
|
||||
weak_ptr_this_ = ptr;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<IWifiRttControllerEventCallback>>
|
||||
WifiRttController::getEventCallbacks() {
|
||||
return event_callbacks_;
|
||||
}
|
||||
|
||||
std::string WifiRttController::getIfaceName() {
|
||||
return ifname_;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::getBoundIface(std::shared_ptr<IWifiStaIface>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
&WifiRttController::getBoundIfaceInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::registerEventCallback(
|
||||
const std::shared_ptr<IWifiRttControllerEventCallback>& callback) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
&WifiRttController::registerEventCallbackInternal, callback);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::rangeRequest(int32_t in_cmdId,
|
||||
const std::vector<RttConfig>& in_rttConfigs) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
&WifiRttController::rangeRequestInternal, in_cmdId, in_rttConfigs);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::rangeCancel(int32_t in_cmdId,
|
||||
const std::vector<MacAddress>& in_addrs) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
&WifiRttController::rangeCancelInternal, in_cmdId, in_addrs);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::getCapabilities(RttCapabilities* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
&WifiRttController::getCapabilitiesInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::setLci(int32_t in_cmdId, const RttLciInformation& in_lci) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
&WifiRttController::setLciInternal, in_cmdId, in_lci);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::setLcr(int32_t in_cmdId, const RttLcrInformation& in_lcr) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
&WifiRttController::setLcrInternal, in_cmdId, in_lcr);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::getResponderInfo(RttResponder* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
&WifiRttController::getResponderInfoInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::enableResponder(int32_t in_cmdId,
|
||||
const WifiChannelInfo& in_channelHint,
|
||||
int32_t in_maxDurationInSeconds,
|
||||
const RttResponder& in_info) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
&WifiRttController::enableResponderInternal, in_cmdId, in_channelHint,
|
||||
in_maxDurationInSeconds, in_info);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::disableResponder(int32_t in_cmdId) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
|
||||
&WifiRttController::disableResponderInternal, in_cmdId);
|
||||
}
|
||||
|
||||
std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus>
|
||||
WifiRttController::getBoundIfaceInternal() {
|
||||
return {bound_iface_, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::registerEventCallbackInternal(
|
||||
const std::shared_ptr<IWifiRttControllerEventCallback>& callback) {
|
||||
event_callbacks_.emplace_back(callback);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::rangeRequestInternal(
|
||||
int32_t cmd_id, const std::vector<RttConfig>& rtt_configs) {
|
||||
std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
|
||||
if (!aidl_struct_util::convertAidlVectorOfRttConfigToLegacy(rtt_configs, &legacy_configs)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
std::weak_ptr<WifiRttController> weak_ptr_this = weak_ptr_this_;
|
||||
const auto& on_results_callback =
|
||||
[weak_ptr_this](legacy_hal::wifi_request_id id,
|
||||
const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
std::vector<RttResult> aidl_results;
|
||||
if (!aidl_struct_util::convertLegacyVectorOfRttResultToAidl(results,
|
||||
&aidl_results)) {
|
||||
LOG(ERROR) << "Failed to convert rtt results to AIDL structs";
|
||||
return;
|
||||
}
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->onResults(id, aidl_results).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke the callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequest(
|
||||
ifname_, cmd_id, legacy_configs, on_results_callback);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::rangeCancelInternal(int32_t cmd_id,
|
||||
const std::vector<MacAddress>& addrs) {
|
||||
std::vector<std::array<uint8_t, ETH_ALEN>> legacy_addrs;
|
||||
for (const auto& addr : addrs) {
|
||||
std::array<uint8_t, ETH_ALEN> addr_array;
|
||||
std::copy_n(addr.data.begin(), ETH_ALEN, addr_array.begin());
|
||||
legacy_addrs.push_back(addr_array);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, legacy_addrs);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
std::pair<RttCapabilities, ndk::ScopedAStatus> WifiRttController::getCapabilitiesInternal() {
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
legacy_hal::wifi_rtt_capabilities legacy_caps;
|
||||
std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
return {RttCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
RttCapabilities aidl_caps;
|
||||
if (!aidl_struct_util::convertLegacyRttCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
|
||||
return {RttCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {aidl_caps, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::setLciInternal(int32_t cmd_id, const RttLciInformation& lci) {
|
||||
legacy_hal::wifi_lci_information legacy_lci;
|
||||
if (!aidl_struct_util::convertAidlRttLciInformationToLegacy(lci, &legacy_lci)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::setLcrInternal(int32_t cmd_id, const RttLcrInformation& lcr) {
|
||||
legacy_hal::wifi_lcr_information legacy_lcr;
|
||||
if (!aidl_struct_util::convertAidlRttLcrInformationToLegacy(lcr, &legacy_lcr)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
std::pair<RttResponder, ndk::ScopedAStatus> WifiRttController::getResponderInfoInternal() {
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
legacy_hal::wifi_rtt_responder legacy_responder;
|
||||
std::tie(legacy_status, legacy_responder) = legacy_hal_.lock()->getRttResponderInfo(ifname_);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
return {RttResponder{}, createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
RttResponder aidl_responder;
|
||||
if (!aidl_struct_util::convertLegacyRttResponderToAidl(legacy_responder, &aidl_responder)) {
|
||||
return {RttResponder{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {aidl_responder, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::enableResponderInternal(int32_t cmd_id,
|
||||
const WifiChannelInfo& channel_hint,
|
||||
int32_t max_duration_seconds,
|
||||
const RttResponder& info) {
|
||||
legacy_hal::wifi_channel_info legacy_channel_info;
|
||||
if (!aidl_struct_util::convertAidlWifiChannelInfoToLegacy(channel_hint, &legacy_channel_info)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_rtt_responder legacy_responder;
|
||||
if (!aidl_struct_util::convertAidlRttResponderToLegacy(info, &legacy_responder)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableRttResponder(
|
||||
ifname_, cmd_id, legacy_channel_info, max_duration_seconds, legacy_responder);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiRttController::disableResponderInternal(int32_t cmd_id) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
102
wifi/aidl/default/wifi_rtt_controller.h
Normal file
102
wifi/aidl/default/wifi_rtt_controller.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_RTT_CONTROLLER_H_
|
||||
#define WIFI_RTT_CONTROLLER_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/BnWifiRttController.h>
|
||||
#include <aidl/android/hardware/wifi/IWifiRttControllerEventCallback.h>
|
||||
#include <aidl/android/hardware/wifi/IWifiStaIface.h>
|
||||
#include <android-base/macros.h>
|
||||
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
/**
|
||||
* AIDL interface object used to control all RTT operations.
|
||||
*/
|
||||
class WifiRttController : public BnWifiRttController {
|
||||
public:
|
||||
WifiRttController(const std::string& iface_name,
|
||||
const std::shared_ptr<IWifiStaIface>& bound_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
|
||||
// Factory method - use instead of default constructor.
|
||||
static std::shared_ptr<WifiRttController> create(
|
||||
const std::string& iface_name, const std::shared_ptr<IWifiStaIface>& bound_iface,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
|
||||
|
||||
// Refer to |WifiChip::invalidate()|.
|
||||
void invalidate();
|
||||
bool isValid();
|
||||
std::vector<std::shared_ptr<IWifiRttControllerEventCallback>> getEventCallbacks();
|
||||
std::string getIfaceName();
|
||||
|
||||
// AIDL methods exposed.
|
||||
ndk::ScopedAStatus getBoundIface(std::shared_ptr<IWifiStaIface>* _aidl_return) override;
|
||||
ndk::ScopedAStatus registerEventCallback(
|
||||
const std::shared_ptr<IWifiRttControllerEventCallback>& callback) override;
|
||||
ndk::ScopedAStatus rangeRequest(int32_t in_cmdId,
|
||||
const std::vector<RttConfig>& in_rttConfigs) override;
|
||||
ndk::ScopedAStatus rangeCancel(int32_t in_cmdId,
|
||||
const std::vector<MacAddress>& in_addrs) override;
|
||||
ndk::ScopedAStatus getCapabilities(RttCapabilities* _aidl_return) override;
|
||||
ndk::ScopedAStatus setLci(int32_t in_cmdId, const RttLciInformation& in_lci) override;
|
||||
ndk::ScopedAStatus setLcr(int32_t in_cmdId, const RttLcrInformation& in_lcr) override;
|
||||
ndk::ScopedAStatus getResponderInfo(RttResponder* _aidl_return) override;
|
||||
ndk::ScopedAStatus enableResponder(int32_t in_cmdId, const WifiChannelInfo& in_channelHint,
|
||||
int32_t in_maxDurationInSeconds,
|
||||
const RttResponder& in_info) override;
|
||||
ndk::ScopedAStatus disableResponder(int32_t in_cmdId) override;
|
||||
|
||||
private:
|
||||
// Corresponding worker functions for the AIDL methods.
|
||||
std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> getBoundIfaceInternal();
|
||||
ndk::ScopedAStatus registerEventCallbackInternal(
|
||||
const std::shared_ptr<IWifiRttControllerEventCallback>& callback);
|
||||
ndk::ScopedAStatus rangeRequestInternal(int32_t cmd_id,
|
||||
const std::vector<RttConfig>& rtt_configs);
|
||||
ndk::ScopedAStatus rangeCancelInternal(int32_t cmd_id, const std::vector<MacAddress>& addrs);
|
||||
std::pair<RttCapabilities, ndk::ScopedAStatus> getCapabilitiesInternal();
|
||||
ndk::ScopedAStatus setLciInternal(int32_t cmd_id, const RttLciInformation& lci);
|
||||
ndk::ScopedAStatus setLcrInternal(int32_t cmd_id, const RttLcrInformation& lcr);
|
||||
std::pair<RttResponder, ndk::ScopedAStatus> getResponderInfoInternal();
|
||||
ndk::ScopedAStatus enableResponderInternal(int32_t cmd_id, const WifiChannelInfo& channel_hint,
|
||||
int32_t max_duration_seconds,
|
||||
const RttResponder& info);
|
||||
ndk::ScopedAStatus disableResponderInternal(int32_t cmd_id);
|
||||
|
||||
void setWeakPtr(std::weak_ptr<WifiRttController> ptr);
|
||||
|
||||
std::string ifname_;
|
||||
std::shared_ptr<IWifiStaIface> bound_iface_;
|
||||
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
|
||||
std::vector<std::shared_ptr<IWifiRttControllerEventCallback>> event_callbacks_;
|
||||
std::weak_ptr<WifiRttController> weak_ptr_this_;
|
||||
bool is_valid_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WifiRttController);
|
||||
};
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_RTT_CONTROLLER_H_
|
||||
558
wifi/aidl/default/wifi_sta_iface.cpp
Normal file
558
wifi/aidl/default/wifi_sta_iface.cpp
Normal file
@@ -0,0 +1,558 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi_sta_iface.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "aidl_return_util.h"
|
||||
#include "aidl_struct_util.h"
|
||||
#include "wifi_status_util.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
using aidl_return_util::validateAndCall;
|
||||
|
||||
WifiStaIface::WifiStaIface(const std::string& ifname,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
|
||||
: ifname_(ifname), legacy_hal_(legacy_hal), iface_util_(iface_util), is_valid_(true) {
|
||||
// Turn on DFS channel usage for STA iface.
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDfsFlag(ifname_, true);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to set DFS flag; DFS channels may be unavailable.";
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<WifiStaIface> WifiStaIface::create(
|
||||
const std::string& ifname, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) {
|
||||
std::shared_ptr<WifiStaIface> ptr =
|
||||
ndk::SharedRefBase::make<WifiStaIface>(ifname, legacy_hal, iface_util);
|
||||
std::weak_ptr<WifiStaIface> weak_ptr_this(ptr);
|
||||
ptr->setWeakPtr(weak_ptr_this);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void WifiStaIface::invalidate() {
|
||||
legacy_hal_.reset();
|
||||
event_cb_handler_.invalidate();
|
||||
is_valid_ = false;
|
||||
}
|
||||
|
||||
void WifiStaIface::setWeakPtr(std::weak_ptr<WifiStaIface> ptr) {
|
||||
weak_ptr_this_ = ptr;
|
||||
}
|
||||
|
||||
bool WifiStaIface::isValid() {
|
||||
return is_valid_;
|
||||
}
|
||||
|
||||
std::string WifiStaIface::getName() {
|
||||
return ifname_;
|
||||
}
|
||||
|
||||
std::set<std::shared_ptr<IWifiStaIfaceEventCallback>> WifiStaIface::getEventCallbacks() {
|
||||
return event_cb_handler_.getCallbacks();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::getName(std::string* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getNameInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::registerEventCallback(
|
||||
const std::shared_ptr<IWifiStaIfaceEventCallback>& in_callback) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::registerEventCallbackInternal, in_callback);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::getCapabilities(
|
||||
IWifiStaIface::StaIfaceCapabilityMask* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getCapabilitiesInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::getApfPacketFilterCapabilities(
|
||||
StaApfPacketFilterCapabilities* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getApfPacketFilterCapabilitiesInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::installApfPacketFilter(const std::vector<uint8_t>& in_program) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::installApfPacketFilterInternal, in_program);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::readApfPacketFilterData(std::vector<uint8_t>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::readApfPacketFilterDataInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::getBackgroundScanCapabilities(
|
||||
StaBackgroundScanCapabilities* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getBackgroundScanCapabilitiesInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::getValidFrequenciesForBand(WifiBand in_band,
|
||||
std::vector<int32_t>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getValidFrequenciesForBandInternal, _aidl_return,
|
||||
in_band);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::startBackgroundScan(int32_t in_cmdId,
|
||||
const StaBackgroundScanParameters& in_params) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::startBackgroundScanInternal, in_cmdId, in_params);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::stopBackgroundScan(int32_t in_cmdId) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::stopBackgroundScanInternal, in_cmdId);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::enableLinkLayerStatsCollection(bool in_debug) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::enableLinkLayerStatsCollectionInternal, in_debug);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::disableLinkLayerStatsCollection() {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::disableLinkLayerStatsCollectionInternal);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::getLinkLayerStats(StaLinkLayerStats* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getLinkLayerStatsInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::startRssiMonitoring(int32_t in_cmdId, int32_t in_maxRssi,
|
||||
int32_t in_minRssi) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::startRssiMonitoringInternal, in_cmdId, in_maxRssi,
|
||||
in_minRssi);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::stopRssiMonitoring(int32_t in_cmdId) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::stopRssiMonitoringInternal, in_cmdId);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::getRoamingCapabilities(StaRoamingCapabilities* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getRoamingCapabilitiesInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::configureRoaming(const StaRoamingConfig& in_config) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::configureRoamingInternal, in_config);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::setRoamingState(StaRoamingState in_state) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::setRoamingStateInternal, in_state);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::enableNdOffload(bool in_enable) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::enableNdOffloadInternal, in_enable);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::startSendingKeepAlivePackets(
|
||||
int32_t in_cmdId, const std::vector<uint8_t>& in_ipPacketData, char16_t in_etherType,
|
||||
const std::array<uint8_t, 6>& in_srcAddress, const std::array<uint8_t, 6>& in_dstAddress,
|
||||
int32_t in_periodInMs) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::startSendingKeepAlivePacketsInternal, in_cmdId,
|
||||
in_ipPacketData, in_etherType, in_srcAddress, in_dstAddress,
|
||||
in_periodInMs);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::stopSendingKeepAlivePackets(int32_t in_cmdId) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::stopSendingKeepAlivePacketsInternal, in_cmdId);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::startDebugPacketFateMonitoring() {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::startDebugPacketFateMonitoringInternal);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::getDebugTxPacketFates(
|
||||
std::vector<WifiDebugTxPacketFateReport>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getDebugTxPacketFatesInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::getDebugRxPacketFates(
|
||||
std::vector<WifiDebugRxPacketFateReport>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getDebugRxPacketFatesInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::setMacAddress(const std::array<uint8_t, 6>& in_mac) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::setMacAddressInternal, in_mac);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getFactoryMacAddressInternal, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::setScanMode(bool in_enable) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::setScanModeInternal, in_enable);
|
||||
}
|
||||
|
||||
std::pair<std::string, ndk::ScopedAStatus> WifiStaIface::getNameInternal() {
|
||||
return {ifname_, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::registerEventCallbackInternal(
|
||||
const std::shared_ptr<IWifiStaIfaceEventCallback>& callback) {
|
||||
if (!event_cb_handler_.addCallback(callback)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
std::pair<IWifiStaIface::StaIfaceCapabilityMask, ndk::ScopedAStatus>
|
||||
WifiStaIface::getCapabilitiesInternal() {
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
uint64_t legacy_feature_set;
|
||||
std::tie(legacy_status, legacy_feature_set) =
|
||||
legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
return {IWifiStaIface::StaIfaceCapabilityMask{},
|
||||
createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
uint32_t legacy_logger_feature_set;
|
||||
std::tie(legacy_status, legacy_logger_feature_set) =
|
||||
legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
// some devices don't support querying logger feature set
|
||||
legacy_logger_feature_set = 0;
|
||||
}
|
||||
uint32_t aidl_caps;
|
||||
if (!aidl_struct_util::convertLegacyFeaturesToAidlStaCapabilities(
|
||||
legacy_feature_set, legacy_logger_feature_set, &aidl_caps)) {
|
||||
return {IWifiStaIface::StaIfaceCapabilityMask{},
|
||||
createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {static_cast<IWifiStaIface::StaIfaceCapabilityMask>(aidl_caps),
|
||||
ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
std::pair<StaApfPacketFilterCapabilities, ndk::ScopedAStatus>
|
||||
WifiStaIface::getApfPacketFilterCapabilitiesInternal() {
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
legacy_hal::PacketFilterCapabilities legacy_caps;
|
||||
std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getPacketFilterCapabilities(ifname_);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
return {StaApfPacketFilterCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
StaApfPacketFilterCapabilities aidl_caps;
|
||||
if (!aidl_struct_util::convertLegacyApfCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
|
||||
return {StaApfPacketFilterCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {aidl_caps, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::installApfPacketFilterInternal(
|
||||
const std::vector<uint8_t>& program) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setPacketFilter(ifname_, program);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
|
||||
WifiStaIface::readApfPacketFilterDataInternal() {
|
||||
const std::pair<legacy_hal::wifi_error, std::vector<uint8_t>> legacy_status_and_data =
|
||||
legacy_hal_.lock()->readApfPacketFilterData(ifname_);
|
||||
return {std::move(legacy_status_and_data.second),
|
||||
createWifiStatusFromLegacyError(legacy_status_and_data.first)};
|
||||
}
|
||||
|
||||
std::pair<StaBackgroundScanCapabilities, ndk::ScopedAStatus>
|
||||
WifiStaIface::getBackgroundScanCapabilitiesInternal() {
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
legacy_hal::wifi_gscan_capabilities legacy_caps;
|
||||
std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getGscanCapabilities(ifname_);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
return {StaBackgroundScanCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
StaBackgroundScanCapabilities aidl_caps;
|
||||
if (!aidl_struct_util::convertLegacyGscanCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
|
||||
return {StaBackgroundScanCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {aidl_caps, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
|
||||
WifiStaIface::getValidFrequenciesForBandInternal(WifiBand band) {
|
||||
static_assert(sizeof(WifiChannelWidthInMhz) == sizeof(int32_t), "Size mismatch");
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
std::vector<uint32_t> valid_frequencies;
|
||||
std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand(
|
||||
ifname_, aidl_struct_util::convertAidlWifiBandToLegacy(band));
|
||||
return {std::vector<int32_t>(valid_frequencies.begin(), valid_frequencies.end()),
|
||||
createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::startBackgroundScanInternal(
|
||||
int32_t cmd_id, const StaBackgroundScanParameters& params) {
|
||||
legacy_hal::wifi_scan_cmd_params legacy_params;
|
||||
if (!aidl_struct_util::convertAidlGscanParamsToLegacy(params, &legacy_params)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
std::weak_ptr<WifiStaIface> weak_ptr_this = weak_ptr_this_;
|
||||
const auto& on_failure_callback = [weak_ptr_this](legacy_hal::wifi_request_id id) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->onBackgroundScanFailure(id).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke onBackgroundScanFailure callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
const auto& on_results_callback =
|
||||
[weak_ptr_this](legacy_hal::wifi_request_id id,
|
||||
const std::vector<legacy_hal::wifi_cached_scan_results>& results) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
std::vector<StaScanData> aidl_scan_datas;
|
||||
if (!aidl_struct_util::convertLegacyVectorOfCachedGscanResultsToAidl(
|
||||
results, &aidl_scan_datas)) {
|
||||
LOG(ERROR) << "Failed to convert scan results to AIDL structs";
|
||||
return;
|
||||
}
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->onBackgroundScanResults(id, aidl_scan_datas).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke onBackgroundScanResults callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
const auto& on_full_result_callback = [weak_ptr_this](
|
||||
legacy_hal::wifi_request_id id,
|
||||
const legacy_hal::wifi_scan_result* result,
|
||||
uint32_t buckets_scanned) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
StaScanResult aidl_scan_result;
|
||||
if (!aidl_struct_util::convertLegacyGscanResultToAidl(*result, true, &aidl_scan_result)) {
|
||||
LOG(ERROR) << "Failed to convert full scan results to AIDL structs";
|
||||
return;
|
||||
}
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->onBackgroundFullScanResult(id, buckets_scanned, aidl_scan_result)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke onBackgroundFullScanResult callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->startGscan(ifname_, cmd_id, legacy_params, on_failure_callback,
|
||||
on_results_callback, on_full_result_callback);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::stopBackgroundScanInternal(int32_t cmd_id) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopGscan(ifname_, cmd_id);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableLinkLayerStats(ifname_);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
std::pair<StaLinkLayerStats, ndk::ScopedAStatus> WifiStaIface::getLinkLayerStatsInternal() {
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
legacy_hal::LinkLayerStats legacy_stats;
|
||||
std::tie(legacy_status, legacy_stats) = legacy_hal_.lock()->getLinkLayerStats(ifname_);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
return {StaLinkLayerStats{}, createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
StaLinkLayerStats aidl_stats;
|
||||
if (!aidl_struct_util::convertLegacyLinkLayerStatsToAidl(legacy_stats, &aidl_stats)) {
|
||||
return {StaLinkLayerStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {aidl_stats, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::startRssiMonitoringInternal(int32_t cmd_id, int32_t max_rssi,
|
||||
int32_t min_rssi) {
|
||||
std::weak_ptr<WifiStaIface> weak_ptr_this = weak_ptr_this_;
|
||||
const auto& on_threshold_breached_callback =
|
||||
[weak_ptr_this](legacy_hal::wifi_request_id id, std::array<uint8_t, ETH_ALEN> bssid,
|
||||
int8_t rssi) {
|
||||
const auto shared_ptr_this = weak_ptr_this.lock();
|
||||
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
|
||||
LOG(ERROR) << "Callback invoked on an invalid object";
|
||||
return;
|
||||
}
|
||||
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
|
||||
if (!callback->onRssiThresholdBreached(id, bssid, rssi).isOk()) {
|
||||
LOG(ERROR) << "Failed to invoke onRssiThresholdBreached callback";
|
||||
}
|
||||
}
|
||||
};
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRssiMonitoring(
|
||||
ifname_, cmd_id, max_rssi, min_rssi, on_threshold_breached_callback);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::stopRssiMonitoringInternal(int32_t cmd_id) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
std::pair<StaRoamingCapabilities, ndk::ScopedAStatus>
|
||||
WifiStaIface::getRoamingCapabilitiesInternal() {
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
legacy_hal::wifi_roaming_capabilities legacy_caps;
|
||||
std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRoamingCapabilities(ifname_);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
return {StaRoamingCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
StaRoamingCapabilities aidl_caps;
|
||||
if (!aidl_struct_util::convertLegacyRoamingCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
|
||||
return {StaRoamingCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {aidl_caps, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::configureRoamingInternal(const StaRoamingConfig& config) {
|
||||
legacy_hal::wifi_roaming_config legacy_config;
|
||||
if (!aidl_struct_util::convertAidlRoamingConfigToLegacy(config, &legacy_config)) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
|
||||
}
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->configureRoaming(ifname_, legacy_config);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableFirmwareRoaming(
|
||||
ifname_, aidl_struct_util::convertAidlRoamingStateToLegacy(state));
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::enableNdOffloadInternal(bool enable) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->configureNdOffload(ifname_, enable);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::startSendingKeepAlivePacketsInternal(
|
||||
int32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, char16_t ether_type,
|
||||
const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address,
|
||||
int32_t period_in_ms) {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startSendingOffloadedPacket(
|
||||
ifname_, cmd_id, ether_type, ip_packet_data, src_address, dst_address, period_in_ms);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(int32_t cmd_id) {
|
||||
legacy_hal::wifi_error legacy_status =
|
||||
legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
|
||||
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startPktFateMonitoring(ifname_);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
std::pair<std::vector<WifiDebugTxPacketFateReport>, ndk::ScopedAStatus>
|
||||
WifiStaIface::getDebugTxPacketFatesInternal() {
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
std::vector<legacy_hal::wifi_tx_report> legacy_fates;
|
||||
std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getTxPktFates(ifname_);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
return {std::vector<WifiDebugTxPacketFateReport>(),
|
||||
createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
std::vector<WifiDebugTxPacketFateReport> aidl_fates;
|
||||
if (!aidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToAidl(legacy_fates,
|
||||
&aidl_fates)) {
|
||||
return {std::vector<WifiDebugTxPacketFateReport>(),
|
||||
createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {aidl_fates, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
std::pair<std::vector<WifiDebugRxPacketFateReport>, ndk::ScopedAStatus>
|
||||
WifiStaIface::getDebugRxPacketFatesInternal() {
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
std::vector<legacy_hal::wifi_rx_report> legacy_fates;
|
||||
std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getRxPktFates(ifname_);
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
return {std::vector<WifiDebugRxPacketFateReport>(),
|
||||
createWifiStatusFromLegacyError(legacy_status)};
|
||||
}
|
||||
std::vector<WifiDebugRxPacketFateReport> aidl_fates;
|
||||
if (!aidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToAidl(legacy_fates,
|
||||
&aidl_fates)) {
|
||||
return {std::vector<WifiDebugRxPacketFateReport>(),
|
||||
createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {aidl_fates, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
|
||||
bool status = iface_util_.lock()->setMacAddress(ifname_, mac);
|
||||
if (!status) {
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> WifiStaIface::getFactoryMacAddressInternal() {
|
||||
std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifname_);
|
||||
if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
|
||||
return {mac, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
|
||||
}
|
||||
return {mac, ndk::ScopedAStatus::ok()};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus WifiStaIface::setScanModeInternal(bool enable) {
|
||||
// OEM's need to implement this on their devices if needed.
|
||||
LOG(WARNING) << "setScanModeInternal(" << enable << ") not supported";
|
||||
return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
154
wifi/aidl/default/wifi_sta_iface.h
Normal file
154
wifi/aidl/default/wifi_sta_iface.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_STA_IFACE_H_
|
||||
#define WIFI_STA_IFACE_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/BnWifiStaIface.h>
|
||||
#include <aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.h>
|
||||
#include <android-base/macros.h>
|
||||
|
||||
#include "aidl_callback_util.h"
|
||||
#include "wifi_iface_util.h"
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
/**
|
||||
* AIDL interface object used to control a STA Iface instance.
|
||||
*/
|
||||
class WifiStaIface : public BnWifiStaIface {
|
||||
public:
|
||||
WifiStaIface(const std::string& ifname,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
|
||||
|
||||
// Factory method - use instead of default constructor.
|
||||
static std::shared_ptr<WifiStaIface> create(
|
||||
const std::string& ifname, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
|
||||
|
||||
// Refer to |WifiChip::invalidate()|.
|
||||
void invalidate();
|
||||
bool isValid();
|
||||
std::set<std::shared_ptr<IWifiStaIfaceEventCallback>> getEventCallbacks();
|
||||
std::string getName();
|
||||
|
||||
// AIDL methods exposed.
|
||||
ndk::ScopedAStatus getName(std::string* _aidl_return) override;
|
||||
ndk::ScopedAStatus registerEventCallback(
|
||||
const std::shared_ptr<IWifiStaIfaceEventCallback>& in_callback) override;
|
||||
ndk::ScopedAStatus getCapabilities(
|
||||
IWifiStaIface::StaIfaceCapabilityMask* _aidl_return) override;
|
||||
ndk::ScopedAStatus getApfPacketFilterCapabilities(
|
||||
StaApfPacketFilterCapabilities* _aidl_return) override;
|
||||
ndk::ScopedAStatus installApfPacketFilter(const std::vector<uint8_t>& in_program) override;
|
||||
ndk::ScopedAStatus readApfPacketFilterData(std::vector<uint8_t>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getBackgroundScanCapabilities(
|
||||
StaBackgroundScanCapabilities* _aidl_return) override;
|
||||
ndk::ScopedAStatus getValidFrequenciesForBand(WifiBand in_band,
|
||||
std::vector<int32_t>* _aidl_return) override;
|
||||
ndk::ScopedAStatus startBackgroundScan(int32_t in_cmdId,
|
||||
const StaBackgroundScanParameters& in_params) override;
|
||||
ndk::ScopedAStatus stopBackgroundScan(int32_t in_cmdId) override;
|
||||
ndk::ScopedAStatus enableLinkLayerStatsCollection(bool in_debug) override;
|
||||
ndk::ScopedAStatus disableLinkLayerStatsCollection() override;
|
||||
ndk::ScopedAStatus getLinkLayerStats(StaLinkLayerStats* _aidl_return) override;
|
||||
ndk::ScopedAStatus startRssiMonitoring(int32_t in_cmdId, int32_t in_maxRssi,
|
||||
int32_t in_minRssi) override;
|
||||
ndk::ScopedAStatus stopRssiMonitoring(int32_t in_cmdId) override;
|
||||
ndk::ScopedAStatus getRoamingCapabilities(StaRoamingCapabilities* _aidl_return) override;
|
||||
ndk::ScopedAStatus configureRoaming(const StaRoamingConfig& in_config) override;
|
||||
ndk::ScopedAStatus setRoamingState(StaRoamingState in_state) override;
|
||||
ndk::ScopedAStatus enableNdOffload(bool in_enable) override;
|
||||
ndk::ScopedAStatus startSendingKeepAlivePackets(int32_t in_cmdId,
|
||||
const std::vector<uint8_t>& in_ipPacketData,
|
||||
char16_t in_etherType,
|
||||
const std::array<uint8_t, 6>& in_srcAddress,
|
||||
const std::array<uint8_t, 6>& in_dstAddress,
|
||||
int32_t in_periodInMs) override;
|
||||
ndk::ScopedAStatus stopSendingKeepAlivePackets(int32_t in_cmdId) override;
|
||||
ndk::ScopedAStatus startDebugPacketFateMonitoring() override;
|
||||
ndk::ScopedAStatus getDebugTxPacketFates(
|
||||
std::vector<WifiDebugTxPacketFateReport>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getDebugRxPacketFates(
|
||||
std::vector<WifiDebugRxPacketFateReport>* _aidl_return) override;
|
||||
ndk::ScopedAStatus setMacAddress(const std::array<uint8_t, 6>& in_mac) override;
|
||||
ndk::ScopedAStatus getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) override;
|
||||
ndk::ScopedAStatus setScanMode(bool in_enable) override;
|
||||
|
||||
private:
|
||||
// Corresponding worker functions for the AIDL methods.
|
||||
std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
|
||||
ndk::ScopedAStatus registerEventCallbackInternal(
|
||||
const std::shared_ptr<IWifiStaIfaceEventCallback>& callback);
|
||||
std::pair<IWifiStaIface::StaIfaceCapabilityMask, ndk::ScopedAStatus> getCapabilitiesInternal();
|
||||
std::pair<StaApfPacketFilterCapabilities, ndk::ScopedAStatus>
|
||||
getApfPacketFilterCapabilitiesInternal();
|
||||
ndk::ScopedAStatus installApfPacketFilterInternal(const std::vector<uint8_t>& program);
|
||||
std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> readApfPacketFilterDataInternal();
|
||||
std::pair<StaBackgroundScanCapabilities, ndk::ScopedAStatus>
|
||||
getBackgroundScanCapabilitiesInternal();
|
||||
std::pair<std::vector<int32_t>, ndk::ScopedAStatus> getValidFrequenciesForBandInternal(
|
||||
WifiBand band);
|
||||
ndk::ScopedAStatus startBackgroundScanInternal(int32_t cmd_id,
|
||||
const StaBackgroundScanParameters& params);
|
||||
ndk::ScopedAStatus stopBackgroundScanInternal(int32_t cmd_id);
|
||||
ndk::ScopedAStatus enableLinkLayerStatsCollectionInternal(bool debug);
|
||||
ndk::ScopedAStatus disableLinkLayerStatsCollectionInternal();
|
||||
std::pair<StaLinkLayerStats, ndk::ScopedAStatus> getLinkLayerStatsInternal();
|
||||
ndk::ScopedAStatus startRssiMonitoringInternal(int32_t cmd_id, int32_t max_rssi,
|
||||
int32_t min_rssi);
|
||||
ndk::ScopedAStatus stopRssiMonitoringInternal(int32_t cmd_id);
|
||||
std::pair<StaRoamingCapabilities, ndk::ScopedAStatus> getRoamingCapabilitiesInternal();
|
||||
ndk::ScopedAStatus configureRoamingInternal(const StaRoamingConfig& config);
|
||||
ndk::ScopedAStatus setRoamingStateInternal(StaRoamingState state);
|
||||
ndk::ScopedAStatus enableNdOffloadInternal(bool enable);
|
||||
ndk::ScopedAStatus startSendingKeepAlivePacketsInternal(
|
||||
int32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, char16_t ether_type,
|
||||
const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address,
|
||||
int32_t period_in_ms);
|
||||
ndk::ScopedAStatus stopSendingKeepAlivePacketsInternal(int32_t cmd_id);
|
||||
ndk::ScopedAStatus startDebugPacketFateMonitoringInternal();
|
||||
std::pair<std::vector<WifiDebugTxPacketFateReport>, ndk::ScopedAStatus>
|
||||
getDebugTxPacketFatesInternal();
|
||||
std::pair<std::vector<WifiDebugRxPacketFateReport>, ndk::ScopedAStatus>
|
||||
getDebugRxPacketFatesInternal();
|
||||
ndk::ScopedAStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
|
||||
std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getFactoryMacAddressInternal();
|
||||
ndk::ScopedAStatus setScanModeInternal(bool enable);
|
||||
|
||||
void setWeakPtr(std::weak_ptr<WifiStaIface> ptr);
|
||||
|
||||
std::string ifname_;
|
||||
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
|
||||
std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
|
||||
std::weak_ptr<WifiStaIface> weak_ptr_this_;
|
||||
bool is_valid_;
|
||||
aidl_callback_util::AidlCallbackHandler<IWifiStaIfaceEventCallback> event_cb_handler_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WifiStaIface);
|
||||
};
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_STA_IFACE_H_
|
||||
106
wifi/aidl/default/wifi_status_util.cpp
Normal file
106
wifi/aidl/default/wifi_status_util.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi_status_util.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
|
||||
std::string legacyErrorToString(legacy_hal::wifi_error error) {
|
||||
switch (error) {
|
||||
case legacy_hal::WIFI_SUCCESS:
|
||||
return "SUCCESS";
|
||||
case legacy_hal::WIFI_ERROR_UNINITIALIZED:
|
||||
return "UNINITIALIZED";
|
||||
case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
|
||||
return "NOT_AVAILABLE";
|
||||
case legacy_hal::WIFI_ERROR_NOT_SUPPORTED:
|
||||
return "NOT_SUPPORTED";
|
||||
case legacy_hal::WIFI_ERROR_INVALID_ARGS:
|
||||
return "INVALID_ARGS";
|
||||
case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID:
|
||||
return "INVALID_REQUEST_ID";
|
||||
case legacy_hal::WIFI_ERROR_TIMED_OUT:
|
||||
return "TIMED_OUT";
|
||||
case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
|
||||
return "TOO_MANY_REQUESTS";
|
||||
case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
|
||||
return "OUT_OF_MEMORY";
|
||||
case legacy_hal::WIFI_ERROR_BUSY:
|
||||
return "BUSY";
|
||||
case legacy_hal::WIFI_ERROR_UNKNOWN:
|
||||
return "UNKNOWN";
|
||||
default:
|
||||
return "UNKNOWN ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus createWifiStatus(WifiStatusCode code, const std::string& description) {
|
||||
return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(static_cast<int32_t>(code),
|
||||
description.c_str());
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus createWifiStatus(WifiStatusCode code) {
|
||||
return ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(code));
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
|
||||
const std::string& desc) {
|
||||
switch (error) {
|
||||
case legacy_hal::WIFI_ERROR_NONE:
|
||||
return ndk::ScopedAStatus::ok();
|
||||
|
||||
case legacy_hal::WIFI_ERROR_UNINITIALIZED:
|
||||
case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
|
||||
return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, desc);
|
||||
|
||||
case legacy_hal::WIFI_ERROR_NOT_SUPPORTED:
|
||||
return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED, desc);
|
||||
|
||||
case legacy_hal::WIFI_ERROR_INVALID_ARGS:
|
||||
case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID:
|
||||
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS, desc);
|
||||
|
||||
case legacy_hal::WIFI_ERROR_TIMED_OUT:
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", timed out");
|
||||
|
||||
case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", too many requests");
|
||||
|
||||
case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", out of memory");
|
||||
|
||||
case legacy_hal::WIFI_ERROR_BUSY:
|
||||
return createWifiStatus(WifiStatusCode::ERROR_BUSY);
|
||||
|
||||
case legacy_hal::WIFI_ERROR_UNKNOWN:
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown");
|
||||
|
||||
default:
|
||||
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) {
|
||||
return createWifiStatusFromLegacyError(error, "");
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
42
wifi/aidl/default/wifi_status_util.h
Normal file
42
wifi/aidl/default/wifi_status_util.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef WIFI_STATUS_UTIL_H_
|
||||
#define WIFI_STATUS_UTIL_H_
|
||||
|
||||
#include <aidl/android/hardware/wifi/IWifi.h>
|
||||
|
||||
#include "wifi_legacy_hal.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace wifi {
|
||||
using ::aidl::android::hardware::wifi::WifiStatusCode;
|
||||
|
||||
std::string legacyErrorToString(legacy_hal::wifi_error error);
|
||||
ndk::ScopedAStatus createWifiStatus(WifiStatusCode code, const std::string& description);
|
||||
ndk::ScopedAStatus createWifiStatus(WifiStatusCode code);
|
||||
ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
|
||||
const std::string& description);
|
||||
ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error);
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // WIFI_STATUS_UTIL_H_
|
||||
169
wifi/aidl/vts/functional/Android.bp
Normal file
169
wifi/aidl/vts/functional/Android.bp
Normal file
@@ -0,0 +1,169 @@
|
||||
//
|
||||
// Copyright (C) 2022 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.
|
||||
//
|
||||
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalWifiChipTargetTest",
|
||||
defaults: [
|
||||
"VtsHalTargetTestDefaults",
|
||||
"use_libaidlvintf_gtest_helper_static",
|
||||
],
|
||||
srcs: [
|
||||
"wifi_chip_aidl_test.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libbinder_ndk",
|
||||
"libvndksupport",
|
||||
],
|
||||
static_libs: [
|
||||
"VtsHalWifiTargetTestUtil",
|
||||
"android.hardware.wifi-V1-ndk",
|
||||
"libwifi-system-iface",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalWifiStaIfaceTargetTest",
|
||||
defaults: [
|
||||
"VtsHalTargetTestDefaults",
|
||||
"use_libaidlvintf_gtest_helper_static",
|
||||
],
|
||||
srcs: [
|
||||
"wifi_sta_iface_aidl_test.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libbinder_ndk",
|
||||
"libvndksupport",
|
||||
],
|
||||
static_libs: [
|
||||
"VtsHalWifiTargetTestUtil",
|
||||
"android.hardware.wifi-V1-ndk",
|
||||
"libwifi-system-iface",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalWifiApIfaceTargetTest",
|
||||
defaults: [
|
||||
"VtsHalTargetTestDefaults",
|
||||
"use_libaidlvintf_gtest_helper_static",
|
||||
],
|
||||
srcs: [
|
||||
"wifi_ap_iface_aidl_test.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libbinder_ndk",
|
||||
"libvndksupport",
|
||||
],
|
||||
static_libs: [
|
||||
"VtsHalWifiTargetTestUtil",
|
||||
"android.hardware.wifi-V1-ndk",
|
||||
"libwifi-system-iface",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalWifiNanIfaceTargetTest",
|
||||
defaults: [
|
||||
"VtsHalTargetTestDefaults",
|
||||
"use_libaidlvintf_gtest_helper_static",
|
||||
],
|
||||
srcs: [
|
||||
"wifi_nan_iface_aidl_test.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libbinder_ndk",
|
||||
"libvndksupport",
|
||||
],
|
||||
static_libs: [
|
||||
"VtsHalWifiTargetTestUtil",
|
||||
"android.hardware.wifi-V1-ndk",
|
||||
"libwifi-system-iface",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalWifiRttControllerTargetTest",
|
||||
defaults: [
|
||||
"VtsHalTargetTestDefaults",
|
||||
"use_libaidlvintf_gtest_helper_static",
|
||||
],
|
||||
srcs: [
|
||||
"wifi_rtt_controller_aidl_test.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libbinder_ndk",
|
||||
"libvndksupport",
|
||||
],
|
||||
static_libs: [
|
||||
"VtsHalWifiTargetTestUtil",
|
||||
"android.hardware.wifi-V1-ndk",
|
||||
"libwifi-system-iface",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_static {
|
||||
name: "VtsHalWifiTargetTestUtil",
|
||||
defaults: ["VtsHalTargetTestDefaults"],
|
||||
srcs: [
|
||||
"wifi_aidl_test_utils.cpp",
|
||||
],
|
||||
export_include_dirs: [
|
||||
".",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libbinder_ndk",
|
||||
"libnativehelper",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.wifi-V1-ndk",
|
||||
"libwifi-system-iface",
|
||||
],
|
||||
}
|
||||
216
wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
Normal file
216
wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "wifi_aidl_test_utils.h"
|
||||
|
||||
using ::android::wifi_system::InterfaceTool;
|
||||
|
||||
namespace {
|
||||
bool findAnyModeSupportingConcurrencyType(IfaceConcurrencyType desired_type,
|
||||
const std::vector<IWifiChip::ChipMode>& modes,
|
||||
int* mode_id) {
|
||||
for (const auto& mode : modes) {
|
||||
for (const auto& combination : mode.availableCombinations) {
|
||||
for (const auto& iface_limit : combination.limits) {
|
||||
const auto& iface_types = iface_limit.types;
|
||||
if (std::find(iface_types.begin(), iface_types.end(), desired_type) !=
|
||||
iface_types.end()) {
|
||||
*mode_id = mode.id;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool configureChipToSupportConcurrencyTypeInternal(const std::shared_ptr<IWifiChip>& wifi_chip,
|
||||
IfaceConcurrencyType type,
|
||||
int* configured_mode_id) {
|
||||
if (!configured_mode_id) {
|
||||
return false;
|
||||
}
|
||||
std::vector<IWifiChip::ChipMode> chip_modes;
|
||||
auto status = wifi_chip->getAvailableModes(&chip_modes);
|
||||
if (!status.isOk()) {
|
||||
return false;
|
||||
}
|
||||
if (!findAnyModeSupportingConcurrencyType(type, chip_modes, configured_mode_id)) {
|
||||
return false;
|
||||
}
|
||||
if (!wifi_chip->configureChip(*configured_mode_id).isOk()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool configureChipToSupportConcurrencyTypeInternal(const std::shared_ptr<IWifiChip>& wifi_chip,
|
||||
IfaceConcurrencyType type) {
|
||||
int mode_id;
|
||||
return configureChipToSupportConcurrencyTypeInternal(wifi_chip, type, &mode_id);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool checkStatusCode(ndk::ScopedAStatus* status, WifiStatusCode expected_code) {
|
||||
if (status == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return status->getServiceSpecificError() == static_cast<int32_t>(expected_code);
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifi> getWifi(const char* instance_name) {
|
||||
return IWifi::fromBinder(ndk::SpAIBinder(AServiceManager_waitForService(instance_name)));
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiChip> getWifiChip(const char* instance_name) {
|
||||
std::shared_ptr<IWifi> wifi = getWifi(instance_name);
|
||||
if (!wifi.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const int retry_interval_ms = 2;
|
||||
const int max_retries = 5;
|
||||
int retry_count = 0;
|
||||
auto status = wifi->start();
|
||||
while (retry_count < max_retries && !status.isOk()) {
|
||||
retry_count++;
|
||||
usleep(retry_interval_ms * 1000);
|
||||
status = wifi->start();
|
||||
}
|
||||
if (!status.isOk()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<int> chip_ids = {};
|
||||
status = wifi->getChipIds(&chip_ids);
|
||||
if (!status.isOk() || chip_ids.size() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
std::shared_ptr<IWifiChip> chip;
|
||||
status = wifi->getChip(chip_ids[0], &chip);
|
||||
if (!status.isOk()) {
|
||||
return nullptr;
|
||||
}
|
||||
return chip;
|
||||
}
|
||||
|
||||
void setupStaIface(const std::shared_ptr<IWifiStaIface>& iface) {
|
||||
std::string iface_name;
|
||||
auto status = iface->getName(&iface_name);
|
||||
if (status.isOk()) {
|
||||
InterfaceTool iface_tool;
|
||||
iface_tool.SetUpState(iface_name.c_str(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void setupNanIface(const std::shared_ptr<IWifiNanIface>& iface) {
|
||||
std::string iface_name;
|
||||
auto status = iface->getName(&iface_name);
|
||||
if (status.isOk()) {
|
||||
InterfaceTool iface_tool;
|
||||
iface_tool.SetUpState(iface_name.c_str(), true);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiStaIface> getWifiStaIface(const char* instance_name) {
|
||||
std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
|
||||
if (!wifi_chip.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::STA)) {
|
||||
return nullptr;
|
||||
}
|
||||
std::shared_ptr<IWifiStaIface> iface;
|
||||
auto status = wifi_chip->createStaIface(&iface);
|
||||
if (!status.isOk()) {
|
||||
return nullptr;
|
||||
}
|
||||
setupStaIface(iface);
|
||||
return iface;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiNanIface> getWifiNanIface(const char* instance_name) {
|
||||
std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
|
||||
if (!wifi_chip.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip,
|
||||
IfaceConcurrencyType::NAN_IFACE)) {
|
||||
return nullptr;
|
||||
}
|
||||
std::shared_ptr<IWifiNanIface> iface;
|
||||
auto status = wifi_chip->createNanIface(&iface);
|
||||
if (!status.isOk()) {
|
||||
return nullptr;
|
||||
}
|
||||
setupNanIface(iface);
|
||||
return iface;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name) {
|
||||
std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
|
||||
if (!wifi_chip.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP)) {
|
||||
return nullptr;
|
||||
}
|
||||
std::shared_ptr<IWifiApIface> iface;
|
||||
auto status = wifi_chip->createApIface(&iface);
|
||||
if (!status.isOk()) {
|
||||
return nullptr;
|
||||
}
|
||||
return iface;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip) {
|
||||
if (!wifi_chip.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
int mode_id;
|
||||
std::shared_ptr<IWifiApIface> iface;
|
||||
configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP, &mode_id);
|
||||
auto status = wifi_chip->createBridgedApIface(&iface);
|
||||
if (!status.isOk()) {
|
||||
return nullptr;
|
||||
}
|
||||
return iface;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiApIface> getBridgedWifiApIface(const char* instance_name) {
|
||||
std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
|
||||
return getBridgedWifiApIface(wifi_chip);
|
||||
}
|
||||
|
||||
bool configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
|
||||
IfaceConcurrencyType type, int* configured_mode_id) {
|
||||
return configureChipToSupportConcurrencyTypeInternal(wifi_chip, type, configured_mode_id);
|
||||
}
|
||||
|
||||
void stopWifiService(const char* instance_name) {
|
||||
std::shared_ptr<IWifi> wifi = getWifi(instance_name);
|
||||
if (wifi != nullptr) {
|
||||
wifi->stop();
|
||||
}
|
||||
}
|
||||
|
||||
int32_t getChipCapabilities(const std::shared_ptr<IWifiChip>& wifi_chip) {
|
||||
IWifiChip::ChipCapabilityMask caps = {};
|
||||
if (wifi_chip->getCapabilities(&caps).isOk()) {
|
||||
return static_cast<int32_t>(caps);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
48
wifi/aidl/vts/functional/wifi_aidl_test_utils.h
Normal file
48
wifi/aidl/vts/functional/wifi_aidl_test_utils.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <VtsCoreUtil.h>
|
||||
|
||||
#include <aidl/android/hardware/wifi/IWifi.h>
|
||||
#include <aidl/android/hardware/wifi/IWifiChip.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <wifi_system/interface_tool.h>
|
||||
|
||||
using aidl::android::hardware::wifi::IfaceConcurrencyType;
|
||||
using aidl::android::hardware::wifi::IWifi;
|
||||
using aidl::android::hardware::wifi::IWifiApIface;
|
||||
using aidl::android::hardware::wifi::IWifiChip;
|
||||
using aidl::android::hardware::wifi::IWifiNanIface;
|
||||
using aidl::android::hardware::wifi::IWifiStaIface;
|
||||
using aidl::android::hardware::wifi::WifiStatusCode;
|
||||
|
||||
// Helper functions to obtain references to the various AIDL interface objects.
|
||||
std::shared_ptr<IWifi> getWifi(const char* instance_name);
|
||||
std::shared_ptr<IWifiChip> getWifiChip(const char* instance_name);
|
||||
std::shared_ptr<IWifiStaIface> getWifiStaIface(const char* instance_name);
|
||||
std::shared_ptr<IWifiNanIface> getWifiNanIface(const char* instance_name);
|
||||
std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name);
|
||||
std::shared_ptr<IWifiApIface> getBridgedWifiApIface(const char* instance_name);
|
||||
std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip);
|
||||
// Configure the chip in a mode to support the creation of the provided iface type.
|
||||
bool configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
|
||||
IfaceConcurrencyType type, int* configured_mode_id);
|
||||
// Used to trigger IWifi.stop() at the end of every test.
|
||||
void stopWifiService(const char* instance_name);
|
||||
int32_t getChipCapabilities(const std::shared_ptr<IWifiChip>& wifi_chip);
|
||||
bool checkStatusCode(ndk::ScopedAStatus* status, WifiStatusCode expected_code);
|
||||
154
wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp
Normal file
154
wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Staache 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 <vector>
|
||||
|
||||
#include <VtsCoreUtil.h>
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/wifi/BnWifi.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_status.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
|
||||
#include "wifi_aidl_test_utils.h"
|
||||
|
||||
using aidl::android::hardware::wifi::IWifiApIface;
|
||||
using aidl::android::hardware::wifi::WifiBand;
|
||||
|
||||
class WifiApIfaceAidlTest : public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
isBridgedSupport_ = testing::checkSubstringInCommandOutput(
|
||||
"/system/bin/cmd wifi get-softap-supported-features",
|
||||
"wifi_softap_bridged_ap_supported");
|
||||
stopWifiService(getInstanceName());
|
||||
}
|
||||
|
||||
void TearDown() override { stopWifiService(getInstanceName()); }
|
||||
|
||||
protected:
|
||||
bool isBridgedSupport_ = false;
|
||||
const char* getInstanceName() { return GetParam().c_str(); }
|
||||
};
|
||||
|
||||
/*
|
||||
* SetMacAddress
|
||||
*/
|
||||
TEST_P(WifiApIfaceAidlTest, SetMacAddress) {
|
||||
std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_ap_iface.get());
|
||||
std::array<uint8_t, 6> mac = {0x12, 0x22, 0x33, 0x52, 0x10, 0x44};
|
||||
EXPECT_TRUE(wifi_ap_iface->setMacAddress(mac).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* SetCountryCode
|
||||
*/
|
||||
TEST_P(WifiApIfaceAidlTest, SetCountryCode) {
|
||||
std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_ap_iface.get());
|
||||
|
||||
const std::array<uint8_t, 2> country_code = {0x55, 0x53};
|
||||
EXPECT_TRUE(wifi_ap_iface->setCountryCode(country_code).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetValidFrequenciesForBand
|
||||
* Ensures that we can retrieve valid frequencies for the 2.4 GHz band.
|
||||
*/
|
||||
TEST_P(WifiApIfaceAidlTest, GetValidFrequenciesForBand) {
|
||||
std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_ap_iface.get());
|
||||
|
||||
std::vector<int32_t> freqs;
|
||||
EXPECT_TRUE(wifi_ap_iface->getValidFrequenciesForBand(WifiBand::BAND_24GHZ, &freqs).isOk());
|
||||
EXPECT_NE(freqs.size(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetFactoryMacAddress
|
||||
*/
|
||||
TEST_P(WifiApIfaceAidlTest, GetFactoryMacAddress) {
|
||||
std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_ap_iface.get());
|
||||
|
||||
std::array<uint8_t, 6> mac;
|
||||
EXPECT_TRUE(wifi_ap_iface->getFactoryMacAddress(&mac).isOk());
|
||||
std::array<uint8_t, 6> all_zero_mac = {0, 0, 0, 0, 0, 0};
|
||||
EXPECT_NE(mac, all_zero_mac);
|
||||
}
|
||||
|
||||
/**
|
||||
* GetBridgedInstances - non-bridged mode
|
||||
*/
|
||||
TEST_P(WifiApIfaceAidlTest, GetBridgedInstances) {
|
||||
std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_ap_iface.get());
|
||||
|
||||
std::vector<std::string> instances;
|
||||
EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
|
||||
EXPECT_EQ(instances.size(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* GetBridgedInstances - bridged AP mode.
|
||||
*/
|
||||
TEST_P(WifiApIfaceAidlTest, GetBridgedInstances_Bridged) {
|
||||
if (!isBridgedSupport_) {
|
||||
GTEST_SKIP() << "Missing Bridged AP support";
|
||||
}
|
||||
std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_ap_iface.get());
|
||||
|
||||
std::vector<std::string> instances;
|
||||
EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
|
||||
EXPECT_EQ(instances.size(), 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* ResetToFactoryMacAddress - non-bridged mode
|
||||
*/
|
||||
TEST_P(WifiApIfaceAidlTest, ResetToFactoryMacAddress) {
|
||||
std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_ap_iface.get());
|
||||
EXPECT_TRUE(wifi_ap_iface->resetToFactoryMacAddress().isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* ResetToFactoryMacAddress - bridged AP mode
|
||||
*/
|
||||
TEST_P(WifiApIfaceAidlTest, ResetToFactoryMacAddress_Bridged) {
|
||||
if (!isBridgedSupport_) {
|
||||
GTEST_SKIP() << "Missing Bridged AP support";
|
||||
}
|
||||
std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_ap_iface.get());
|
||||
EXPECT_TRUE(wifi_ap_iface->resetToFactoryMacAddress().isOk());
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiApIfaceAidlTest);
|
||||
INSTANTIATE_TEST_SUITE_P(WifiTest, WifiApIfaceAidlTest,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
|
||||
android::ProcessState::self()->startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
889
wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
Normal file
889
wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
Normal file
@@ -0,0 +1,889 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Staache 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 <numeric>
|
||||
#include <vector>
|
||||
|
||||
#include <VtsCoreUtil.h>
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/wifi/BnWifi.h>
|
||||
#include <aidl/android/hardware/wifi/BnWifiChipEventCallback.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_status.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
|
||||
#include "wifi_aidl_test_utils.h"
|
||||
|
||||
using aidl::android::hardware::wifi::BnWifiChipEventCallback;
|
||||
using aidl::android::hardware::wifi::IfaceType;
|
||||
using aidl::android::hardware::wifi::IWifiApIface;
|
||||
using aidl::android::hardware::wifi::IWifiChip;
|
||||
using aidl::android::hardware::wifi::IWifiNanIface;
|
||||
using aidl::android::hardware::wifi::IWifiP2pIface;
|
||||
using aidl::android::hardware::wifi::IWifiRttController;
|
||||
using aidl::android::hardware::wifi::WifiBand;
|
||||
using aidl::android::hardware::wifi::WifiDebugHostWakeReasonStats;
|
||||
using aidl::android::hardware::wifi::WifiDebugRingBufferStatus;
|
||||
using aidl::android::hardware::wifi::WifiDebugRingBufferVerboseLevel;
|
||||
using aidl::android::hardware::wifi::WifiIfaceMode;
|
||||
using aidl::android::hardware::wifi::WifiRadioCombinationMatrix;
|
||||
using aidl::android::hardware::wifi::WifiStatusCode;
|
||||
using aidl::android::hardware::wifi::WifiUsableChannel;
|
||||
|
||||
class WifiChipAidlTest : public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
stopWifiService(getInstanceName());
|
||||
wifi_chip_ = getWifiChip(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_chip_.get());
|
||||
}
|
||||
|
||||
void TearDown() override { stopWifiService(getInstanceName()); }
|
||||
|
||||
protected:
|
||||
int configureChipForConcurrencyType(IfaceConcurrencyType type) {
|
||||
int mode_id;
|
||||
EXPECT_TRUE(configureChipToSupportConcurrencyType(wifi_chip_, type, &mode_id));
|
||||
return mode_id;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiStaIface> configureChipForStaAndGetIface() {
|
||||
std::shared_ptr<IWifiStaIface> iface;
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
EXPECT_TRUE(wifi_chip_->createStaIface(&iface).isOk());
|
||||
EXPECT_NE(nullptr, iface.get());
|
||||
return iface;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiP2pIface> configureChipForP2pAndGetIface() {
|
||||
std::shared_ptr<IWifiP2pIface> iface;
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::P2P);
|
||||
EXPECT_TRUE(wifi_chip_->createP2pIface(&iface).isOk());
|
||||
EXPECT_NE(nullptr, iface.get());
|
||||
return iface;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiApIface> configureChipForApAndGetIface() {
|
||||
std::shared_ptr<IWifiApIface> iface;
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::AP);
|
||||
EXPECT_TRUE(wifi_chip_->createApIface(&iface).isOk());
|
||||
EXPECT_NE(nullptr, iface.get());
|
||||
return iface;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiNanIface> configureChipForNanAndGetIface() {
|
||||
std::shared_ptr<IWifiNanIface> iface;
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::NAN_IFACE);
|
||||
EXPECT_TRUE(wifi_chip_->createNanIface(&iface).isOk());
|
||||
EXPECT_NE(nullptr, iface.get());
|
||||
return iface;
|
||||
}
|
||||
|
||||
std::string getStaIfaceName(const std::shared_ptr<IWifiStaIface>& iface) {
|
||||
std::string iface_name;
|
||||
EXPECT_TRUE(iface->getName(&iface_name).isOk());
|
||||
return iface_name;
|
||||
}
|
||||
|
||||
std::string getP2pIfaceName(const std::shared_ptr<IWifiP2pIface>& iface) {
|
||||
std::string iface_name;
|
||||
EXPECT_TRUE(iface->getName(&iface_name).isOk());
|
||||
return iface_name;
|
||||
}
|
||||
|
||||
std::string getApIfaceName(const std::shared_ptr<IWifiApIface>& iface) {
|
||||
std::string iface_name;
|
||||
EXPECT_TRUE(iface->getName(&iface_name).isOk());
|
||||
return iface_name;
|
||||
}
|
||||
|
||||
std::string getNanIfaceName(const std::shared_ptr<IWifiNanIface>& iface) {
|
||||
std::string iface_name;
|
||||
EXPECT_TRUE(iface->getName(&iface_name).isOk());
|
||||
return iface_name;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<IWifiStaIface>> create2StaIfacesIfPossible() {
|
||||
std::shared_ptr<IWifiStaIface> iface1 = configureChipForStaAndGetIface();
|
||||
|
||||
// Try create a create second iface.
|
||||
std::shared_ptr<IWifiStaIface> iface2;
|
||||
bool add_second_success = wifi_chip_->createStaIface(&iface2).isOk();
|
||||
if (!add_second_success) {
|
||||
return {iface1};
|
||||
}
|
||||
EXPECT_NE(nullptr, iface2.get());
|
||||
return {iface1, iface2};
|
||||
}
|
||||
|
||||
bool hasAnyRingBufferCapabilities(int32_t caps) {
|
||||
return caps &
|
||||
(static_cast<int32_t>(
|
||||
IWifiChip::ChipCapabilityMask::DEBUG_RING_BUFFER_CONNECT_EVENT) |
|
||||
static_cast<int32_t>(IWifiChip::ChipCapabilityMask::DEBUG_RING_BUFFER_POWER_EVENT) |
|
||||
static_cast<int32_t>(
|
||||
IWifiChip::ChipCapabilityMask::DEBUG_RING_BUFFER_WAKELOCK_EVENT) |
|
||||
static_cast<int32_t>(IWifiChip::ChipCapabilityMask::DEBUG_RING_BUFFER_VENDOR_DATA));
|
||||
}
|
||||
|
||||
const char* getInstanceName() { return GetParam().c_str(); }
|
||||
|
||||
std::shared_ptr<IWifiChip> wifi_chip_;
|
||||
};
|
||||
|
||||
class WifiChipEventCallback : public BnWifiChipEventCallback {
|
||||
public:
|
||||
WifiChipEventCallback() = default;
|
||||
|
||||
::ndk::ScopedAStatus onChipReconfigureFailure(WifiStatusCode /* status */) override {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus onChipReconfigured(int /* modeId */) override {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus onDebugErrorAlert(int /* errorCode */,
|
||||
const std::vector<uint8_t>& /* debugData */) override {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus onDebugRingBufferDataAvailable(
|
||||
const WifiDebugRingBufferStatus& /* status */,
|
||||
const std::vector<uint8_t>& /* data */) override {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus onIfaceAdded(IfaceType /* type */,
|
||||
const std::string& /* name */) override {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus onIfaceRemoved(IfaceType /* type */,
|
||||
const std::string& /* name */) override {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus onRadioModeChange(
|
||||
const std::vector<RadioModeInfo>& /* radioModeInfos */) override {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* RegisterEventCallback
|
||||
*
|
||||
* Note: it is not feasible to test the invocation of the callback function,
|
||||
* since events are triggered internally in the HAL implementation and cannot be
|
||||
* triggered from the test case.
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, RegisterEventCallback) {
|
||||
std::shared_ptr<WifiChipEventCallback> callback =
|
||||
ndk::SharedRefBase::make<WifiChipEventCallback>();
|
||||
ASSERT_NE(nullptr, callback.get());
|
||||
EXPECT_TRUE(wifi_chip_->registerEventCallback(callback).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetCapabilities
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetCapabilities) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
EXPECT_NE(static_cast<int32_t>(caps), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetId
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetId) {
|
||||
int id;
|
||||
EXPECT_TRUE(wifi_chip_->getId(&id).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetAvailableModes
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetAvailableModes) {
|
||||
std::vector<IWifiChip::ChipMode> modes;
|
||||
EXPECT_TRUE(wifi_chip_->getAvailableModes(&modes).isOk());
|
||||
EXPECT_NE(modes.size(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetMode
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetMode) {
|
||||
int expected_mode = configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int retrieved_mode;
|
||||
EXPECT_TRUE(wifi_chip_->getMode(&retrieved_mode).isOk());
|
||||
EXPECT_EQ(retrieved_mode, expected_mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetUsableChannels
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetUsableChannels) {
|
||||
WifiBand band = WifiBand::BAND_24GHZ_5GHZ_6GHZ;
|
||||
uint32_t ifaceModeMask = static_cast<uint32_t>(WifiIfaceMode::IFACE_MODE_P2P_CLIENT) |
|
||||
static_cast<uint32_t>(WifiIfaceMode::IFACE_MODE_P2P_GO);
|
||||
uint32_t filterMask =
|
||||
static_cast<uint32_t>(IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) |
|
||||
static_cast<uint32_t>(IWifiChip::UsableChannelFilter::CONCURRENCY);
|
||||
|
||||
std::vector<WifiUsableChannel> channels;
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
auto status = wifi_chip_->getUsableChannels(
|
||||
band, static_cast<WifiIfaceMode>(ifaceModeMask),
|
||||
static_cast<IWifiChip::UsableChannelFilter>(filterMask), &channels);
|
||||
if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
GTEST_SKIP() << "getUsableChannels() is not supported by vendor.";
|
||||
}
|
||||
EXPECT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetSupportedRadioCombinationsMatrix
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetSupportedRadioCombinationsMatrix) {
|
||||
WifiRadioCombinationMatrix combination_matrix = {};
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
auto status = wifi_chip_->getSupportedRadioCombinationsMatrix(&combination_matrix);
|
||||
if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
GTEST_SKIP() << "Skipping this test since getSupportedRadioCombinationsMatrix() "
|
||||
"is not supported by vendor.";
|
||||
}
|
||||
EXPECT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* SetCountryCode
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, SetCountryCode) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
std::array<uint8_t, 2> country_code = {0x55, 0x53};
|
||||
EXPECT_TRUE(wifi_chip_->setCountryCode(country_code).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* SetLatencyMode_normal
|
||||
* Tests the setLatencyMode() API with Latency mode NORMAL.
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, SetLatencyMode_normal) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
auto status = wifi_chip_->setLatencyMode(IWifiChip::LatencyMode::NORMAL);
|
||||
if (caps & static_cast<int32_t>(IWifiChip::ChipCapabilityMask::SET_LATENCY_MODE)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SetLatencyMode_low
|
||||
* Tests the setLatencyMode() API with Latency mode LOW.
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, SetLatencyMode_low) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
auto status = wifi_chip_->setLatencyMode(IWifiChip::LatencyMode::LOW);
|
||||
if (caps & static_cast<int32_t>(IWifiChip::ChipCapabilityMask::SET_LATENCY_MODE)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SetMultiStaPrimaryConnection
|
||||
*
|
||||
* Only runs if the device supports 2 STA ifaces.
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, SetMultiStaPrimaryConnection) {
|
||||
auto ifaces = create2StaIfacesIfPossible();
|
||||
if (ifaces.size() < 2) {
|
||||
GTEST_SKIP() << "Device does not support more than 1 STA concurrently";
|
||||
}
|
||||
|
||||
auto status = wifi_chip_->setMultiStaPrimaryConnection(getStaIfaceName(ifaces[0]));
|
||||
if (!status.isOk()) {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SetMultiStaUseCase
|
||||
*
|
||||
* Only runs if the device supports 2 STA ifaces.
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, setMultiStaUseCase) {
|
||||
auto ifaces = create2StaIfacesIfPossible();
|
||||
if (ifaces.size() < 2) {
|
||||
GTEST_SKIP() << "Device does not support more than 1 STA concurrently";
|
||||
}
|
||||
|
||||
auto status = wifi_chip_->setMultiStaUseCase(
|
||||
IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY);
|
||||
if (!status.isOk()) {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SetCoexUnsafeChannels
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, SetCoexUnsafeChannels) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
|
||||
// Test with an empty vector of CoexUnsafeChannels.
|
||||
std::vector<IWifiChip::CoexUnsafeChannel> vec;
|
||||
IWifiChip::CoexRestriction restrictions = static_cast<IWifiChip::CoexRestriction>(0);
|
||||
auto status = wifi_chip_->setCoexUnsafeChannels(vec, restrictions);
|
||||
if (!status.isOk()) {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
|
||||
// Test with a non-empty vector of CoexUnsafeChannels.
|
||||
IWifiChip::CoexUnsafeChannel unsafeChannel24Ghz;
|
||||
unsafeChannel24Ghz.band = WifiBand::BAND_24GHZ;
|
||||
unsafeChannel24Ghz.channel = 6;
|
||||
vec.push_back(unsafeChannel24Ghz);
|
||||
IWifiChip::CoexUnsafeChannel unsafeChannel5Ghz;
|
||||
unsafeChannel5Ghz.band = WifiBand::BAND_5GHZ;
|
||||
unsafeChannel5Ghz.channel = 36;
|
||||
vec.push_back(unsafeChannel5Ghz);
|
||||
restrictions = static_cast<IWifiChip::CoexRestriction>(
|
||||
static_cast<int32_t>(IWifiChip::CoexRestriction::WIFI_AWARE) |
|
||||
static_cast<int32_t>(IWifiChip::CoexRestriction::SOFTAP) |
|
||||
static_cast<int32_t>(IWifiChip::CoexRestriction::WIFI_DIRECT));
|
||||
|
||||
status = wifi_chip_->setCoexUnsafeChannels(vec, restrictions);
|
||||
if (!status.isOk()) {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SelectTxPowerScenario - Body
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, SelectTxPowerScenario_body) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
int32_t expected_caps =
|
||||
static_cast<int32_t>(IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT) |
|
||||
static_cast<int32_t>(IWifiChip::ChipCapabilityMask::USE_BODY_HEAD_SAR);
|
||||
auto status = wifi_chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF);
|
||||
if (caps & expected_caps) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SelectTxPowerScenario - Voice Call
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, SelectTxPowerScenario_voiceCall) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
auto status = wifi_chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::VOICE_CALL);
|
||||
if (caps & static_cast<int32_t>(IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ResetTxPowerScenario
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, ResetTxPowerScenario) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
auto status = wifi_chip_->resetTxPowerScenario();
|
||||
if (caps & static_cast<int32_t>(IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ConfigureChip
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, ConfigureChip) {
|
||||
std::vector<IWifiChip::ChipMode> modes;
|
||||
EXPECT_TRUE(wifi_chip_->getAvailableModes(&modes).isOk());
|
||||
EXPECT_NE(modes.size(), 0);
|
||||
for (const auto& mode : modes) {
|
||||
// configureChip() requires a fresh IWifiChip object.
|
||||
wifi_chip_ = getWifiChip(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_chip_.get());
|
||||
EXPECT_TRUE(wifi_chip_->configureChip(mode.id).isOk());
|
||||
stopWifiService(getInstanceName());
|
||||
// Sleep for 5 milliseconds between each wifi state toggle.
|
||||
usleep(5000);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* RequestChipDebugInfo
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, RequestChipDebugInfo) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
IWifiChip::ChipDebugInfo debug_info = {};
|
||||
EXPECT_TRUE(wifi_chip_->requestChipDebugInfo(&debug_info).isOk());
|
||||
EXPECT_NE(debug_info.driverDescription.size(), 0);
|
||||
EXPECT_NE(debug_info.firmwareDescription.size(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* RequestFirmwareDebugDump
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, RequestFirmwareDebugDump) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
std::vector<uint8_t> debug_dump;
|
||||
auto status = wifi_chip_->requestFirmwareDebugDump(&debug_dump);
|
||||
if (caps & static_cast<int32_t>(IWifiChip::ChipCapabilityMask::DEBUG_MEMORY_FIRMWARE_DUMP)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* RequestDriverDebugDump
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, RequestDriverDebugDump) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
std::vector<uint8_t> debug_dump;
|
||||
auto status = wifi_chip_->requestDriverDebugDump(&debug_dump);
|
||||
if (caps & static_cast<int32_t>(IWifiChip::ChipCapabilityMask::DEBUG_MEMORY_DRIVER_DUMP)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GetDebugRingBuffersStatus
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetDebugRingBuffersStatus) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
std::vector<WifiDebugRingBufferStatus> ring_buffer_status;
|
||||
auto status = wifi_chip_->getDebugRingBuffersStatus(&ring_buffer_status);
|
||||
if (hasAnyRingBufferCapabilities(caps)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
ASSERT_NE(ring_buffer_status.size(), 0);
|
||||
for (const auto& ring_buffer : ring_buffer_status) {
|
||||
EXPECT_NE(ring_buffer.ringName.size(), 0);
|
||||
}
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GetDebugHostWakeReasonStats
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetDebugHostWakeReasonStats) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
WifiDebugHostWakeReasonStats wake_reason_stats = {};
|
||||
auto status = wifi_chip_->getDebugHostWakeReasonStats(&wake_reason_stats);
|
||||
if (caps & static_cast<int32_t>(IWifiChip::ChipCapabilityMask::DEBUG_HOST_WAKE_REASON_STATS)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* StartLoggingToDebugRingBuffer
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, StartLoggingToDebugRingBuffer) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
std::string ring_name;
|
||||
std::vector<WifiDebugRingBufferStatus> ring_buffer_status;
|
||||
auto status = wifi_chip_->getDebugRingBuffersStatus(&ring_buffer_status);
|
||||
|
||||
if (hasAnyRingBufferCapabilities(caps)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
ASSERT_NE(ring_buffer_status.size(), 0);
|
||||
ring_name = ring_buffer_status[0].ringName;
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
|
||||
status = wifi_chip_->startLoggingToDebugRingBuffer(
|
||||
ring_name, WifiDebugRingBufferVerboseLevel::VERBOSE, 5, 1024);
|
||||
if (hasAnyRingBufferCapabilities(caps)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ForceDumpToDebugRingBuffer
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, ForceDumpToDebugRingBuffer) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
int32_t caps = getChipCapabilities(wifi_chip_);
|
||||
std::string ring_name;
|
||||
std::vector<WifiDebugRingBufferStatus> ring_buffer_status;
|
||||
auto status = wifi_chip_->getDebugRingBuffersStatus(&ring_buffer_status);
|
||||
|
||||
if (hasAnyRingBufferCapabilities(caps)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
ASSERT_NE(ring_buffer_status.size(), 0);
|
||||
ring_name = ring_buffer_status[0].ringName;
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
|
||||
status = wifi_chip_->forceDumpToDebugRingBuffer(ring_name);
|
||||
if (hasAnyRingBufferCapabilities(caps)) {
|
||||
EXPECT_TRUE(status.isOk());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateStaIface
|
||||
* Configures the chip in STA mode and creates an iface.
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, CreateStaIface) {
|
||||
configureChipForStaAndGetIface();
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateApIface
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, CreateApIface) {
|
||||
configureChipForApAndGetIface();
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateNanIface
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, CreateNanIface) {
|
||||
configureChipForNanAndGetIface();
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateP2pIface
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, CreateP2pIface) {
|
||||
configureChipForNanAndGetIface();
|
||||
}
|
||||
|
||||
/*
|
||||
* GetStaIfaceNames
|
||||
* Configures the chip in STA mode and ensures that the iface name list is
|
||||
* empty before creating the iface. Then create the iface and ensure that
|
||||
* iface name is returned in the iface name list.
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetStaIfaceNames) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::STA);
|
||||
|
||||
std::vector<std::string> iface_names;
|
||||
EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 0);
|
||||
|
||||
std::shared_ptr<IWifiStaIface> iface;
|
||||
EXPECT_TRUE(wifi_chip_->createStaIface(&iface).isOk());
|
||||
ASSERT_NE(nullptr, iface.get());
|
||||
|
||||
std::string iface_name = getStaIfaceName(iface);
|
||||
EXPECT_TRUE(wifi_chip_->getStaIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 1);
|
||||
EXPECT_EQ(iface_name, iface_names[0]);
|
||||
|
||||
EXPECT_TRUE(wifi_chip_->removeStaIface(iface_name).isOk());
|
||||
EXPECT_TRUE(wifi_chip_->getStaIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetP2pIfaceNames
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetP2pIfaceNames) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::P2P);
|
||||
|
||||
std::vector<std::string> iface_names;
|
||||
EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 0);
|
||||
|
||||
std::shared_ptr<IWifiP2pIface> iface;
|
||||
EXPECT_TRUE(wifi_chip_->createP2pIface(&iface).isOk());
|
||||
ASSERT_NE(nullptr, iface.get());
|
||||
|
||||
std::string iface_name = getP2pIfaceName(iface);
|
||||
EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 1);
|
||||
EXPECT_EQ(iface_name, iface_names[0]);
|
||||
|
||||
EXPECT_TRUE(wifi_chip_->removeP2pIface(iface_name).isOk());
|
||||
EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetApIfaceNames
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetApIfaceNames) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::AP);
|
||||
|
||||
std::vector<std::string> iface_names;
|
||||
EXPECT_TRUE(wifi_chip_->getApIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 0);
|
||||
|
||||
std::shared_ptr<IWifiApIface> iface;
|
||||
EXPECT_TRUE(wifi_chip_->createApIface(&iface).isOk());
|
||||
ASSERT_NE(nullptr, iface.get());
|
||||
|
||||
std::string iface_name = getApIfaceName(iface);
|
||||
EXPECT_TRUE(wifi_chip_->getApIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 1);
|
||||
EXPECT_EQ(iface_name, iface_names[0]);
|
||||
|
||||
EXPECT_TRUE(wifi_chip_->removeApIface(iface_name).isOk());
|
||||
EXPECT_TRUE(wifi_chip_->getApIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetNanIfaceNames
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetNanIfaceNames) {
|
||||
configureChipForConcurrencyType(IfaceConcurrencyType::NAN_IFACE);
|
||||
|
||||
std::vector<std::string> iface_names;
|
||||
EXPECT_TRUE(wifi_chip_->getNanIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 0);
|
||||
|
||||
std::shared_ptr<IWifiNanIface> iface;
|
||||
EXPECT_TRUE(wifi_chip_->createNanIface(&iface).isOk());
|
||||
ASSERT_NE(nullptr, iface.get());
|
||||
|
||||
std::string iface_name = getNanIfaceName(iface);
|
||||
EXPECT_TRUE(wifi_chip_->getNanIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 1);
|
||||
EXPECT_EQ(iface_name, iface_names[0]);
|
||||
|
||||
EXPECT_TRUE(wifi_chip_->removeNanIface(iface_name).isOk());
|
||||
EXPECT_TRUE(wifi_chip_->getNanIfaceNames(&iface_names).isOk());
|
||||
EXPECT_EQ(iface_names.size(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetStaIface
|
||||
* Configures the chip in STA mode and creates an iface. Then retrieves
|
||||
* the iface object using its name and ensures that any other name
|
||||
* doesn't retrieve a valid iface object.
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetStaIface) {
|
||||
std::shared_ptr<IWifiStaIface> iface = configureChipForStaAndGetIface();
|
||||
std::string iface_name = getStaIfaceName(iface);
|
||||
|
||||
std::shared_ptr<IWifiStaIface> retrieved_iface;
|
||||
EXPECT_TRUE(wifi_chip_->getStaIface(iface_name, &retrieved_iface).isOk());
|
||||
EXPECT_NE(nullptr, retrieved_iface.get());
|
||||
|
||||
std::string invalid_name = iface_name + "0";
|
||||
std::shared_ptr<IWifiStaIface> invalid_iface;
|
||||
auto status = wifi_chip_->getStaIface(invalid_name, &invalid_iface);
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
EXPECT_EQ(nullptr, invalid_iface.get());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetP2pIface
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetP2pIface) {
|
||||
std::shared_ptr<IWifiP2pIface> iface = configureChipForP2pAndGetIface();
|
||||
std::string iface_name = getP2pIfaceName(iface);
|
||||
|
||||
std::shared_ptr<IWifiP2pIface> retrieved_iface;
|
||||
EXPECT_TRUE(wifi_chip_->getP2pIface(iface_name, &retrieved_iface).isOk());
|
||||
EXPECT_NE(nullptr, retrieved_iface.get());
|
||||
|
||||
std::string invalid_name = iface_name + "0";
|
||||
std::shared_ptr<IWifiP2pIface> invalid_iface;
|
||||
auto status = wifi_chip_->getP2pIface(invalid_name, &invalid_iface);
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
EXPECT_EQ(nullptr, invalid_iface.get());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetApIface
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetApIface) {
|
||||
std::shared_ptr<IWifiApIface> iface = configureChipForApAndGetIface();
|
||||
std::string iface_name = getApIfaceName(iface);
|
||||
|
||||
std::shared_ptr<IWifiApIface> retrieved_iface;
|
||||
EXPECT_TRUE(wifi_chip_->getApIface(iface_name, &retrieved_iface).isOk());
|
||||
EXPECT_NE(nullptr, retrieved_iface.get());
|
||||
|
||||
std::string invalid_name = iface_name + "0";
|
||||
std::shared_ptr<IWifiApIface> invalid_iface;
|
||||
auto status = wifi_chip_->getApIface(invalid_name, &invalid_iface);
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
EXPECT_EQ(nullptr, invalid_iface.get());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetNanIface
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, GetNanIface) {
|
||||
std::shared_ptr<IWifiNanIface> iface = configureChipForNanAndGetIface();
|
||||
std::string iface_name = getNanIfaceName(iface);
|
||||
|
||||
std::shared_ptr<IWifiNanIface> retrieved_iface;
|
||||
EXPECT_TRUE(wifi_chip_->getNanIface(iface_name, &retrieved_iface).isOk());
|
||||
EXPECT_NE(nullptr, retrieved_iface.get());
|
||||
|
||||
std::string invalid_name = iface_name + "0";
|
||||
std::shared_ptr<IWifiNanIface> invalid_iface;
|
||||
auto status = wifi_chip_->getNanIface(invalid_name, &invalid_iface);
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
EXPECT_EQ(nullptr, invalid_iface.get());
|
||||
}
|
||||
|
||||
/*
|
||||
* RemoveStaIface
|
||||
* Configures the chip in STA mode and creates an iface. Then removes
|
||||
* the iface object using the correct name and ensures that any other
|
||||
* name doesn't remove the iface.
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, RemoveStaIface) {
|
||||
std::shared_ptr<IWifiStaIface> iface = configureChipForStaAndGetIface();
|
||||
std::string iface_name = getStaIfaceName(iface);
|
||||
|
||||
std::string invalid_name = iface_name + "0";
|
||||
auto status = wifi_chip_->removeStaIface(invalid_name);
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
EXPECT_TRUE(wifi_chip_->removeStaIface(iface_name).isOk());
|
||||
|
||||
// No such iface exists now, so this should return failure.
|
||||
EXPECT_FALSE(wifi_chip_->removeStaIface(iface_name).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* RemoveP2pIface
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, RemoveP2pIface) {
|
||||
std::shared_ptr<IWifiP2pIface> iface = configureChipForP2pAndGetIface();
|
||||
std::string iface_name = getP2pIfaceName(iface);
|
||||
|
||||
std::string invalid_name = iface_name + "0";
|
||||
auto status = wifi_chip_->removeP2pIface(invalid_name);
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
EXPECT_TRUE(wifi_chip_->removeP2pIface(iface_name).isOk());
|
||||
|
||||
// No such iface exists now, so this should return failure.
|
||||
EXPECT_FALSE(wifi_chip_->removeP2pIface(iface_name).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* RemoveApIface
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, RemoveApIface) {
|
||||
std::shared_ptr<IWifiApIface> iface = configureChipForApAndGetIface();
|
||||
std::string iface_name = getApIfaceName(iface);
|
||||
|
||||
std::string invalid_name = iface_name + "0";
|
||||
auto status = wifi_chip_->removeApIface(invalid_name);
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
EXPECT_TRUE(wifi_chip_->removeApIface(iface_name).isOk());
|
||||
|
||||
// No such iface exists now, so this should return failure.
|
||||
EXPECT_FALSE(wifi_chip_->removeApIface(iface_name).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* RemoveNanIface
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, RemoveNanIface) {
|
||||
std::shared_ptr<IWifiNanIface> iface = configureChipForNanAndGetIface();
|
||||
std::string iface_name = getNanIfaceName(iface);
|
||||
|
||||
std::string invalid_name = iface_name + "0";
|
||||
auto status = wifi_chip_->removeNanIface(invalid_name);
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
EXPECT_TRUE(wifi_chip_->removeNanIface(iface_name).isOk());
|
||||
|
||||
// No such iface exists now, so this should return failure.
|
||||
EXPECT_FALSE(wifi_chip_->removeNanIface(iface_name).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateRttController
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, CreateRttController) {
|
||||
std::shared_ptr<IWifiStaIface> iface = configureChipForStaAndGetIface();
|
||||
std::shared_ptr<IWifiRttController> rtt_controller;
|
||||
auto status = wifi_chip_->createRttController(iface, &rtt_controller);
|
||||
if (status.isOk()) {
|
||||
EXPECT_NE(nullptr, rtt_controller.get());
|
||||
} else {
|
||||
EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CreateBridgedApIface & RemoveIfaceInstanceFromBridgedApIface
|
||||
*/
|
||||
TEST_P(WifiChipAidlTest, CreateBridgedApIfaceAndremoveIfaceInstanceFromBridgedApIfaceTest) {
|
||||
bool isBridgedSupport = testing::checkSubstringInCommandOutput(
|
||||
"/system/bin/cmd wifi get-softap-supported-features",
|
||||
"wifi_softap_bridged_ap_supported");
|
||||
if (!isBridgedSupport) {
|
||||
GTEST_SKIP() << "Missing Bridged AP support";
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_chip.get());
|
||||
std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(wifi_chip);
|
||||
ASSERT_NE(nullptr, wifi_ap_iface.get());
|
||||
|
||||
std::string br_name;
|
||||
std::vector<std::string> instances;
|
||||
EXPECT_TRUE(wifi_ap_iface->getName(&br_name).isOk());
|
||||
EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
|
||||
EXPECT_EQ(instances.size(), 2);
|
||||
|
||||
std::vector<std::string> instances_after_remove;
|
||||
EXPECT_TRUE(wifi_chip->removeIfaceInstanceFromBridgedApIface(br_name, instances[0]).isOk());
|
||||
EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances_after_remove).isOk());
|
||||
EXPECT_EQ(instances_after_remove.size(), 1);
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipAidlTest);
|
||||
INSTANTIATE_TEST_SUITE_P(WifiTest, WifiChipAidlTest,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
|
||||
android::ProcessState::self()->startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
627
wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
Normal file
627
wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
Normal file
@@ -0,0 +1,627 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Staache 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 <vector>
|
||||
|
||||
#include <VtsCoreUtil.h>
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/wifi/BnWifi.h>
|
||||
#include <aidl/android/hardware/wifi/BnWifiNanIfaceEventCallback.h>
|
||||
#include <aidl/android/hardware/wifi/NanBandIndex.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_status.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
|
||||
#include "wifi_aidl_test_utils.h"
|
||||
|
||||
using aidl::android::hardware::wifi::BnWifiNanIfaceEventCallback;
|
||||
using aidl::android::hardware::wifi::IWifiNanIface;
|
||||
using aidl::android::hardware::wifi::NanBandIndex;
|
||||
using aidl::android::hardware::wifi::NanBandSpecificConfig;
|
||||
using aidl::android::hardware::wifi::NanCapabilities;
|
||||
using aidl::android::hardware::wifi::NanClusterEventInd;
|
||||
using aidl::android::hardware::wifi::NanConfigRequest;
|
||||
using aidl::android::hardware::wifi::NanConfigRequestSupplemental;
|
||||
using aidl::android::hardware::wifi::NanDataPathConfirmInd;
|
||||
using aidl::android::hardware::wifi::NanDataPathRequestInd;
|
||||
using aidl::android::hardware::wifi::NanDataPathScheduleUpdateInd;
|
||||
using aidl::android::hardware::wifi::NanDataPathSecurityType;
|
||||
using aidl::android::hardware::wifi::NanEnableRequest;
|
||||
using aidl::android::hardware::wifi::NanFollowupReceivedInd;
|
||||
using aidl::android::hardware::wifi::NanInitiateDataPathRequest;
|
||||
using aidl::android::hardware::wifi::NanMatchAlg;
|
||||
using aidl::android::hardware::wifi::NanMatchInd;
|
||||
using aidl::android::hardware::wifi::NanPublishRequest;
|
||||
using aidl::android::hardware::wifi::NanPublishType;
|
||||
using aidl::android::hardware::wifi::NanRespondToDataPathIndicationRequest;
|
||||
using aidl::android::hardware::wifi::NanStatus;
|
||||
using aidl::android::hardware::wifi::NanStatusCode;
|
||||
using aidl::android::hardware::wifi::NanTxType;
|
||||
|
||||
#define TIMEOUT_PERIOD 10
|
||||
|
||||
class WifiNanIfaceAidlTest : public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware"))
|
||||
GTEST_SKIP() << "Skipping this test since NAN is not supported.";
|
||||
stopWifiService(getInstanceName());
|
||||
|
||||
wifi_nan_iface_ = getWifiNanIface(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_nan_iface_.get());
|
||||
std::shared_ptr<WifiNanIfaceEventCallback> callback =
|
||||
ndk::SharedRefBase::make<WifiNanIfaceEventCallback>(*this);
|
||||
EXPECT_TRUE(wifi_nan_iface_->registerEventCallback(callback).isOk());
|
||||
}
|
||||
|
||||
void TearDown() override { stopWifiService(getInstanceName()); }
|
||||
|
||||
// Used as a mechanism to inform the test about data/event callbacks.
|
||||
inline void notify() {
|
||||
std::unique_lock<std::mutex> lock(mtx_);
|
||||
count_++;
|
||||
cv_.notify_one();
|
||||
}
|
||||
|
||||
enum CallbackType {
|
||||
INVALID = -2,
|
||||
ANY_CALLBACK = -1,
|
||||
|
||||
NOTIFY_CAPABILITIES_RESPONSE = 0,
|
||||
NOTIFY_ENABLE_RESPONSE,
|
||||
NOTIFY_CONFIG_RESPONSE,
|
||||
NOTIFY_DISABLE_RESPONSE,
|
||||
NOTIFY_START_PUBLISH_RESPONSE,
|
||||
NOTIFY_STOP_PUBLISH_RESPONSE,
|
||||
NOTIFY_START_SUBSCRIBE_RESPONSE,
|
||||
NOTIFY_STOP_SUBSCRIBE_RESPONSE,
|
||||
NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE,
|
||||
NOTIFY_CREATE_DATA_INTERFACE_RESPONSE,
|
||||
NOTIFY_DELETE_DATA_INTERFACE_RESPONSE,
|
||||
NOTIFY_INITIATE_DATA_PATH_RESPONSE,
|
||||
NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE,
|
||||
NOTIFY_TERMINATE_DATA_PATH_RESPONSE,
|
||||
|
||||
EVENT_CLUSTER_EVENT,
|
||||
EVENT_DISABLED,
|
||||
EVENT_PUBLISH_TERMINATED,
|
||||
EVENT_SUBSCRIBE_TERMINATED,
|
||||
EVENT_MATCH,
|
||||
EVENT_MATCH_EXPIRED,
|
||||
EVENT_FOLLOWUP_RECEIVED,
|
||||
EVENT_TRANSMIT_FOLLOWUP,
|
||||
EVENT_DATA_PATH_REQUEST,
|
||||
EVENT_DATA_PATH_CONFIRM,
|
||||
EVENT_DATA_PATH_TERMINATED,
|
||||
EVENT_DATA_PATH_SCHEDULE_UPDATE,
|
||||
};
|
||||
|
||||
// Test code calls this function to wait for data/event callback.
|
||||
// Must set callbackType = INVALID before calling this function.
|
||||
inline std::cv_status wait(CallbackType waitForCallbackType) {
|
||||
std::unique_lock<std::mutex> lock(mtx_);
|
||||
EXPECT_NE(INVALID, waitForCallbackType);
|
||||
|
||||
std::cv_status status = std::cv_status::no_timeout;
|
||||
auto now = std::chrono::system_clock::now();
|
||||
while (count_ == 0) {
|
||||
status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
|
||||
if (status == std::cv_status::timeout) return status;
|
||||
if (waitForCallbackType != ANY_CALLBACK && callback_type_ != INVALID &&
|
||||
callback_type_ != waitForCallbackType) {
|
||||
count_--;
|
||||
}
|
||||
}
|
||||
count_--;
|
||||
return status;
|
||||
}
|
||||
|
||||
class WifiNanIfaceEventCallback : public BnWifiNanIfaceEventCallback {
|
||||
public:
|
||||
WifiNanIfaceEventCallback(WifiNanIfaceAidlTest& parent) : parent_(parent){};
|
||||
|
||||
::ndk::ScopedAStatus eventClusterEvent(const NanClusterEventInd& event) override {
|
||||
parent_.callback_type_ = EVENT_CLUSTER_EVENT;
|
||||
parent_.nan_cluster_event_ind_ = event;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventDataPathConfirm(const NanDataPathConfirmInd& event) override {
|
||||
parent_.callback_type_ = EVENT_DATA_PATH_CONFIRM;
|
||||
parent_.nan_data_path_confirm_ind_ = event;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventDataPathRequest(const NanDataPathRequestInd& event) override {
|
||||
parent_.callback_type_ = EVENT_DATA_PATH_REQUEST;
|
||||
parent_.nan_data_path_request_ind_ = event;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventDataPathScheduleUpdate(
|
||||
const NanDataPathScheduleUpdateInd& event) override {
|
||||
parent_.callback_type_ = EVENT_DATA_PATH_SCHEDULE_UPDATE;
|
||||
parent_.nan_data_path_schedule_update_ind_ = event;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventDataPathTerminated(int32_t ndpInstanceId) override {
|
||||
parent_.callback_type_ = EVENT_DATA_PATH_TERMINATED;
|
||||
parent_.ndp_instance_id_ = ndpInstanceId;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventDisabled(const NanStatus& status) override {
|
||||
parent_.callback_type_ = EVENT_DISABLED;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventFollowupReceived(const NanFollowupReceivedInd& event) override {
|
||||
parent_.callback_type_ = EVENT_FOLLOWUP_RECEIVED;
|
||||
parent_.nan_followup_received_ind_ = event;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventMatch(const NanMatchInd& event) override {
|
||||
parent_.callback_type_ = EVENT_MATCH;
|
||||
parent_.nan_match_ind_ = event;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventMatchExpired(int8_t discoverySessionId, int32_t peerId) override {
|
||||
parent_.callback_type_ = EVENT_MATCH_EXPIRED;
|
||||
parent_.session_id_ = discoverySessionId;
|
||||
parent_.peer_id_ = peerId;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventPublishTerminated(int8_t sessionId,
|
||||
const NanStatus& status) override {
|
||||
parent_.callback_type_ = EVENT_PUBLISH_TERMINATED;
|
||||
parent_.session_id_ = sessionId;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventSubscribeTerminated(int8_t sessionId,
|
||||
const NanStatus& status) override {
|
||||
parent_.callback_type_ = EVENT_SUBSCRIBE_TERMINATED;
|
||||
parent_.session_id_ = sessionId;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus eventTransmitFollowup(char16_t id, const NanStatus& status) override {
|
||||
parent_.callback_type_ = EVENT_TRANSMIT_FOLLOWUP;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyCapabilitiesResponse(
|
||||
char16_t id, const NanStatus& status,
|
||||
const NanCapabilities& capabilities) override {
|
||||
parent_.callback_type_ = NOTIFY_CAPABILITIES_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.capabilities_ = capabilities;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyConfigResponse(char16_t id, const NanStatus& status) override {
|
||||
parent_.callback_type_ = NOTIFY_CONFIG_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyCreateDataInterfaceResponse(char16_t id,
|
||||
const NanStatus& status) override {
|
||||
parent_.callback_type_ = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyDeleteDataInterfaceResponse(char16_t id,
|
||||
const NanStatus& status) override {
|
||||
parent_.callback_type_ = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyDisableResponse(char16_t id, const NanStatus& status) override {
|
||||
parent_.callback_type_ = NOTIFY_DISABLE_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyEnableResponse(char16_t id, const NanStatus& status) override {
|
||||
parent_.callback_type_ = NOTIFY_ENABLE_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyInitiateDataPathResponse(char16_t id, const NanStatus& status,
|
||||
int32_t ndpInstanceId) override {
|
||||
parent_.callback_type_ = NOTIFY_INITIATE_DATA_PATH_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.ndp_instance_id_ = ndpInstanceId;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyRespondToDataPathIndicationResponse(
|
||||
char16_t id, const NanStatus& status) override {
|
||||
parent_.callback_type_ = NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyStartPublishResponse(char16_t id, const NanStatus& status,
|
||||
int8_t sessionId) override {
|
||||
parent_.callback_type_ = NOTIFY_START_PUBLISH_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.session_id_ = sessionId;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyStartSubscribeResponse(char16_t id, const NanStatus& status,
|
||||
int8_t sessionId) override {
|
||||
parent_.callback_type_ = NOTIFY_START_SUBSCRIBE_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.session_id_ = sessionId;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyStopPublishResponse(char16_t id,
|
||||
const NanStatus& status) override {
|
||||
parent_.callback_type_ = NOTIFY_STOP_PUBLISH_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyStopSubscribeResponse(char16_t id,
|
||||
const NanStatus& status) override {
|
||||
parent_.callback_type_ = NOTIFY_STOP_SUBSCRIBE_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyTerminateDataPathResponse(char16_t id,
|
||||
const NanStatus& status) override {
|
||||
parent_.callback_type_ = NOTIFY_TERMINATE_DATA_PATH_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
::ndk::ScopedAStatus notifyTransmitFollowupResponse(char16_t id,
|
||||
const NanStatus& status) override {
|
||||
parent_.callback_type_ = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE;
|
||||
parent_.id_ = id;
|
||||
parent_.status_ = status;
|
||||
parent_.notify();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
private:
|
||||
WifiNanIfaceAidlTest& parent_;
|
||||
};
|
||||
|
||||
protected:
|
||||
std::shared_ptr<IWifiNanIface> wifi_nan_iface_;
|
||||
CallbackType callback_type_;
|
||||
uint16_t id_;
|
||||
uint8_t session_id_;
|
||||
uint32_t ndp_instance_id_;
|
||||
uint32_t peer_id_;
|
||||
NanCapabilities capabilities_;
|
||||
NanClusterEventInd nan_cluster_event_ind_;
|
||||
NanDataPathConfirmInd nan_data_path_confirm_ind_;
|
||||
NanDataPathRequestInd nan_data_path_request_ind_;
|
||||
NanDataPathScheduleUpdateInd nan_data_path_schedule_update_ind_;
|
||||
NanFollowupReceivedInd nan_followup_received_ind_;
|
||||
NanMatchInd nan_match_ind_;
|
||||
NanStatus status_;
|
||||
|
||||
const char* getInstanceName() { return GetParam().c_str(); }
|
||||
|
||||
private:
|
||||
// synchronization objects
|
||||
std::mutex mtx_;
|
||||
std::condition_variable cv_;
|
||||
int count_ = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* FailOnIfaceInvalid
|
||||
* Ensure that API calls to an interface fail with code ERROR_WIFI_IFACE_INVALID
|
||||
* after wifi is disabled.
|
||||
*/
|
||||
TEST_P(WifiNanIfaceAidlTest, FailOnIfaceInvalid) {
|
||||
stopWifiService(getInstanceName());
|
||||
sleep(5); // Ensure that all chips/interfaces are invalidated.
|
||||
auto status = wifi_nan_iface_->getCapabilitiesRequest(0);
|
||||
ASSERT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_WIFI_IFACE_INVALID));
|
||||
}
|
||||
|
||||
/*
|
||||
* EnableRequest - Invalid Args
|
||||
*/
|
||||
TEST_P(WifiNanIfaceAidlTest, EnableRequest_InvalidArgs) {
|
||||
uint16_t inputCmdId = 10;
|
||||
callback_type_ = INVALID;
|
||||
NanEnableRequest nanEnableRequest = {};
|
||||
NanConfigRequestSupplemental nanConfigRequestSupp = {};
|
||||
auto status =
|
||||
wifi_nan_iface_->enableRequest(inputCmdId, nanEnableRequest, nanConfigRequestSupp);
|
||||
if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
ASSERT_TRUE(status.isOk());
|
||||
|
||||
// Wait for a callback.
|
||||
ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
|
||||
ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callback_type_);
|
||||
ASSERT_EQ(id_, inputCmdId);
|
||||
ASSERT_EQ(status_.status, NanStatusCode::INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ConfigRequest - Invalid Args
|
||||
*/
|
||||
TEST_P(WifiNanIfaceAidlTest, ConfigRequest_InvalidArgs) {
|
||||
uint16_t inputCmdId = 10;
|
||||
callback_type_ = INVALID;
|
||||
NanConfigRequest nanConfigRequest = {};
|
||||
NanConfigRequestSupplemental nanConfigRequestSupp = {};
|
||||
auto status =
|
||||
wifi_nan_iface_->configRequest(inputCmdId, nanConfigRequest, nanConfigRequestSupp);
|
||||
|
||||
if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
ASSERT_TRUE(status.isOk());
|
||||
|
||||
// Wait for a callback.
|
||||
ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE));
|
||||
ASSERT_EQ(NOTIFY_CONFIG_RESPONSE, callback_type_);
|
||||
ASSERT_EQ(id_, inputCmdId);
|
||||
ASSERT_EQ(status_.status, NanStatusCode::INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* EnableRequest - Invalid Args in Shim Conversion
|
||||
*/
|
||||
TEST_P(WifiNanIfaceAidlTest, EnableRequest_InvalidShimArgs) {
|
||||
uint16_t inputCmdId = 10;
|
||||
NanEnableRequest nanEnableRequest = {};
|
||||
nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon = -15; // must be > 0
|
||||
NanConfigRequestSupplemental nanConfigRequestSupp = {};
|
||||
auto status =
|
||||
wifi_nan_iface_->enableRequest(inputCmdId, nanEnableRequest, nanConfigRequestSupp);
|
||||
if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
ASSERT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ConfigRequest - Invalid Args in Shim Conversion
|
||||
*/
|
||||
TEST_P(WifiNanIfaceAidlTest, ConfigRequest_InvalidShimArgs) {
|
||||
uint16_t inputCmdId = 10;
|
||||
NanConfigRequest nanConfigRequest = {};
|
||||
nanConfigRequest.numberOfPublishServiceIdsInBeacon = -15; // must be > 0
|
||||
NanConfigRequestSupplemental nanConfigRequestSupp = {};
|
||||
auto status =
|
||||
wifi_nan_iface_->configRequest(inputCmdId, nanConfigRequest, nanConfigRequestSupp);
|
||||
if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
ASSERT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NotifyCapabilitiesResponse
|
||||
*/
|
||||
TEST_P(WifiNanIfaceAidlTest, NotifyCapabilitiesResponse) {
|
||||
uint16_t inputCmdId = 10;
|
||||
callback_type_ = INVALID;
|
||||
EXPECT_TRUE(wifi_nan_iface_->getCapabilitiesRequest(inputCmdId).isOk());
|
||||
|
||||
// Wait for a callback.
|
||||
ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CAPABILITIES_RESPONSE));
|
||||
ASSERT_EQ(NOTIFY_CAPABILITIES_RESPONSE, callback_type_);
|
||||
ASSERT_EQ(id_, inputCmdId);
|
||||
ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
|
||||
|
||||
// Check for reasonable capability values.
|
||||
EXPECT_GT(capabilities_.maxConcurrentClusters, 0);
|
||||
EXPECT_GT(capabilities_.maxPublishes, 0);
|
||||
EXPECT_GT(capabilities_.maxSubscribes, 0);
|
||||
EXPECT_EQ(capabilities_.maxServiceNameLen, 255);
|
||||
EXPECT_EQ(capabilities_.maxMatchFilterLen, 255);
|
||||
EXPECT_GT(capabilities_.maxTotalMatchFilterLen, 255);
|
||||
EXPECT_EQ(capabilities_.maxServiceSpecificInfoLen, 255);
|
||||
EXPECT_GE(capabilities_.maxExtendedServiceSpecificInfoLen, 255);
|
||||
EXPECT_GT(capabilities_.maxNdiInterfaces, 0);
|
||||
EXPECT_GT(capabilities_.maxNdpSessions, 0);
|
||||
EXPECT_GT(capabilities_.maxAppInfoLen, 0);
|
||||
EXPECT_GT(capabilities_.maxQueuedTransmitFollowupMsgs, 0);
|
||||
EXPECT_GT(capabilities_.maxSubscribeInterfaceAddresses, 0);
|
||||
EXPECT_NE(static_cast<int32_t>(capabilities_.supportedCipherSuites), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* StartPublishRequest
|
||||
*/
|
||||
TEST_P(WifiNanIfaceAidlTest, StartPublishRequest) {
|
||||
uint16_t inputCmdId = 10;
|
||||
NanBandSpecificConfig config24 = {};
|
||||
config24.rssiClose = 60;
|
||||
config24.rssiMiddle = 70;
|
||||
config24.rssiCloseProximity = 60;
|
||||
config24.dwellTimeMs = 200;
|
||||
config24.scanPeriodSec = 20;
|
||||
config24.validDiscoveryWindowIntervalVal = false;
|
||||
config24.discoveryWindowIntervalVal = 0;
|
||||
|
||||
NanBandSpecificConfig config5 = {};
|
||||
config5.rssiClose = 60;
|
||||
config5.rssiMiddle = 75;
|
||||
config5.rssiCloseProximity = 60;
|
||||
config5.dwellTimeMs = 200;
|
||||
config5.scanPeriodSec = 20;
|
||||
config5.validDiscoveryWindowIntervalVal = false;
|
||||
config5.discoveryWindowIntervalVal = 0;
|
||||
|
||||
NanEnableRequest req = {};
|
||||
req.operateInBand[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = true;
|
||||
req.operateInBand[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = false;
|
||||
req.hopCountMax = 2;
|
||||
req.configParams.masterPref = 0;
|
||||
req.configParams.disableDiscoveryAddressChangeIndication = true;
|
||||
req.configParams.disableStartedClusterIndication = true;
|
||||
req.configParams.disableJoinedClusterIndication = true;
|
||||
req.configParams.includePublishServiceIdsInBeacon = true;
|
||||
req.configParams.numberOfPublishServiceIdsInBeacon = 0;
|
||||
req.configParams.includeSubscribeServiceIdsInBeacon = true;
|
||||
req.configParams.numberOfSubscribeServiceIdsInBeacon = 0;
|
||||
req.configParams.rssiWindowSize = 8;
|
||||
req.configParams.macAddressRandomizationIntervalSec = 1800;
|
||||
req.configParams.bandSpecificConfig[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] =
|
||||
config24;
|
||||
req.configParams.bandSpecificConfig[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] =
|
||||
config5;
|
||||
|
||||
req.debugConfigs.validClusterIdVals = true;
|
||||
req.debugConfigs.clusterIdTopRangeVal = 65535;
|
||||
req.debugConfigs.clusterIdBottomRangeVal = 0;
|
||||
req.debugConfigs.validIntfAddrVal = false;
|
||||
req.debugConfigs.validOuiVal = false;
|
||||
req.debugConfigs.ouiVal = 0;
|
||||
req.debugConfigs.validRandomFactorForceVal = false;
|
||||
req.debugConfigs.randomFactorForceVal = 0;
|
||||
req.debugConfigs.validHopCountForceVal = false;
|
||||
req.debugConfigs.hopCountForceVal = 0;
|
||||
req.debugConfigs.validDiscoveryChannelVal = false;
|
||||
req.debugConfigs.discoveryChannelMhzVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = 0;
|
||||
req.debugConfigs.discoveryChannelMhzVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = 0;
|
||||
req.debugConfigs.validUseBeaconsInBandVal = false;
|
||||
req.debugConfigs.useBeaconsInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = true;
|
||||
req.debugConfigs.useBeaconsInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = true;
|
||||
req.debugConfigs.validUseSdfInBandVal = false;
|
||||
req.debugConfigs.useSdfInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = true;
|
||||
req.debugConfigs.useSdfInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = true;
|
||||
|
||||
NanConfigRequestSupplemental nanConfigRequestSupp = {};
|
||||
nanConfigRequestSupp.discoveryBeaconIntervalMs = 20;
|
||||
nanConfigRequestSupp.numberOfSpatialStreamsInDiscovery = 0;
|
||||
nanConfigRequestSupp.enableDiscoveryWindowEarlyTermination = false;
|
||||
|
||||
callback_type_ = INVALID;
|
||||
auto status = wifi_nan_iface_->enableRequest(inputCmdId, req, nanConfigRequestSupp);
|
||||
if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
ASSERT_TRUE(status.isOk());
|
||||
|
||||
// Wait for a callback.
|
||||
ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
|
||||
ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callback_type_);
|
||||
ASSERT_EQ(id_, inputCmdId);
|
||||
ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
|
||||
}
|
||||
|
||||
NanPublishRequest nanPublishRequest = {};
|
||||
nanPublishRequest.baseConfigs.sessionId = 0;
|
||||
nanPublishRequest.baseConfigs.ttlSec = 0;
|
||||
nanPublishRequest.baseConfigs.discoveryWindowPeriod = 1;
|
||||
nanPublishRequest.baseConfigs.discoveryCount = 0;
|
||||
nanPublishRequest.baseConfigs.serviceName = {97};
|
||||
nanPublishRequest.baseConfigs.discoveryMatchIndicator = NanMatchAlg::MATCH_NEVER;
|
||||
nanPublishRequest.baseConfigs.useRssiThreshold = false;
|
||||
nanPublishRequest.baseConfigs.disableDiscoveryTerminationIndication = false;
|
||||
nanPublishRequest.baseConfigs.disableMatchExpirationIndication = true;
|
||||
nanPublishRequest.baseConfigs.disableFollowupReceivedIndication = false;
|
||||
nanPublishRequest.baseConfigs.securityConfig.securityType = NanDataPathSecurityType::OPEN;
|
||||
nanPublishRequest.autoAcceptDataPathRequests = false;
|
||||
nanPublishRequest.publishType = NanPublishType::UNSOLICITED;
|
||||
nanPublishRequest.txType = NanTxType::BROADCAST;
|
||||
|
||||
status = wifi_nan_iface_->startPublishRequest(inputCmdId + 1, nanPublishRequest);
|
||||
if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
ASSERT_TRUE(status.isOk());
|
||||
|
||||
// Wait for a callback.
|
||||
ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_START_PUBLISH_RESPONSE));
|
||||
ASSERT_EQ(NOTIFY_START_PUBLISH_RESPONSE, callback_type_);
|
||||
ASSERT_EQ(id_, inputCmdId + 1);
|
||||
ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* RespondToDataPathIndicationRequest - Invalid Args
|
||||
*/
|
||||
TEST_P(WifiNanIfaceAidlTest, RespondToDataPathIndicationRequest_InvalidArgs) {
|
||||
uint16_t inputCmdId = 10;
|
||||
callback_type_ = INVALID;
|
||||
NanRespondToDataPathIndicationRequest nanRespondToDataPathIndicationRequest = {};
|
||||
nanRespondToDataPathIndicationRequest.ifaceName = "AwareInterfaceNameTooLong";
|
||||
auto status = wifi_nan_iface_->respondToDataPathIndicationRequest(
|
||||
inputCmdId, nanRespondToDataPathIndicationRequest);
|
||||
|
||||
if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
ASSERT_EQ(status.getServiceSpecificError(),
|
||||
static_cast<int32_t>(WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* InitiateDataPathRequest - Invalid Args
|
||||
*/
|
||||
TEST_P(WifiNanIfaceAidlTest, InitiateDataPathRequest_InvalidArgs) {
|
||||
uint16_t inputCmdId = 10;
|
||||
callback_type_ = INVALID;
|
||||
NanInitiateDataPathRequest nanInitiateDataPathRequest = {};
|
||||
nanInitiateDataPathRequest.ifaceName = "AwareInterfaceNameTooLong";
|
||||
auto status = wifi_nan_iface_->initiateDataPathRequest(inputCmdId, nanInitiateDataPathRequest);
|
||||
|
||||
if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
ASSERT_EQ(status.getServiceSpecificError(),
|
||||
static_cast<int32_t>(WifiStatusCode::ERROR_INVALID_ARGS));
|
||||
}
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceAidlTest);
|
||||
INSTANTIATE_TEST_SUITE_P(WifiTest, WifiNanIfaceAidlTest,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
|
||||
android::ProcessState::self()->startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
234
wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp
Normal file
234
wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Staache 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 <vector>
|
||||
|
||||
#include <VtsCoreUtil.h>
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/wifi/BnWifi.h>
|
||||
#include <aidl/android/hardware/wifi/BnWifiRttControllerEventCallback.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_status.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
|
||||
#include "wifi_aidl_test_utils.h"
|
||||
|
||||
using aidl::android::hardware::wifi::BnWifiRttControllerEventCallback;
|
||||
using aidl::android::hardware::wifi::IWifiRttController;
|
||||
using aidl::android::hardware::wifi::RttBw;
|
||||
using aidl::android::hardware::wifi::RttCapabilities;
|
||||
using aidl::android::hardware::wifi::RttConfig;
|
||||
using aidl::android::hardware::wifi::RttPeerType;
|
||||
using aidl::android::hardware::wifi::RttPreamble;
|
||||
using aidl::android::hardware::wifi::RttResponder;
|
||||
using aidl::android::hardware::wifi::RttResult;
|
||||
using aidl::android::hardware::wifi::RttType;
|
||||
using aidl::android::hardware::wifi::WifiChannelInfo;
|
||||
using aidl::android::hardware::wifi::WifiChannelWidthInMhz;
|
||||
using aidl::android::hardware::wifi::WifiStatusCode;
|
||||
|
||||
class WifiRttControllerAidlTest : public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
if (!::testing::deviceSupportsFeature("android.hardware.wifi.rtt"))
|
||||
GTEST_SKIP() << "Skipping this test since RTT is not supported.";
|
||||
stopWifiService(getInstanceName());
|
||||
wifi_rtt_controller_ = getWifiRttController();
|
||||
ASSERT_NE(nullptr, wifi_rtt_controller_.get());
|
||||
|
||||
// Check RTT support before we run the test.
|
||||
RttCapabilities caps = {};
|
||||
auto status = wifi_rtt_controller_->getCapabilities(&caps);
|
||||
if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
|
||||
GTEST_SKIP() << "Skipping this test since RTT is not supported.";
|
||||
}
|
||||
}
|
||||
|
||||
void TearDown() override { stopWifiService(getInstanceName()); }
|
||||
|
||||
protected:
|
||||
std::shared_ptr<IWifiRttController> getWifiRttController() {
|
||||
std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
|
||||
EXPECT_NE(nullptr, wifi_chip.get());
|
||||
|
||||
std::shared_ptr<IWifiStaIface> wifi_sta_iface = getWifiStaIface(getInstanceName());
|
||||
EXPECT_NE(nullptr, wifi_sta_iface.get());
|
||||
|
||||
std::shared_ptr<IWifiRttController> rtt_controller;
|
||||
EXPECT_TRUE(wifi_chip->createRttController(wifi_sta_iface, &rtt_controller).isOk());
|
||||
EXPECT_NE(nullptr, rtt_controller.get());
|
||||
return rtt_controller;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiRttController> wifi_rtt_controller_;
|
||||
|
||||
private:
|
||||
const char* getInstanceName() { return GetParam().c_str(); }
|
||||
};
|
||||
|
||||
class WifiRttControllerEventCallback : public BnWifiRttControllerEventCallback {
|
||||
public:
|
||||
WifiRttControllerEventCallback() = default;
|
||||
|
||||
::ndk::ScopedAStatus onResults(int /* cmdId */,
|
||||
const std::vector<RttResult>& /* results */) override {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* RegisterEventCallback
|
||||
*
|
||||
* Note: it is not feasible to test the invocation of the callback function,
|
||||
* since events are triggered internally in the HAL implementation and cannot be
|
||||
* triggered from the test case.
|
||||
*/
|
||||
TEST_P(WifiRttControllerAidlTest, RegisterEventCallback) {
|
||||
std::shared_ptr<WifiRttControllerEventCallback> callback =
|
||||
ndk::SharedRefBase::make<WifiRttControllerEventCallback>();
|
||||
ASSERT_NE(nullptr, callback.get());
|
||||
EXPECT_TRUE(wifi_rtt_controller_->registerEventCallback(callback).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetCapabilities
|
||||
*/
|
||||
TEST_P(WifiRttControllerAidlTest, GetCapabilities) {
|
||||
RttCapabilities caps = {};
|
||||
EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetResponderInfo
|
||||
*/
|
||||
TEST_P(WifiRttControllerAidlTest, GetResponderInfo) {
|
||||
RttResponder responder = {};
|
||||
EXPECT_TRUE(wifi_rtt_controller_->getResponderInfo(&responder).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* EnableResponder
|
||||
*/
|
||||
TEST_P(WifiRttControllerAidlTest, EnableResponder) {
|
||||
int cmdId = 55;
|
||||
WifiChannelInfo channelInfo;
|
||||
channelInfo.width = WifiChannelWidthInMhz::WIDTH_80;
|
||||
channelInfo.centerFreq = 5660;
|
||||
channelInfo.centerFreq0 = 5660;
|
||||
channelInfo.centerFreq1 = 0;
|
||||
|
||||
RttResponder responder = {};
|
||||
EXPECT_TRUE(wifi_rtt_controller_->getResponderInfo(&responder).isOk());
|
||||
EXPECT_TRUE(wifi_rtt_controller_->enableResponder(cmdId, channelInfo, 10, responder).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* Request2SidedRangeMeasurement
|
||||
* Tests the two sided ranging - 802.11mc FTM protocol.
|
||||
*/
|
||||
TEST_P(WifiRttControllerAidlTest, Request2SidedRangeMeasurement) {
|
||||
RttCapabilities caps = {};
|
||||
EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk());
|
||||
if (!caps.rttFtmSupported) {
|
||||
GTEST_SKIP() << "Skipping two sided RTT since driver/fw does not support";
|
||||
}
|
||||
|
||||
RttConfig config;
|
||||
config.addr = {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}};
|
||||
config.type = RttType::TWO_SIDED;
|
||||
config.peer = RttPeerType::AP;
|
||||
config.channel.width = WifiChannelWidthInMhz::WIDTH_80;
|
||||
config.channel.centerFreq = 5180;
|
||||
config.channel.centerFreq0 = 5210;
|
||||
config.channel.centerFreq1 = 0;
|
||||
config.bw = RttBw::BW_20MHZ;
|
||||
config.preamble = RttPreamble::HT;
|
||||
config.mustRequestLci = false;
|
||||
config.mustRequestLcr = false;
|
||||
config.burstPeriod = 0;
|
||||
config.numBurst = 0;
|
||||
config.numFramesPerBurst = 8;
|
||||
config.numRetriesPerRttFrame = 0;
|
||||
config.numRetriesPerFtmr = 0;
|
||||
config.burstDuration = 9;
|
||||
|
||||
int cmdId = 55;
|
||||
std::vector<RttConfig> configs = {config};
|
||||
EXPECT_TRUE(wifi_rtt_controller_->rangeRequest(cmdId, configs).isOk());
|
||||
|
||||
// Sleep for 2 seconds to wait for driver/firmware to complete RTT.
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
/*
|
||||
* RangeRequest
|
||||
*/
|
||||
TEST_P(WifiRttControllerAidlTest, RangeRequest) {
|
||||
RttCapabilities caps = {};
|
||||
EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk());
|
||||
if (!caps.rttOneSidedSupported) {
|
||||
GTEST_SKIP() << "Skipping one sided RTT since driver/fw does not support";
|
||||
}
|
||||
|
||||
// Get the highest supported preamble.
|
||||
int preamble = 1;
|
||||
int caps_preamble_support = static_cast<int>(caps.preambleSupport);
|
||||
caps_preamble_support >>= 1;
|
||||
while (caps_preamble_support != 0) {
|
||||
caps_preamble_support >>= 1;
|
||||
preamble <<= 1;
|
||||
}
|
||||
|
||||
RttConfig config;
|
||||
config.addr = {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}};
|
||||
config.type = RttType::ONE_SIDED;
|
||||
config.peer = RttPeerType::AP;
|
||||
config.channel.width = WifiChannelWidthInMhz::WIDTH_80;
|
||||
config.channel.centerFreq = 5765;
|
||||
config.channel.centerFreq0 = 5775;
|
||||
config.channel.centerFreq1 = 0;
|
||||
config.bw = RttBw::BW_80MHZ;
|
||||
config.preamble = static_cast<RttPreamble>(preamble);
|
||||
config.mustRequestLci = false;
|
||||
config.mustRequestLcr = false;
|
||||
config.burstPeriod = 0;
|
||||
config.numBurst = 0;
|
||||
config.numFramesPerBurst = 8;
|
||||
config.numRetriesPerRttFrame = 3;
|
||||
config.numRetriesPerFtmr = 3;
|
||||
config.burstDuration = 9;
|
||||
|
||||
int cmdId = 55;
|
||||
std::vector<RttConfig> configs = {config};
|
||||
EXPECT_TRUE(wifi_rtt_controller_->rangeRequest(cmdId, configs).isOk());
|
||||
|
||||
// Sleep for 2 seconds to wait for driver/firmware to complete RTT.
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiRttControllerAidlTest);
|
||||
INSTANTIATE_TEST_SUITE_P(WifiTest, WifiRttControllerAidlTest,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
|
||||
android::ProcessState::self()->startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
282
wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
Normal file
282
wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Staache 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 <vector>
|
||||
|
||||
#include <VtsCoreUtil.h>
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/wifi/BnWifi.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_status.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
|
||||
#include "wifi_aidl_test_utils.h"
|
||||
|
||||
using aidl::android::hardware::wifi::IWifi;
|
||||
using aidl::android::hardware::wifi::IWifiStaIface;
|
||||
using aidl::android::hardware::wifi::MacAddress;
|
||||
using aidl::android::hardware::wifi::Ssid;
|
||||
using aidl::android::hardware::wifi::StaApfPacketFilterCapabilities;
|
||||
using aidl::android::hardware::wifi::StaBackgroundScanCapabilities;
|
||||
using aidl::android::hardware::wifi::StaLinkLayerStats;
|
||||
using aidl::android::hardware::wifi::StaRoamingCapabilities;
|
||||
using aidl::android::hardware::wifi::StaRoamingConfig;
|
||||
using aidl::android::hardware::wifi::StaRoamingState;
|
||||
using aidl::android::hardware::wifi::WifiBand;
|
||||
using aidl::android::hardware::wifi::WifiDebugRxPacketFateReport;
|
||||
using aidl::android::hardware::wifi::WifiDebugTxPacketFateReport;
|
||||
using aidl::android::hardware::wifi::WifiStatusCode;
|
||||
|
||||
class WifiStaIfaceAidlTest : public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
stopWifiService(getInstanceName());
|
||||
wifi_sta_iface_ = getWifiStaIface(getInstanceName());
|
||||
ASSERT_NE(nullptr, wifi_sta_iface_.get());
|
||||
}
|
||||
|
||||
void TearDown() override { stopWifiService(getInstanceName()); }
|
||||
|
||||
protected:
|
||||
bool isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask expected) {
|
||||
IWifiStaIface::StaIfaceCapabilityMask caps = {};
|
||||
EXPECT_TRUE(wifi_sta_iface_->getCapabilities(&caps).isOk());
|
||||
return static_cast<uint32_t>(caps) & static_cast<uint32_t>(expected);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus createStaIface(std::shared_ptr<IWifiStaIface>* sta_iface) {
|
||||
std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
|
||||
EXPECT_NE(nullptr, wifi_chip.get());
|
||||
return wifi_chip->createStaIface(sta_iface);
|
||||
}
|
||||
|
||||
std::shared_ptr<IWifiStaIface> wifi_sta_iface_;
|
||||
|
||||
private:
|
||||
const char* getInstanceName() { return GetParam().c_str(); }
|
||||
};
|
||||
|
||||
/*
|
||||
* GetFactoryMacAddress
|
||||
* Ensures that calls to getFactoryMacAddress will retrieve a non-zero MAC.
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, GetFactoryMacAddress) {
|
||||
std::array<uint8_t, 6> mac;
|
||||
EXPECT_TRUE(wifi_sta_iface_->getFactoryMacAddress(&mac).isOk());
|
||||
std::array<uint8_t, 6> all_zero_mac = {0, 0, 0, 0, 0, 0};
|
||||
EXPECT_NE(mac, all_zero_mac);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetCapabilities
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, GetCapabilities) {
|
||||
IWifiStaIface::StaIfaceCapabilityMask caps = {};
|
||||
EXPECT_TRUE(wifi_sta_iface_->getCapabilities(&caps).isOk());
|
||||
EXPECT_NE(static_cast<int32_t>(caps), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetApfPacketFilterCapabilities
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, GetApfPacketFilterCapabilities) {
|
||||
if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::APF)) {
|
||||
GTEST_SKIP() << "APF packet filter capabilities are not supported.";
|
||||
}
|
||||
StaApfPacketFilterCapabilities apf_caps = {};
|
||||
EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetBackgroundScanCapabilities
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, GetBackgroundScanCapabilities) {
|
||||
if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::BACKGROUND_SCAN)) {
|
||||
GTEST_SKIP() << "Background scan capabilities are not supported.";
|
||||
}
|
||||
StaBackgroundScanCapabilities caps = {};
|
||||
EXPECT_TRUE(wifi_sta_iface_->getBackgroundScanCapabilities(&caps).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* GetValidFrequenciesForBand
|
||||
* Ensures that we can retrieve valid frequencies for the 2.4 GHz band.
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, GetValidFrequenciesForBand) {
|
||||
std::vector<int> freqs;
|
||||
EXPECT_TRUE(wifi_sta_iface_->getValidFrequenciesForBand(WifiBand::BAND_24GHZ, &freqs).isOk());
|
||||
EXPECT_NE(freqs.size(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetLinkLayerStats
|
||||
* Ensures that calls to getLinkLayerStats will retrieve a non-empty
|
||||
* StaLinkLayerStats after link layer stats collection is enabled.
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, GetLinkLayerStats) {
|
||||
if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) {
|
||||
GTEST_SKIP() << "Skipping this test since link layer stats are not supported.";
|
||||
}
|
||||
|
||||
// Enable link layer stats collection.
|
||||
EXPECT_TRUE(wifi_sta_iface_->enableLinkLayerStatsCollection(true).isOk());
|
||||
|
||||
// Retrieve link layer stats.
|
||||
StaLinkLayerStats link_layer_stats = {};
|
||||
EXPECT_TRUE(wifi_sta_iface_->getLinkLayerStats(&link_layer_stats).isOk());
|
||||
EXPECT_GT(link_layer_stats.timeStampInMs, 0);
|
||||
|
||||
// Try to create a 2nd iface. If successful, it should fill the duty cycle field.
|
||||
std::shared_ptr<IWifiStaIface> iface;
|
||||
auto status = createStaIface(&iface);
|
||||
if (status.isOk()) {
|
||||
EXPECT_GT(link_layer_stats.iface.timeSliceDutyCycleInPercent, 0);
|
||||
}
|
||||
|
||||
// Disable link layer stats collection.
|
||||
EXPECT_TRUE(wifi_sta_iface_->disableLinkLayerStatsCollection().isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* SetMacAddress
|
||||
* Ensures that calls to setMacAddress will return successfully.
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, SetMacAddress) {
|
||||
std::array<uint8_t, 6> mac = {0x12, 0x22, 0x33, 0x52, 0x10, 0x41};
|
||||
EXPECT_TRUE(wifi_sta_iface_->setMacAddress(mac).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* SetScanMode
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, SetScanMode) {
|
||||
auto status = wifi_sta_iface_->setScanMode(true);
|
||||
EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
|
||||
status = wifi_sta_iface_->setScanMode(false);
|
||||
EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
|
||||
/*
|
||||
* LinkLayerStatsCollection
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, LinkLayerStatsCollection) {
|
||||
if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) {
|
||||
GTEST_SKIP() << "Link layer stats collection is not supported.";
|
||||
}
|
||||
|
||||
// Enable link layer stats collection.
|
||||
EXPECT_TRUE(wifi_sta_iface_->enableLinkLayerStatsCollection(true).isOk());
|
||||
|
||||
// Retrieve link layer stats.
|
||||
StaLinkLayerStats link_layer_stats = {};
|
||||
EXPECT_TRUE(wifi_sta_iface_->getLinkLayerStats(&link_layer_stats).isOk());
|
||||
|
||||
// Disable link layer stats collection.
|
||||
EXPECT_TRUE(wifi_sta_iface_->disableLinkLayerStatsCollection().isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* RSSIMonitoring
|
||||
* Ensures that calls to startRssiMonitoring and stopRssiMonitoring will fail
|
||||
* if the device is not connected to an AP.
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, RSSIMonitoring) {
|
||||
if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::RSSI_MONITOR)) {
|
||||
GTEST_SKIP() << "RSSI monitoring is not supported.";
|
||||
}
|
||||
|
||||
const int cmd = 1;
|
||||
const int maxRssi = -50;
|
||||
const int minRssi = -90;
|
||||
// Expected to fail because device is not connected to an AP.
|
||||
EXPECT_FALSE(wifi_sta_iface_->startRssiMonitoring(cmd, maxRssi, minRssi).isOk());
|
||||
EXPECT_FALSE(wifi_sta_iface_->stopRssiMonitoring(cmd).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* RoamingControl
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, RoamingControl) {
|
||||
if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::CONTROL_ROAMING)) {
|
||||
GTEST_SKIP() << "Roaming control is not supported.";
|
||||
}
|
||||
|
||||
// Retrieve roaming capabilities.
|
||||
StaRoamingCapabilities caps = {};
|
||||
EXPECT_TRUE(wifi_sta_iface_->getRoamingCapabilities(&caps).isOk());
|
||||
|
||||
// Set up roaming configuration based on roaming capabilities.
|
||||
StaRoamingConfig roaming_config = {};
|
||||
if (caps.maxBlocklistSize > 0) {
|
||||
MacAddress block_list_entry;
|
||||
block_list_entry.data = std::array<uint8_t, 6>{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}};
|
||||
roaming_config.bssidBlocklist = {block_list_entry};
|
||||
}
|
||||
if (caps.maxAllowlistSize > 0) {
|
||||
Ssid allow_list_entry = {};
|
||||
allow_list_entry.data = std::array<uint8_t, 32>{{0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}};
|
||||
roaming_config.ssidAllowlist = {allow_list_entry};
|
||||
}
|
||||
|
||||
// Configure roaming.
|
||||
EXPECT_TRUE(wifi_sta_iface_->configureRoaming(roaming_config).isOk());
|
||||
|
||||
// Enable roaming.
|
||||
EXPECT_TRUE(wifi_sta_iface_->setRoamingState(StaRoamingState::ENABLED).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* EnableNDOffload
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, EnableNDOffload) {
|
||||
if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::ND_OFFLOAD)) {
|
||||
GTEST_SKIP() << "ND offload is not supported.";
|
||||
}
|
||||
EXPECT_TRUE(wifi_sta_iface_->enableNdOffload(true).isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* PacketFateMonitoring
|
||||
*/
|
||||
TEST_P(WifiStaIfaceAidlTest, PacketFateMonitoring) {
|
||||
if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::DEBUG_PACKET_FATE)) {
|
||||
GTEST_SKIP() << "Packet fate monitoring is not supported.";
|
||||
}
|
||||
|
||||
// Start packet fate monitoring.
|
||||
EXPECT_TRUE(wifi_sta_iface_->startDebugPacketFateMonitoring().isOk());
|
||||
|
||||
// Retrieve packets.
|
||||
std::vector<WifiDebugRxPacketFateReport> rx_reports;
|
||||
std::vector<WifiDebugTxPacketFateReport> tx_reports;
|
||||
EXPECT_TRUE(wifi_sta_iface_->getDebugRxPacketFates(&rx_reports).isOk());
|
||||
EXPECT_TRUE(wifi_sta_iface_->getDebugTxPacketFates(&tx_reports).isOk());
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceAidlTest);
|
||||
INSTANTIATE_TEST_SUITE_P(WifiTest, WifiStaIfaceAidlTest,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
|
||||
android::ProcessState::self()->startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user