Loading wifi/1.5/IWifiChip.hal +40 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.hardware.wifi@1.5; import @1.0::WifiStatus; import @1.0::IWifiApIface; import @1.0::IWifiIface; import @1.3::IWifiChip; import @1.4::IWifiChip; Loading Loading @@ -127,4 +128,43 @@ interface IWifiChip extends @1.4::IWifiChip { * |WifiStatusCode.ERROR_INVALID_ARGS| */ setMultiStaUseCase(MultiStaUseCase useCase) generates (WifiStatus status); /** * Create bridged IWifiApIface. * * Depending on the mode the chip is configured in, the interface creation * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum * allowed (specified in |ChipIfaceCombination|) number of ifaces of the AP * type. * * @return status WifiStatus of the operation. * Possible status codes: * |WifiStatusCode.SUCCESS|, * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, * |WifiStatusCode.ERROR_NOT_SUPPORTED|, * |WifiStatusCode.ERROR_NOT_AVAILABLE| * @return iface HIDL interface object representing the iface if * successful, null otherwise. */ createBridgedApIface() generates (WifiStatus status, IWifiApIface iface); /** * Removes one of the instance on the AP Iface with the provided ifaceName and * ifaceInstanceName. * * Use the API: removeApIface with brIfaceName in the V1_0::WifiChip.hal to remove bridge Iface. * * @param brIfaceName Name of the bridged AP iface. * @param ifaceInstanceName Name of the instance. The empty instance is * invalid. * @return status WifiStatus of the operation. * Possible status codes: * |WifiStatusCode.SUCCESS|, * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, * |WifiStatusCode.ERROR_INVALID_ARGS|, * |WifiStatusCode.ERROR_NOT_AVAILABLE| */ removeIfaceInstanceFromBridgedApIface(string brIfaceName, string ifaceInstanceName) generates (WifiStatus status); }; wifi/1.5/default/wifi_chip.cpp +165 −17 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <android-base/logging.h> #include <android-base/unique_fd.h> #include <cutils/properties.h> #include <net/if.h> #include <sys/stat.h> #include <sys/sysmacros.h> Loading @@ -44,6 +45,7 @@ constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/"; constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface"; constexpr char kNoActiveWlanIfaceNamePropertyValue[] = ""; constexpr unsigned kMaxWlanIfaces = 5; constexpr char kApBridgeIfacePrefix[] = "ap_br_"; template <typename Iface> void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) { Loading Loading @@ -434,6 +436,13 @@ Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) { &WifiChip::createApIfaceInternal, hidl_status_cb); } Return<void> WifiChip::createBridgedApIface( createBridgedApIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::createBridgedApIfaceInternal, hidl_status_cb); } Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getApIfaceNamesInternal, hidl_status_cb); Loading @@ -453,6 +462,15 @@ Return<void> WifiChip::removeApIface(const hidl_string& ifname, ifname); } Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface( const hidl_string& ifname, const hidl_string& ifInstanceName, removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) { return validateAndCall( this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, hidl_status_cb, ifname, ifInstanceName); } Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::createNanIfaceInternal, hidl_status_cb); Loading Loading @@ -693,6 +711,7 @@ Return<void> WifiChip::setMultiStaUseCase( } void WifiChip::invalidateAndRemoveAllIfaces() { invalidateAndClearBridgedApAll(); invalidateAndClearAll(ap_ifaces_); invalidateAndClearAll(nan_ifaces_); invalidateAndClearAll(p2p_ifaces_); Loading Loading @@ -861,20 +880,20 @@ WifiChip::requestFirmwareDebugDumpInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump}; } std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } std::string ifname = allocateApIfaceName(); legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface( ifname, WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) { legacy_hal::wifi_error legacy_status; legacy_status = legacy_hal_.lock()->createVirtualInterface( apVirtIf, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP)); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to add interface: " << ifname << " " LOG(ERROR) << "Failed to add interface: " << apVirtIf << " " << legacyErrorToString(legacy_status); return {createWifiStatusFromLegacyError(legacy_status), {}}; return createWifiStatusFromLegacyError(legacy_status); } return createWifiStatus(WifiStatusCode::SUCCESS); } sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) { sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_, iface_util_); ap_ifaces_.push_back(iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { Loading @@ -883,6 +902,60 @@ std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() { } } setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); return iface; } std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } std::string ifname = allocateApIfaceName(); WifiStatus status = createVirtualApInterface(ifname); if (status.code != WifiStatusCode::SUCCESS) { return {status, {}}; } sp<WifiApIface> iface = newWifiApIface(ifname); return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createBridgedApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } std::string br_ifname = kApBridgeIfacePrefix + allocateApIfaceName(); std::vector<std::string> ap_instances; for (int i = 0; i < 2; i++) { // TODO: b/173999527, it should use idx from 2 when STA+STA support, but // need to check vendor support or not. std::string ifaceInstanceName = allocateApOrStaIfaceName( IfaceType::AP, isStaApConcurrencyAllowedInCurrentMode() ? 1 : 0); WifiStatus status = createVirtualApInterface(ifaceInstanceName); if (status.code != WifiStatusCode::SUCCESS) { if (ap_instances.size() != 0) { legacy_hal_.lock()->deleteVirtualInterface( ap_instances.front()); } return {status, {}}; } ap_instances.push_back(ifaceInstanceName); } br_ifaces_ap_instances_[br_ifname] = ap_instances; if (!iface_util_.lock()->createBridge(br_ifname)) { LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str(); invalidateAndClearBridgedAp(br_ifname); return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } for (auto const& instance : ap_instances) { // Bind ap instance interface to AP bridge if (!iface_util_.lock()->addIfaceToBridge(br_ifname, instance)) { LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str(); invalidateAndClearBridgedAp(br_ifname); return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } } sp<WifiApIface> iface = newWifiApIface(br_ifname); return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } Loading Loading @@ -913,12 +986,8 @@ 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); } // Clear the bridge interface and the iface instance. invalidateAndClearBridgedAp(ifname); invalidateAndClear(ap_ifaces_, iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) { Loading @@ -929,6 +998,42 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { return createWifiStatus(WifiStatusCode::SUCCESS); } WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( const std::string& ifname, const std::string& ifInstanceName) { legacy_hal::wifi_error legacy_status; const auto iface = findUsingName(ap_ifaces_, ifname); if (!iface.get() || !ifInstanceName.empty()) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } // Requires to remove one of the instance in bridge mode for (auto const& it : br_ifaces_ap_instances_) { if (it.first == ifname) { for (auto const& iface : it.second) { if (iface == ifInstanceName) { if (!iface_util_.lock()->removeIfaceFromBridge(it.first, iface)) { LOG(ERROR) << "Failed to remove interface: " << iface << " from " << ifname << ", error: " << legacyErrorToString(legacy_status); return createWifiStatus( WifiStatusCode::ERROR_NOT_AVAILABLE); } legacy_status = legacy_hal_.lock()->deleteVirtualInterface(iface); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to del interface: " << iface << " " << legacyErrorToString(legacy_status); return createWifiStatusFromLegacyError(legacy_status); } } } break; } } br_ifaces_ap_instances_.erase(ifInstanceName); return createWifiStatus(WifiStatusCode::SUCCESS); } std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::createNanIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) { Loading Loading @@ -1653,6 +1758,7 @@ std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) { for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) { const auto ifname = getWlanIfaceNameWithType(type, idx); if (findUsingNameFromBridgedApInstances(ifname)) continue; if (findUsingName(ap_ifaces_, ifname)) continue; if (findUsingName(sta_ifaces_, ifname)) continue; return ifname; Loading Loading @@ -1727,6 +1833,48 @@ std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) { return getWlanIfaceName(idx); } void WifiChip::invalidateAndClearBridgedApAll() { for (auto const& it : br_ifaces_ap_instances_) { for (auto const& iface : it.second) { iface_util_.lock()->removeIfaceFromBridge(it.first, iface); legacy_hal_.lock()->deleteVirtualInterface(iface); } iface_util_.lock()->deleteBridge(it.first); } br_ifaces_ap_instances_.clear(); } void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) { if (br_name.empty()) return; // delete managed interfaces for (auto const& it : br_ifaces_ap_instances_) { if (it.first == br_name) { for (auto const& iface : it.second) { iface_util_.lock()->removeIfaceFromBridge(br_name, iface); legacy_hal_.lock()->deleteVirtualInterface(iface); } iface_util_.lock()->deleteBridge(br_name); br_ifaces_ap_instances_.erase(br_name); break; } } return; } bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) { for (auto const& it : br_ifaces_ap_instances_) { if (it.first == name) { return true; } for (auto const& iface : it.second) { if (iface == name) { return true; } } } return false; } } // namespace implementation } // namespace V1_5 } // namespace wifi Loading wifi/1.5/default/wifi_chip.h +14 −1 Original line number Diff line number Diff line Loading @@ -94,11 +94,16 @@ class WifiChip : public V1_5::IWifiChip { Return<void> requestFirmwareDebugDump( requestFirmwareDebugDump_cb hidl_status_cb) override; Return<void> createApIface(createApIface_cb hidl_status_cb) override; Return<void> createBridgedApIface( createBridgedApIface_cb hidl_status_cb) override; Return<void> getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override; Return<void> getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) override; Return<void> removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) override; Return<void> removeIfaceInstanceFromBridgedApIface( const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName, removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override; Return<void> createNanIface(createNanIface_cb hidl_status_cb) override; Return<void> getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override; Return<void> getNanIface(const hidl_string& ifname, Loading Loading @@ -192,11 +197,16 @@ class WifiChip : public V1_5::IWifiChip { requestDriverDebugDumpInternal(); std::pair<WifiStatus, std::vector<uint8_t>> requestFirmwareDebugDumpInternal(); sp<WifiApIface> newWifiApIface(std::string& ifname); WifiStatus createVirtualApInterface(const std::string& apVirtIf); std::pair<WifiStatus, sp<IWifiApIface>> createApIfaceInternal(); std::pair<WifiStatus, sp<IWifiApIface>> createBridgedApIfaceInternal(); std::pair<WifiStatus, std::vector<hidl_string>> getApIfaceNamesInternal(); std::pair<WifiStatus, sp<IWifiApIface>> getApIfaceInternal( const std::string& ifname); WifiStatus removeApIfaceInternal(const std::string& ifname); WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal( const std::string& brIfaceName, const std::string& ifInstanceName); std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> createNanIfaceInternal(); std::pair<WifiStatus, std::vector<hidl_string>> getNanIfaceNamesInternal(); std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> getNanIfaceInternal( Loading Loading @@ -272,6 +282,9 @@ class WifiChip : public V1_5::IWifiChip { 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); ChipId chip_id_; std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; Loading @@ -296,7 +309,7 @@ class WifiChip : public V1_5::IWifiChip { event_cb_handler_; 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); }; Loading Loading
wifi/1.5/IWifiChip.hal +40 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.hardware.wifi@1.5; import @1.0::WifiStatus; import @1.0::IWifiApIface; import @1.0::IWifiIface; import @1.3::IWifiChip; import @1.4::IWifiChip; Loading Loading @@ -127,4 +128,43 @@ interface IWifiChip extends @1.4::IWifiChip { * |WifiStatusCode.ERROR_INVALID_ARGS| */ setMultiStaUseCase(MultiStaUseCase useCase) generates (WifiStatus status); /** * Create bridged IWifiApIface. * * Depending on the mode the chip is configured in, the interface creation * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum * allowed (specified in |ChipIfaceCombination|) number of ifaces of the AP * type. * * @return status WifiStatus of the operation. * Possible status codes: * |WifiStatusCode.SUCCESS|, * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, * |WifiStatusCode.ERROR_NOT_SUPPORTED|, * |WifiStatusCode.ERROR_NOT_AVAILABLE| * @return iface HIDL interface object representing the iface if * successful, null otherwise. */ createBridgedApIface() generates (WifiStatus status, IWifiApIface iface); /** * Removes one of the instance on the AP Iface with the provided ifaceName and * ifaceInstanceName. * * Use the API: removeApIface with brIfaceName in the V1_0::WifiChip.hal to remove bridge Iface. * * @param brIfaceName Name of the bridged AP iface. * @param ifaceInstanceName Name of the instance. The empty instance is * invalid. * @return status WifiStatus of the operation. * Possible status codes: * |WifiStatusCode.SUCCESS|, * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, * |WifiStatusCode.ERROR_INVALID_ARGS|, * |WifiStatusCode.ERROR_NOT_AVAILABLE| */ removeIfaceInstanceFromBridgedApIface(string brIfaceName, string ifaceInstanceName) generates (WifiStatus status); };
wifi/1.5/default/wifi_chip.cpp +165 −17 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <android-base/logging.h> #include <android-base/unique_fd.h> #include <cutils/properties.h> #include <net/if.h> #include <sys/stat.h> #include <sys/sysmacros.h> Loading @@ -44,6 +45,7 @@ constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/"; constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface"; constexpr char kNoActiveWlanIfaceNamePropertyValue[] = ""; constexpr unsigned kMaxWlanIfaces = 5; constexpr char kApBridgeIfacePrefix[] = "ap_br_"; template <typename Iface> void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) { Loading Loading @@ -434,6 +436,13 @@ Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) { &WifiChip::createApIfaceInternal, hidl_status_cb); } Return<void> WifiChip::createBridgedApIface( createBridgedApIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::createBridgedApIfaceInternal, hidl_status_cb); } Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getApIfaceNamesInternal, hidl_status_cb); Loading @@ -453,6 +462,15 @@ Return<void> WifiChip::removeApIface(const hidl_string& ifname, ifname); } Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface( const hidl_string& ifname, const hidl_string& ifInstanceName, removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) { return validateAndCall( this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, hidl_status_cb, ifname, ifInstanceName); } Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::createNanIfaceInternal, hidl_status_cb); Loading Loading @@ -693,6 +711,7 @@ Return<void> WifiChip::setMultiStaUseCase( } void WifiChip::invalidateAndRemoveAllIfaces() { invalidateAndClearBridgedApAll(); invalidateAndClearAll(ap_ifaces_); invalidateAndClearAll(nan_ifaces_); invalidateAndClearAll(p2p_ifaces_); Loading Loading @@ -861,20 +880,20 @@ WifiChip::requestFirmwareDebugDumpInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump}; } std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } std::string ifname = allocateApIfaceName(); legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface( ifname, WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) { legacy_hal::wifi_error legacy_status; legacy_status = legacy_hal_.lock()->createVirtualInterface( apVirtIf, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP)); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to add interface: " << ifname << " " LOG(ERROR) << "Failed to add interface: " << apVirtIf << " " << legacyErrorToString(legacy_status); return {createWifiStatusFromLegacyError(legacy_status), {}}; return createWifiStatusFromLegacyError(legacy_status); } return createWifiStatus(WifiStatusCode::SUCCESS); } sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) { sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_, iface_util_); ap_ifaces_.push_back(iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { Loading @@ -883,6 +902,60 @@ std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() { } } setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); return iface; } std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } std::string ifname = allocateApIfaceName(); WifiStatus status = createVirtualApInterface(ifname); if (status.code != WifiStatusCode::SUCCESS) { return {status, {}}; } sp<WifiApIface> iface = newWifiApIface(ifname); return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createBridgedApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } std::string br_ifname = kApBridgeIfacePrefix + allocateApIfaceName(); std::vector<std::string> ap_instances; for (int i = 0; i < 2; i++) { // TODO: b/173999527, it should use idx from 2 when STA+STA support, but // need to check vendor support or not. std::string ifaceInstanceName = allocateApOrStaIfaceName( IfaceType::AP, isStaApConcurrencyAllowedInCurrentMode() ? 1 : 0); WifiStatus status = createVirtualApInterface(ifaceInstanceName); if (status.code != WifiStatusCode::SUCCESS) { if (ap_instances.size() != 0) { legacy_hal_.lock()->deleteVirtualInterface( ap_instances.front()); } return {status, {}}; } ap_instances.push_back(ifaceInstanceName); } br_ifaces_ap_instances_[br_ifname] = ap_instances; if (!iface_util_.lock()->createBridge(br_ifname)) { LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str(); invalidateAndClearBridgedAp(br_ifname); return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } for (auto const& instance : ap_instances) { // Bind ap instance interface to AP bridge if (!iface_util_.lock()->addIfaceToBridge(br_ifname, instance)) { LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str(); invalidateAndClearBridgedAp(br_ifname); return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } } sp<WifiApIface> iface = newWifiApIface(br_ifname); return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } Loading Loading @@ -913,12 +986,8 @@ 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); } // Clear the bridge interface and the iface instance. invalidateAndClearBridgedAp(ifname); invalidateAndClear(ap_ifaces_, iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) { Loading @@ -929,6 +998,42 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { return createWifiStatus(WifiStatusCode::SUCCESS); } WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( const std::string& ifname, const std::string& ifInstanceName) { legacy_hal::wifi_error legacy_status; const auto iface = findUsingName(ap_ifaces_, ifname); if (!iface.get() || !ifInstanceName.empty()) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } // Requires to remove one of the instance in bridge mode for (auto const& it : br_ifaces_ap_instances_) { if (it.first == ifname) { for (auto const& iface : it.second) { if (iface == ifInstanceName) { if (!iface_util_.lock()->removeIfaceFromBridge(it.first, iface)) { LOG(ERROR) << "Failed to remove interface: " << iface << " from " << ifname << ", error: " << legacyErrorToString(legacy_status); return createWifiStatus( WifiStatusCode::ERROR_NOT_AVAILABLE); } legacy_status = legacy_hal_.lock()->deleteVirtualInterface(iface); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to del interface: " << iface << " " << legacyErrorToString(legacy_status); return createWifiStatusFromLegacyError(legacy_status); } } } break; } } br_ifaces_ap_instances_.erase(ifInstanceName); return createWifiStatus(WifiStatusCode::SUCCESS); } std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::createNanIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) { Loading Loading @@ -1653,6 +1758,7 @@ std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) { for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) { const auto ifname = getWlanIfaceNameWithType(type, idx); if (findUsingNameFromBridgedApInstances(ifname)) continue; if (findUsingName(ap_ifaces_, ifname)) continue; if (findUsingName(sta_ifaces_, ifname)) continue; return ifname; Loading Loading @@ -1727,6 +1833,48 @@ std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) { return getWlanIfaceName(idx); } void WifiChip::invalidateAndClearBridgedApAll() { for (auto const& it : br_ifaces_ap_instances_) { for (auto const& iface : it.second) { iface_util_.lock()->removeIfaceFromBridge(it.first, iface); legacy_hal_.lock()->deleteVirtualInterface(iface); } iface_util_.lock()->deleteBridge(it.first); } br_ifaces_ap_instances_.clear(); } void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) { if (br_name.empty()) return; // delete managed interfaces for (auto const& it : br_ifaces_ap_instances_) { if (it.first == br_name) { for (auto const& iface : it.second) { iface_util_.lock()->removeIfaceFromBridge(br_name, iface); legacy_hal_.lock()->deleteVirtualInterface(iface); } iface_util_.lock()->deleteBridge(br_name); br_ifaces_ap_instances_.erase(br_name); break; } } return; } bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) { for (auto const& it : br_ifaces_ap_instances_) { if (it.first == name) { return true; } for (auto const& iface : it.second) { if (iface == name) { return true; } } } return false; } } // namespace implementation } // namespace V1_5 } // namespace wifi Loading
wifi/1.5/default/wifi_chip.h +14 −1 Original line number Diff line number Diff line Loading @@ -94,11 +94,16 @@ class WifiChip : public V1_5::IWifiChip { Return<void> requestFirmwareDebugDump( requestFirmwareDebugDump_cb hidl_status_cb) override; Return<void> createApIface(createApIface_cb hidl_status_cb) override; Return<void> createBridgedApIface( createBridgedApIface_cb hidl_status_cb) override; Return<void> getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override; Return<void> getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) override; Return<void> removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) override; Return<void> removeIfaceInstanceFromBridgedApIface( const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName, removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override; Return<void> createNanIface(createNanIface_cb hidl_status_cb) override; Return<void> getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override; Return<void> getNanIface(const hidl_string& ifname, Loading Loading @@ -192,11 +197,16 @@ class WifiChip : public V1_5::IWifiChip { requestDriverDebugDumpInternal(); std::pair<WifiStatus, std::vector<uint8_t>> requestFirmwareDebugDumpInternal(); sp<WifiApIface> newWifiApIface(std::string& ifname); WifiStatus createVirtualApInterface(const std::string& apVirtIf); std::pair<WifiStatus, sp<IWifiApIface>> createApIfaceInternal(); std::pair<WifiStatus, sp<IWifiApIface>> createBridgedApIfaceInternal(); std::pair<WifiStatus, std::vector<hidl_string>> getApIfaceNamesInternal(); std::pair<WifiStatus, sp<IWifiApIface>> getApIfaceInternal( const std::string& ifname); WifiStatus removeApIfaceInternal(const std::string& ifname); WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal( const std::string& brIfaceName, const std::string& ifInstanceName); std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> createNanIfaceInternal(); std::pair<WifiStatus, std::vector<hidl_string>> getNanIfaceNamesInternal(); std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> getNanIfaceInternal( Loading Loading @@ -272,6 +282,9 @@ class WifiChip : public V1_5::IWifiChip { 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); ChipId chip_id_; std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; Loading @@ -296,7 +309,7 @@ class WifiChip : public V1_5::IWifiChip { event_cb_handler_; 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); }; Loading