wifi: Add provision to create/delete dynamic interface(s)

This commit does following:
create/delete softap interface at runtime, if needed.
create/delete station interface at runtime, if needed.

Bug: 146539882
Bug: 121156971
Test: Manual - Basic wifi sanity test.
Change-Id: I6ab9c9e134d2f09e27283c9e60df885392834de4
Signed-off-by: Vinay Gannevaram <quic_vganneva@quicinc.com>
This commit is contained in:
Sunil Ravi
2020-02-03 22:45:19 -08:00
parent 79899f080f
commit ddab4bbd9c
6 changed files with 92 additions and 0 deletions

View File

@@ -2715,6 +2715,21 @@ bool convertLegacyVectorOfRttResultToHidl(
}
return true;
}
legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(
IfaceType hidl_interface_type) {
switch (hidl_interface_type) {
case IfaceType::STA:
return legacy_hal::WIFI_INTERFACE_TYPE_STA;
case IfaceType::AP:
return legacy_hal::WIFI_INTERFACE_TYPE_AP;
case IfaceType::P2P:
return legacy_hal::WIFI_INTERFACE_TYPE_P2P;
case IfaceType::NAN:
return legacy_hal::WIFI_INTERFACE_TYPE_NAN;
}
CHECK(false);
}
} // namespace hidl_struct_util
} // namespace implementation
} // namespace V1_4

View File

@@ -65,6 +65,8 @@ legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2(
bool convertLegacyWifiMacInfosToHidl(
const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
std::vector<IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos);
legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(
IfaceType hidl_interface_type);
// STA iface conversion methods.
bool convertLegacyFeaturesToHidlStaCapabilities(

View File

@@ -797,6 +797,15 @@ std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
std::string ifname = allocateApIfaceName();
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->createVirtualInterface(
ifname,
hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to add interface: " << ifname << " "
<< legacyErrorToString(legacy_status);
return {createWifiStatusFromLegacyError(legacy_status), {}};
}
sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_, iface_util_);
ap_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
@@ -835,6 +844,12 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
// nan/rtt objects over AP iface. But, there is no harm to do it
// here and not make that assumption all over the place.
invalidateAndRemoveDependencies(ifname);
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->deleteVirtualInterface(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to remove interface: " << ifname << " "
<< legacyErrorToString(legacy_status);
}
invalidateAndClear(ap_ifaces_, iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
@@ -944,6 +959,15 @@ WifiChip::createStaIfaceInternal() {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
std::string ifname = allocateStaIfaceName();
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->createVirtualInterface(
ifname,
hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to add interface: " << ifname << " "
<< legacyErrorToString(legacy_status);
return {createWifiStatusFromLegacyError(legacy_status), {}};
}
sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
sta_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
@@ -979,6 +1003,12 @@ WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
}
// Invalidate & remove any dependent objects first.
invalidateAndRemoveDependencies(ifname);
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->deleteVirtualInterface(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to remove interface: " << ifname << " "
<< legacyErrorToString(legacy_status);
}
invalidateAndClear(sta_ifaces_, iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {

View File

@@ -19,6 +19,7 @@
#include <android-base/logging.h>
#include <cutils/properties.h>
#include <net/if.h>
#include "hidl_sync_util.h"
#include "wifi_legacy_hal.h"
@@ -1355,6 +1356,7 @@ wifi_error WifiLegacyHal::retrieveIfaceHandles() {
LOG(ERROR) << "Failed to enumerate interface handles";
return status;
}
iface_name_to_handle_.clear();
for (int i = 0; i < num_iface_handles; ++i) {
std::array<char, IFNAMSIZ> iface_name_arr = {};
status = global_func_table_.wifi_get_iface_name(
@@ -1421,6 +1423,39 @@ WifiLegacyHal::getGscanCachedResults(const std::string& iface_name) {
return {status, std::move(cached_scan_results)};
}
wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname,
wifi_interface_type iftype) {
// Create the interface if it doesn't exist. If interface already exist,
// Vendor Hal should return WIFI_SUCCESS.
wifi_error status = global_func_table_.wifi_virtual_interface_create(
global_handle_, ifname.c_str(), iftype);
return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
}
wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) {
// Delete the interface if it was created dynamically.
wifi_error status = global_func_table_.wifi_virtual_interface_delete(
global_handle_, ifname.c_str());
return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
}
wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(
const std::string& ifname, wifi_error status) {
if (status == WIFI_SUCCESS) {
// refresh list of handlers now.
status = retrieveIfaceHandles();
} else if (status == WIFI_ERROR_NOT_SUPPORTED) {
// Vendor hal does not implement this API. Such vendor implementations
// are expected to create / delete interface by other means.
// check if interface exists.
if (if_nametoindex(ifname.c_str())) {
status = retrieveIfaceHandles();
}
}
return status;
}
void WifiLegacyHal::invalidate() {
global_handle_ = nullptr;
iface_name_to_handle_.clear();

View File

@@ -369,6 +369,11 @@ class WifiLegacyHal {
wifi_error setCountryCode(const std::string& iface_name,
std::array<int8_t, 2> code);
// interface functions.
wifi_error createVirtualInterface(const std::string& ifname,
wifi_interface_type iftype);
wifi_error deleteVirtualInterface(const std::string& ifname);
private:
// Retrieve interface handles for all the available interfaces.
wifi_error retrieveIfaceHandles();
@@ -380,6 +385,9 @@ class WifiLegacyHal {
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_;

View File

@@ -139,6 +139,8 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) {
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);
return true;
}
} // namespace legacy_hal