summaryrefslogtreecommitdiffstats
path: root/wifi
diff options
context:
space:
mode:
Diffstat (limited to 'wifi')
-rw-r--r--wifi/1.3/default/Android.mk3
-rw-r--r--wifi/1.3/default/wifi_chip.cpp49
-rw-r--r--wifi/1.3/default/wifi_chip.h3
-rw-r--r--wifi/1.3/default/wifi_feature_flags.cpp28
-rw-r--r--wifi/1.3/default/wifi_legacy_hal.cpp29
-rw-r--r--wifi/1.3/default/wifi_legacy_hal.h7
6 files changed, 112 insertions, 7 deletions
diff --git a/wifi/1.3/default/Android.mk b/wifi/1.3/default/Android.mk
index 0a3809cce..0fb42177b 100644
--- a/wifi/1.3/default/Android.mk
+++ b/wifi/1.3/default/Android.mk
@@ -36,6 +36,9 @@ endif
ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
endif
+ifdef QC_WIFI_HIDL_FEATURE_DUAL_AP
+LOCAL_CPPFLAGS += -DQC_WIFI_HIDL_FEATURE_DUAL_AP
+endif
# Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed.
LOCAL_CFLAGS += -Wno-error=implicit-fallthrough
LOCAL_SRC_FILES := \
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp
index e9991dcee..2b137498b 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.3/default/wifi_chip.cpp
@@ -21,6 +21,7 @@
#include <cutils/properties.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
+#include <net/if.h>
#include "hidl_return_util.h"
#include "hidl_struct_util.h"
@@ -626,6 +627,8 @@ void WifiChip::invalidateAndRemoveAllIfaces() {
invalidateAndClearAll(nan_ifaces_);
invalidateAndClearAll(p2p_ifaces_);
invalidateAndClearAll(sta_ifaces_);
+ invalidateAndClearAll(created_ap_ifaces_);
+ invalidateAndClearAll(created_sta_ifaces_);
// Since all the ifaces are invalid now, all RTT controller objects
// using those ifaces also need to be invalidated.
for (const auto& rtt : rtt_controllers_) {
@@ -805,10 +808,24 @@ std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
+
+ bool iface_created = false;
std::string ifname = allocateApIfaceName();
+ if (!if_nametoindex(ifname.c_str())) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->QcAddInterface(getWlanIfaceName(0), ifname,
+ (uint32_t)IfaceType::AP);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to add interface: " << ifname << " "
+ << legacyErrorToString(legacy_status);
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ iface_created = true;
+ }
sp<WifiApIface> iface =
new WifiApIface(ifname, legacy_hal_, iface_util_, feature_flags_);
ap_ifaces_.push_back(iface);
+ if (iface_created) created_ap_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
@@ -840,6 +857,16 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
if (!iface.get()) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
+
+ if (findUsingName(created_ap_ifaces_, ifname) != nullptr) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->QcRemoveInterface(getWlanIfaceName(0), ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to remove interface: " << ifname << " "
+ << legacyErrorToString(legacy_status);
+ }
+ invalidateAndClear(created_ap_ifaces_, iface);
+ }
// Invalidate & remove any dependent objects first.
// Note: This is probably not required because we never create
// nan/rtt objects over AP iface. But, there is no harm to do it
@@ -952,9 +979,22 @@ std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
+ bool iface_created = false;
std::string ifname = allocateStaIfaceName();
+ if (!if_nametoindex(ifname.c_str())) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->QcAddInterface(getWlanIfaceName(0), ifname,
+ (uint32_t)IfaceType::STA);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to add interface: " << ifname << " "
+ << legacyErrorToString(legacy_status);
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ iface_created = true;
+ }
sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
sta_ifaces_.push_back(iface);
+ if (iface_created) created_sta_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
@@ -986,6 +1026,15 @@ WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
if (!iface.get()) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
+ if (findUsingName(created_sta_ifaces_, ifname) != nullptr) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->QcRemoveInterface(getWlanIfaceName(0), ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to remove interface: " << ifname << " "
+ << legacyErrorToString(legacy_status);
+ }
+ invalidateAndClear(created_sta_ifaces_, iface);
+ }
// Invalidate & remove any dependent objects first.
invalidateAndRemoveDependencies(ifname);
invalidateAndClear(sta_ifaces_, iface);
diff --git a/wifi/1.3/default/wifi_chip.h b/wifi/1.3/default/wifi_chip.h
index 153ca6a62..2af6ebe04 100644
--- a/wifi/1.3/default/wifi_chip.h
+++ b/wifi/1.3/default/wifi_chip.h
@@ -269,6 +269,9 @@ class WifiChip : public V1_3::IWifiChip {
hidl_callback_util::HidlCallbackHandler<V1_2::IWifiChipEventCallback>
event_cb_handler_;
+ std::vector<sp<WifiApIface>> created_ap_ifaces_;
+ std::vector<sp<WifiStaIface>> created_sta_ifaces_;
+
DISALLOW_COPY_AND_ASSIGN(WifiChip);
};
diff --git a/wifi/1.3/default/wifi_feature_flags.cpp b/wifi/1.3/default/wifi_feature_flags.cpp
index 7212cfac3..a0ffab790 100644
--- a/wifi/1.3/default/wifi_feature_flags.cpp
+++ b/wifi/1.3/default/wifi_feature_flags.cpp
@@ -79,14 +79,28 @@ constexpr ChipModeId kMainModeId = chip_mode_ids::kV3;
# 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}}
+# ifdef QC_WIFI_HIDL_FEATURE_DUAL_AP
+# ifdef WIFI_HIDL_FEATURE_AWARE
+// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) or (2 AP)
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
+ {{{STA}, 1}, {{P2P, NAN}, 1}},\
+ {{{AP}, 2}}
+# else
+// (1 STA + 1 AP) or (1 STA + 1 P2P) or (2 AP)
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
+ {{{STA}, 1}, {{P2P}, 1}},\
+ {{{AP}, 2}}
+# endif
# else
-// (1 STA + 1 AP) or (1 STA + 1 P2P)
-# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
- {{{STA}, 1}, {{P2P}, 1}}
+# 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
# endif
#else
diff --git a/wifi/1.3/default/wifi_legacy_hal.cpp b/wifi/1.3/default/wifi_legacy_hal.cpp
index 485bd1663..5240d5bfc 100644
--- a/wifi/1.3/default/wifi_legacy_hal.cpp
+++ b/wifi/1.3/default/wifi_legacy_hal.cpp
@@ -1415,6 +1415,35 @@ WifiLegacyHal::getGscanCachedResults(const std::string& iface_name) {
return {status, std::move(cached_scan_results)};
}
+wifi_error WifiLegacyHal::QcAddInterface(const std::string& iface_name,
+ const std::string& new_ifname,
+ uint32_t type) {
+ wifi_error status = global_func_table_.wifi_add_or_remove_virtual_intf(
+ getIfaceHandle(iface_name),
+ new_ifname.c_str(), type, true);
+
+ if (status == WIFI_SUCCESS) {
+ // refresh list of handlers now.
+ iface_name_to_handle_.clear();
+ status = retrieveIfaceHandles();
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::QcRemoveInterface(const std::string& iface_name,
+ const std::string& ifname) {
+ wifi_error status = global_func_table_.wifi_add_or_remove_virtual_intf(
+ getIfaceHandle(iface_name),
+ ifname.c_str(), 0, false);
+
+ if (status == WIFI_SUCCESS) {
+ // refresh list of handlers now.
+ iface_name_to_handle_.clear();
+ status = retrieveIfaceHandles();
+ }
+ return status;
+}
+
void WifiLegacyHal::invalidate() {
global_handle_ = nullptr;
iface_name_to_handle_.clear();
diff --git a/wifi/1.3/default/wifi_legacy_hal.h b/wifi/1.3/default/wifi_legacy_hal.h
index 9cfa17240..f88728b9c 100644
--- a/wifi/1.3/default/wifi_legacy_hal.h
+++ b/wifi/1.3/default/wifi_legacy_hal.h
@@ -367,6 +367,13 @@ class WifiLegacyHal {
wifi_error setCountryCode(const std::string& iface_name,
std::array<int8_t, 2> code);
+ wifi_error QcAddInterface(const std::string& iface_name,
+ const std::string& new_ifname,
+ uint32_t type);
+ wifi_error QcRemoveInterface(const std::string& iface_name,
+ const std::string& ifname);
+
+
private:
// Retrieve interface handles for all the available interfaces.
wifi_error retrieveIfaceHandles();