mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-08 16:21:23 +00:00
* changes: Skip AP and P2P tests in wifi_chip_aidl_test if those iface types cannot be created. Add AIDL VTS helper method to check whether the specified iface type is supported.
241 lines
7.6 KiB
C++
241 lines
7.6 KiB
C++
/*
|
|
* 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) {
|
|
if (!wifi_chip.get()) {
|
|
return false;
|
|
}
|
|
return configureChipToSupportConcurrencyTypeInternal(wifi_chip, type, configured_mode_id);
|
|
}
|
|
|
|
bool doesChipSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
|
|
IfaceConcurrencyType type) {
|
|
if (!wifi_chip.get()) {
|
|
return false;
|
|
}
|
|
std::vector<IWifiChip::ChipMode> chip_modes;
|
|
auto status = wifi_chip->getAvailableModes(&chip_modes);
|
|
if (!status.isOk()) {
|
|
return false;
|
|
}
|
|
int mode_id;
|
|
return findAnyModeSupportingConcurrencyType(type, chip_modes, &mode_id);
|
|
}
|
|
|
|
void stopWifiService(const char* instance_name) {
|
|
std::shared_ptr<IWifi> wifi = getWifi(instance_name);
|
|
if (wifi != nullptr) {
|
|
wifi->stop();
|
|
}
|
|
}
|
|
|
|
int32_t getChipFeatureSet(const std::shared_ptr<IWifiChip>& wifi_chip) {
|
|
if (!wifi_chip.get()) {
|
|
return 0;
|
|
}
|
|
int32_t features = 0;
|
|
if (wifi_chip->getFeatureSet(&features).isOk()) {
|
|
return features;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool isAidlServiceAvailable(const char* instance_name) {
|
|
return AServiceManager_isDeclared(instance_name);
|
|
}
|