1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include <fcntl.h> 17094332d3Sopenharmony_ci#include <net/if.h> 18094332d3Sopenharmony_ci#include <sys/stat.h> 19094332d3Sopenharmony_ci#include <sys/sysmacros.h> 20094332d3Sopenharmony_ci#include <cstring> 21094332d3Sopenharmony_ci#include "wifi_chip.h" 22094332d3Sopenharmony_ci#include "parameter.h" 23094332d3Sopenharmony_ci#include "wifi_hal.h" 24094332d3Sopenharmony_ci#include <hdf_log.h> 25094332d3Sopenharmony_ci 26094332d3Sopenharmony_cinamespace OHOS { 27094332d3Sopenharmony_cinamespace HDI { 28094332d3Sopenharmony_cinamespace Wlan { 29094332d3Sopenharmony_cinamespace Chip { 30094332d3Sopenharmony_cinamespace V1_0 { 31094332d3Sopenharmony_ciconstexpr int IFACE_TYPE_STA = 2; 32094332d3Sopenharmony_ciconstexpr char K_ACTIVE_WLAN_IFACE_NAME_PROPERTY[] = "wifi.active.interface"; 33094332d3Sopenharmony_ciconstexpr char K_NO_ACTIVE_WLAN_IFACE_NAME_PROPERTY_VALUE[] = ""; 34094332d3Sopenharmony_ciconstexpr unsigned K_MAX_WLAN_IFACES = 5; 35094332d3Sopenharmony_ciconst std::string AP_CODEX_DEFAULT_IFACENAME = "wlan1"; 36094332d3Sopenharmony_ci 37094332d3Sopenharmony_civoid InvalidateAndClearApIface(std::vector<sptr<WifiApIface>>& ifaces) 38094332d3Sopenharmony_ci{ 39094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 40094332d3Sopenharmony_ci iface->Invalidate(); 41094332d3Sopenharmony_ci } 42094332d3Sopenharmony_ci ifaces.clear(); 43094332d3Sopenharmony_ci} 44094332d3Sopenharmony_ci 45094332d3Sopenharmony_civoid InvalidateAndClearStaIface(std::vector<sptr<WifiStaIface>>& ifaces) 46094332d3Sopenharmony_ci{ 47094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 48094332d3Sopenharmony_ci iface->Invalidate(); 49094332d3Sopenharmony_ci } 50094332d3Sopenharmony_ci ifaces.clear(); 51094332d3Sopenharmony_ci} 52094332d3Sopenharmony_ci 53094332d3Sopenharmony_civoid InvalidateAndClearP2pIface(std::vector<sptr<WifiP2pIface>>& ifaces) 54094332d3Sopenharmony_ci{ 55094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 56094332d3Sopenharmony_ci iface->Invalidate(); 57094332d3Sopenharmony_ci } 58094332d3Sopenharmony_ci ifaces.clear(); 59094332d3Sopenharmony_ci} 60094332d3Sopenharmony_ci 61094332d3Sopenharmony_civoid InvalidateAndClearExtIface(std::vector<sptr<WifiExtIface>>& ifaces) 62094332d3Sopenharmony_ci{ 63094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 64094332d3Sopenharmony_ci iface->Invalidate(); 65094332d3Sopenharmony_ci } 66094332d3Sopenharmony_ci ifaces.clear(); 67094332d3Sopenharmony_ci} 68094332d3Sopenharmony_ci 69094332d3Sopenharmony_ciWifiChip::WifiChip( 70094332d3Sopenharmony_ci int32_t chipId, bool isPrimary, 71094332d3Sopenharmony_ci const std::weak_ptr<WifiVendorHal> vendorHal, 72094332d3Sopenharmony_ci const std::shared_ptr<IfaceUtil> ifaceUtil, 73094332d3Sopenharmony_ci const std::function<void(const std::string&)>& handler) 74094332d3Sopenharmony_ci : chipId_(chipId), 75094332d3Sopenharmony_ci vendorHal_(vendorHal), 76094332d3Sopenharmony_ci isValid_(true), 77094332d3Sopenharmony_ci currentModeId_(chip_mode_ids::K_INVALID), 78094332d3Sopenharmony_ci ifaceUtil_(ifaceUtil), 79094332d3Sopenharmony_ci subsystemCallbackHandler_(handler) 80094332d3Sopenharmony_ci{} 81094332d3Sopenharmony_ci 82094332d3Sopenharmony_ciWifiChip::~WifiChip() 83094332d3Sopenharmony_ci{} 84094332d3Sopenharmony_ci 85094332d3Sopenharmony_civoid WifiChip::Invalidate() 86094332d3Sopenharmony_ci{ 87094332d3Sopenharmony_ci InvalidateAndClearApIface(apIfaces_); 88094332d3Sopenharmony_ci InvalidateAndClearP2pIface(p2pIfaces_); 89094332d3Sopenharmony_ci InvalidateAndClearStaIface(staIfaces_); 90094332d3Sopenharmony_ci InvalidateAndClearExtIface(extIfaces_); 91094332d3Sopenharmony_ci SetParameter(K_ACTIVE_WLAN_IFACE_NAME_PROPERTY, K_NO_ACTIVE_WLAN_IFACE_NAME_PROPERTY_VALUE); 92094332d3Sopenharmony_ci vendorHal_.reset(); 93094332d3Sopenharmony_ci cbHandler_.Invalidate(); 94094332d3Sopenharmony_ci isValid_ = false; 95094332d3Sopenharmony_ci} 96094332d3Sopenharmony_ci 97094332d3Sopenharmony_ciint32_t WifiChip::GetChipId(int32_t& id) 98094332d3Sopenharmony_ci{ 99094332d3Sopenharmony_ci id = chipId_; 100094332d3Sopenharmony_ci return HDF_SUCCESS; 101094332d3Sopenharmony_ci} 102094332d3Sopenharmony_ci 103094332d3Sopenharmony_ciint32_t WifiChip::RegisterChipEventCallback(const sptr<IConcreteChipCallback>& chipEventcallback) 104094332d3Sopenharmony_ci{ 105094332d3Sopenharmony_ci if (!cbHandler_.AddCallback(chipEventcallback)) { 106094332d3Sopenharmony_ci return HDF_FAILURE; 107094332d3Sopenharmony_ci } 108094332d3Sopenharmony_ci return HDF_SUCCESS; 109094332d3Sopenharmony_ci} 110094332d3Sopenharmony_ci 111094332d3Sopenharmony_cistd::string GetWlanIfaceName(unsigned idx) 112094332d3Sopenharmony_ci{ 113094332d3Sopenharmony_ci if (idx >= K_MAX_WLAN_IFACES) { 114094332d3Sopenharmony_ci HDF_LOGI("Requested interface beyond wlan%{public}d", K_MAX_WLAN_IFACES); 115094332d3Sopenharmony_ci return ""; 116094332d3Sopenharmony_ci } 117094332d3Sopenharmony_ci return "wlan" + std::to_string(idx); 118094332d3Sopenharmony_ci} 119094332d3Sopenharmony_ci 120094332d3Sopenharmony_cistd::string WifiChip::GetIfaceName(IfaceType type, unsigned idx) 121094332d3Sopenharmony_ci{ 122094332d3Sopenharmony_ci return GetWlanIfaceName(idx); 123094332d3Sopenharmony_ci} 124094332d3Sopenharmony_ci 125094332d3Sopenharmony_cistd::string WifiChip::GetUsedIfaceName() 126094332d3Sopenharmony_ci{ 127094332d3Sopenharmony_ci if (staIfaces_.size() > 0) return staIfaces_[0]->GetName(); 128094332d3Sopenharmony_ci if (apIfaces_.size() > 0) { 129094332d3Sopenharmony_ci return apIfaces_[0]->GetName(); 130094332d3Sopenharmony_ci } 131094332d3Sopenharmony_ci HDF_LOGI("No active wlan interfaces in use! Using default"); 132094332d3Sopenharmony_ci return GetIfaceName(IfaceType::STA, 0); 133094332d3Sopenharmony_ci} 134094332d3Sopenharmony_ci 135094332d3Sopenharmony_ciint32_t WifiChip::GetChipCaps(uint32_t& capabilities) 136094332d3Sopenharmony_ci{ 137094332d3Sopenharmony_ci WifiError status; 138094332d3Sopenharmony_ci 139094332d3Sopenharmony_ci const auto ifname = GetUsedIfaceName(); 140094332d3Sopenharmony_ci status = vendorHal_.lock()->GetChipCaps(ifname, capabilities); 141094332d3Sopenharmony_ci if (status != HAL_SUCCESS) { 142094332d3Sopenharmony_ci return HDF_FAILURE; 143094332d3Sopenharmony_ci } else { 144094332d3Sopenharmony_ci return HDF_SUCCESS; 145094332d3Sopenharmony_ci } 146094332d3Sopenharmony_ci} 147094332d3Sopenharmony_ci 148094332d3Sopenharmony_ciint32_t WifiChip::GetChipModes(std::vector<UsableMode>& modes) 149094332d3Sopenharmony_ci{ 150094332d3Sopenharmony_ci auto chipModes = std::make_shared<WifiChipModes>(vendorHal_); 151094332d3Sopenharmony_ci modes = chipModes->GetChipModes(true); 152094332d3Sopenharmony_ci return HDF_SUCCESS; 153094332d3Sopenharmony_ci} 154094332d3Sopenharmony_ci 155094332d3Sopenharmony_cibool WifiChip::IsValidModeId(uint32_t modeId) 156094332d3Sopenharmony_ci{ 157094332d3Sopenharmony_ci std::vector<UsableMode> modes; 158094332d3Sopenharmony_ci auto chipModes = std::make_shared<WifiChipModes>(vendorHal_); 159094332d3Sopenharmony_ci modes = chipModes->GetChipModes(true); 160094332d3Sopenharmony_ci for (const auto& mode : modes) { 161094332d3Sopenharmony_ci if (mode.modeId == modeId) { 162094332d3Sopenharmony_ci return true; 163094332d3Sopenharmony_ci } 164094332d3Sopenharmony_ci } 165094332d3Sopenharmony_ci return false; 166094332d3Sopenharmony_ci} 167094332d3Sopenharmony_ci 168094332d3Sopenharmony_ciint32_t WifiChip::GetCurrentMode(uint32_t& modeId) 169094332d3Sopenharmony_ci{ 170094332d3Sopenharmony_ci if (!IsValidModeId(currentModeId_)) { 171094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 172094332d3Sopenharmony_ci } 173094332d3Sopenharmony_ci modeId = currentModeId_; 174094332d3Sopenharmony_ci return HDF_SUCCESS; 175094332d3Sopenharmony_ci} 176094332d3Sopenharmony_ci 177094332d3Sopenharmony_ciint32_t WifiChip::SetChipMode(uint32_t modeId) 178094332d3Sopenharmony_ci{ 179094332d3Sopenharmony_ci if (!IsValidModeId(modeId)) { 180094332d3Sopenharmony_ci return HDF_FAILURE; 181094332d3Sopenharmony_ci } 182094332d3Sopenharmony_ci if (modeId == currentModeId_) { 183094332d3Sopenharmony_ci HDF_LOGI("Already in the specified mode, modeId: %{public}d", modeId); 184094332d3Sopenharmony_ci return HDF_SUCCESS; 185094332d3Sopenharmony_ci } 186094332d3Sopenharmony_ci int32_t status = HandleChipConfiguration(modeId); 187094332d3Sopenharmony_ci if (status != ErrorCode::SUCCESS) { 188094332d3Sopenharmony_ci return HDF_FAILURE; 189094332d3Sopenharmony_ci } 190094332d3Sopenharmony_ci currentModeId_ = modeId; 191094332d3Sopenharmony_ci HDF_LOGI("Configured chip in mode, modeId: %{public}d", modeId); 192094332d3Sopenharmony_ci SetUsedIfaceNameProperty(GetUsedIfaceName()); 193094332d3Sopenharmony_ci vendorHal_.lock()->RegisterRestartCallback(subsystemCallbackHandler_); 194094332d3Sopenharmony_ci return HDF_SUCCESS; 195094332d3Sopenharmony_ci} 196094332d3Sopenharmony_ci 197094332d3Sopenharmony_ciint32_t WifiChip::HandleChipConfiguration(int32_t modeId) 198094332d3Sopenharmony_ci{ 199094332d3Sopenharmony_ci std::unique_lock<std::recursive_mutex> lock = AcquireGlobalLock(); 200094332d3Sopenharmony_ci if (IsValidModeId(currentModeId_)) { 201094332d3Sopenharmony_ci HDF_LOGI("Reconfiguring chip from mode %{public}d to mode %{public}d", currentModeId_, modeId); 202094332d3Sopenharmony_ci InvalidateAndClearApIface(apIfaces_); 203094332d3Sopenharmony_ci InvalidateAndClearP2pIface(p2pIfaces_); 204094332d3Sopenharmony_ci InvalidateAndClearStaIface(staIfaces_); 205094332d3Sopenharmony_ci InvalidateAndClearExtIface(extIfaces_); 206094332d3Sopenharmony_ci WifiError status = vendorHal_.lock()->Stop(&lock, []() {}); 207094332d3Sopenharmony_ci if (status != HAL_SUCCESS) { 208094332d3Sopenharmony_ci HDF_LOGE("Failed to stop vendor HAL: %{public}d", status); 209094332d3Sopenharmony_ci return HDF_FAILURE; 210094332d3Sopenharmony_ci } 211094332d3Sopenharmony_ci } 212094332d3Sopenharmony_ci WifiError status = vendorHal_.lock()->Start(); 213094332d3Sopenharmony_ci if (status != HAL_SUCCESS) { 214094332d3Sopenharmony_ci HDF_LOGE("Failed to start vendor HAL: %{public}d", status); 215094332d3Sopenharmony_ci return HDF_FAILURE; 216094332d3Sopenharmony_ci } 217094332d3Sopenharmony_ci return HDF_SUCCESS; 218094332d3Sopenharmony_ci} 219094332d3Sopenharmony_ci 220094332d3Sopenharmony_cistd::vector<std::map<IfaceType, size_t>> WifiChip::ExpandIfaceCombinations( 221094332d3Sopenharmony_ci const ComboIface& combination) 222094332d3Sopenharmony_ci{ 223094332d3Sopenharmony_ci uint32_t numExpandedCombos = 1; 224094332d3Sopenharmony_ci for (const auto& limit : combination.limits) { 225094332d3Sopenharmony_ci for (uint32_t i = 0; i < limit.ifaceNum; i++) { 226094332d3Sopenharmony_ci numExpandedCombos *= limit.types.size(); 227094332d3Sopenharmony_ci } 228094332d3Sopenharmony_ci } 229094332d3Sopenharmony_ci 230094332d3Sopenharmony_ci std::vector<std::map<IfaceType, size_t>> expandedCombos; 231094332d3Sopenharmony_ci expandedCombos.resize(numExpandedCombos); 232094332d3Sopenharmony_ci for (auto& expandedCombo : expandedCombos) { 233094332d3Sopenharmony_ci for (const auto type : { 234094332d3Sopenharmony_ci IfaceType::AP, IfaceType::P2P, IfaceType::STA 235094332d3Sopenharmony_ci }) { 236094332d3Sopenharmony_ci expandedCombo[type] = 0; 237094332d3Sopenharmony_ci } 238094332d3Sopenharmony_ci } 239094332d3Sopenharmony_ci uint32_t span = numExpandedCombos; 240094332d3Sopenharmony_ci for (const auto& limit : combination.limits) { 241094332d3Sopenharmony_ci for (uint32_t i = 0; i < limit.ifaceNum; i++) { 242094332d3Sopenharmony_ci span /= limit.types.size(); 243094332d3Sopenharmony_ci for (uint32_t k = 0; k < numExpandedCombos; ++k) { 244094332d3Sopenharmony_ci const auto ifaceType = 245094332d3Sopenharmony_ci limit.types[(k / span) % limit.types.size()]; 246094332d3Sopenharmony_ci expandedCombos[k][ifaceType]++; 247094332d3Sopenharmony_ci } 248094332d3Sopenharmony_ci } 249094332d3Sopenharmony_ci } 250094332d3Sopenharmony_ci return expandedCombos; 251094332d3Sopenharmony_ci} 252094332d3Sopenharmony_ci 253094332d3Sopenharmony_cistd::map<IfaceType, size_t> WifiChip::GetCurrentIfaceCombo() 254094332d3Sopenharmony_ci{ 255094332d3Sopenharmony_ci std::map<IfaceType, size_t> iface_counts; 256094332d3Sopenharmony_ci iface_counts[IfaceType::AP] = apIfaces_.size(); 257094332d3Sopenharmony_ci iface_counts[IfaceType::P2P] = p2pIfaces_.size(); 258094332d3Sopenharmony_ci iface_counts[IfaceType::STA] = staIfaces_.size(); 259094332d3Sopenharmony_ci return iface_counts; 260094332d3Sopenharmony_ci} 261094332d3Sopenharmony_ci 262094332d3Sopenharmony_cistd::vector<ComboIface> WifiChip::GetCurrentCombinations() 263094332d3Sopenharmony_ci{ 264094332d3Sopenharmony_ci if (!IsValidModeId(currentModeId_)) { 265094332d3Sopenharmony_ci HDF_LOGE("Chip not configured in a mode yet"); 266094332d3Sopenharmony_ci return {}; 267094332d3Sopenharmony_ci } 268094332d3Sopenharmony_ci std::vector<UsableMode> modes; 269094332d3Sopenharmony_ci auto chipModes = std::make_shared<WifiChipModes>(vendorHal_); 270094332d3Sopenharmony_ci modes = chipModes->GetChipModes(true); 271094332d3Sopenharmony_ci for (const auto& mode : modes) { 272094332d3Sopenharmony_ci if (mode.modeId == currentModeId_) { 273094332d3Sopenharmony_ci return mode.usableCombo; 274094332d3Sopenharmony_ci } 275094332d3Sopenharmony_ci } 276094332d3Sopenharmony_ci HDF_LOGE("not find iface combinations for current mode!"); 277094332d3Sopenharmony_ci return {}; 278094332d3Sopenharmony_ci} 279094332d3Sopenharmony_ci 280094332d3Sopenharmony_ci 281094332d3Sopenharmony_cibool WifiChip::CanExpandedIfaceSupportIfaceType( 282094332d3Sopenharmony_ci const std::map<IfaceType, size_t>& expandedCombo, IfaceType type) 283094332d3Sopenharmony_ci{ 284094332d3Sopenharmony_ci const auto currentCombo = GetCurrentIfaceCombo(); 285094332d3Sopenharmony_ci for (const auto ifaceType : {IfaceType::AP, IfaceType::P2P, IfaceType::STA}) { 286094332d3Sopenharmony_ci size_t numIfacesNeeded = currentCombo.at(ifaceType); 287094332d3Sopenharmony_ci if (ifaceType == type) { 288094332d3Sopenharmony_ci numIfacesNeeded++; 289094332d3Sopenharmony_ci } 290094332d3Sopenharmony_ci size_t numIfacesAllowed = expandedCombo.at(ifaceType); 291094332d3Sopenharmony_ci if (numIfacesNeeded > numIfacesAllowed) { 292094332d3Sopenharmony_ci return false; 293094332d3Sopenharmony_ci } 294094332d3Sopenharmony_ci } 295094332d3Sopenharmony_ci return true; 296094332d3Sopenharmony_ci} 297094332d3Sopenharmony_ci 298094332d3Sopenharmony_cibool WifiChip::CanSupportIfaceType(IfaceType type) 299094332d3Sopenharmony_ci{ 300094332d3Sopenharmony_ci if (!IsValidModeId(currentModeId_)) { 301094332d3Sopenharmony_ci HDF_LOGE("Chip not configured in a mode yet"); 302094332d3Sopenharmony_ci return false; 303094332d3Sopenharmony_ci } 304094332d3Sopenharmony_ci const auto combinations = GetCurrentCombinations(); 305094332d3Sopenharmony_ci for (const auto& combination : combinations) { 306094332d3Sopenharmony_ci const auto expandedCombos = ExpandIfaceCombinations(combination); 307094332d3Sopenharmony_ci for (const auto& expandedCombo : expandedCombos) { 308094332d3Sopenharmony_ci if (CanExpandedIfaceSupportIfaceType(expandedCombo, type)) { 309094332d3Sopenharmony_ci return true; 310094332d3Sopenharmony_ci } 311094332d3Sopenharmony_ci } 312094332d3Sopenharmony_ci } 313094332d3Sopenharmony_ci return false; 314094332d3Sopenharmony_ci} 315094332d3Sopenharmony_ci 316094332d3Sopenharmony_cistd::vector<std::string> GetApNames(std::vector<sptr<WifiApIface>>& ifaces) 317094332d3Sopenharmony_ci{ 318094332d3Sopenharmony_ci std::vector<std::string> names; 319094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 320094332d3Sopenharmony_ci names.emplace_back(iface->GetName()); 321094332d3Sopenharmony_ci } 322094332d3Sopenharmony_ci return names; 323094332d3Sopenharmony_ci} 324094332d3Sopenharmony_ci 325094332d3Sopenharmony_cisptr<WifiApIface> FindApUsingName(std::vector<sptr<WifiApIface>>& ifaces, const std::string& name) 326094332d3Sopenharmony_ci{ 327094332d3Sopenharmony_ci std::vector<std::string> names; 328094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 329094332d3Sopenharmony_ci if (name == iface->GetName()) { 330094332d3Sopenharmony_ci return iface; 331094332d3Sopenharmony_ci } 332094332d3Sopenharmony_ci } 333094332d3Sopenharmony_ci return nullptr; 334094332d3Sopenharmony_ci} 335094332d3Sopenharmony_ci 336094332d3Sopenharmony_cistd::vector<std::string> GetP2pNames(std::vector<sptr<WifiP2pIface>>& ifaces) 337094332d3Sopenharmony_ci{ 338094332d3Sopenharmony_ci std::vector<std::string> names; 339094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 340094332d3Sopenharmony_ci names.emplace_back(iface->GetName()); 341094332d3Sopenharmony_ci } 342094332d3Sopenharmony_ci return names; 343094332d3Sopenharmony_ci} 344094332d3Sopenharmony_ci 345094332d3Sopenharmony_cisptr<WifiP2pIface> FindP2pUsingName(std::vector<sptr<WifiP2pIface>>& ifaces, const std::string& name) 346094332d3Sopenharmony_ci{ 347094332d3Sopenharmony_ci std::vector<std::string> names; 348094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 349094332d3Sopenharmony_ci if (name == iface->GetName()) { 350094332d3Sopenharmony_ci return iface; 351094332d3Sopenharmony_ci } 352094332d3Sopenharmony_ci } 353094332d3Sopenharmony_ci return nullptr; 354094332d3Sopenharmony_ci} 355094332d3Sopenharmony_ci 356094332d3Sopenharmony_cistd::vector<std::string> GetStaNames(std::vector<sptr<WifiStaIface>>& ifaces) 357094332d3Sopenharmony_ci{ 358094332d3Sopenharmony_ci std::vector<std::string> names; 359094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 360094332d3Sopenharmony_ci names.emplace_back(iface->GetName()); 361094332d3Sopenharmony_ci } 362094332d3Sopenharmony_ci return names; 363094332d3Sopenharmony_ci} 364094332d3Sopenharmony_ci 365094332d3Sopenharmony_cisptr<WifiStaIface> FindStaUsingName(std::vector<sptr<WifiStaIface>>& ifaces, const std::string& name) 366094332d3Sopenharmony_ci{ 367094332d3Sopenharmony_ci std::vector<std::string> names; 368094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 369094332d3Sopenharmony_ci if (name == iface->GetName()) { 370094332d3Sopenharmony_ci return iface; 371094332d3Sopenharmony_ci } 372094332d3Sopenharmony_ci } 373094332d3Sopenharmony_ci return nullptr; 374094332d3Sopenharmony_ci} 375094332d3Sopenharmony_ci 376094332d3Sopenharmony_cisptr<WifiExtIface> FindExtUsingName(std::vector<sptr<WifiExtIface>>& ifaces, const std::string& name) 377094332d3Sopenharmony_ci{ 378094332d3Sopenharmony_ci std::vector<std::string> names; 379094332d3Sopenharmony_ci for (const auto& iface : ifaces) { 380094332d3Sopenharmony_ci if (name == iface->GetName()) { 381094332d3Sopenharmony_ci return iface; 382094332d3Sopenharmony_ci } 383094332d3Sopenharmony_ci } 384094332d3Sopenharmony_ci return nullptr; 385094332d3Sopenharmony_ci} 386094332d3Sopenharmony_ci 387094332d3Sopenharmony_cistd::string WifiChip::AllocIfaceName(IfaceType type, uint32_t startIdx) 388094332d3Sopenharmony_ci{ 389094332d3Sopenharmony_ci HDF_LOGI("%{public}s: enter AllocIfaceName", __FUNCTION__); 390094332d3Sopenharmony_ci for (unsigned idx = startIdx; idx < K_MAX_WLAN_IFACES; idx++) { 391094332d3Sopenharmony_ci const auto ifname = GetIfaceName(type, idx); 392094332d3Sopenharmony_ci if (FindApUsingName(apIfaces_, ifname)) { 393094332d3Sopenharmony_ci continue; 394094332d3Sopenharmony_ci } 395094332d3Sopenharmony_ci if (FindStaUsingName(staIfaces_, ifname)) { 396094332d3Sopenharmony_ci continue; 397094332d3Sopenharmony_ci } 398094332d3Sopenharmony_ci return ifname; 399094332d3Sopenharmony_ci } 400094332d3Sopenharmony_ci HDF_LOGE("All wlan interfaces in use already!"); 401094332d3Sopenharmony_ci return {}; 402094332d3Sopenharmony_ci} 403094332d3Sopenharmony_ci 404094332d3Sopenharmony_cibool WifiChip::CanExpandedIfaceComboSupportIfaceCombo( 405094332d3Sopenharmony_ci const std::map<IfaceType, size_t>& expandedCombo, 406094332d3Sopenharmony_ci const std::map<IfaceType, size_t>& reqCombo) 407094332d3Sopenharmony_ci{ 408094332d3Sopenharmony_ci for (const auto type : { 409094332d3Sopenharmony_ci IfaceType::AP, IfaceType::P2P, IfaceType::STA 410094332d3Sopenharmony_ci }) { 411094332d3Sopenharmony_ci if (reqCombo.count(type) == 0) { 412094332d3Sopenharmony_ci continue; 413094332d3Sopenharmony_ci } 414094332d3Sopenharmony_ci size_t numIfacesNeeded = reqCombo.at(type); 415094332d3Sopenharmony_ci size_t numIfacesAllowed = expandedCombo.at(type); 416094332d3Sopenharmony_ci if (numIfacesNeeded > numIfacesAllowed) { 417094332d3Sopenharmony_ci return false; 418094332d3Sopenharmony_ci } 419094332d3Sopenharmony_ci } 420094332d3Sopenharmony_ci return true; 421094332d3Sopenharmony_ci} 422094332d3Sopenharmony_ci 423094332d3Sopenharmony_cibool WifiChip::CanCurrentModeSupportIfaceCombo( 424094332d3Sopenharmony_ci const std::map<IfaceType, size_t>& reqCombo) 425094332d3Sopenharmony_ci{ 426094332d3Sopenharmony_ci if (!IsValidModeId(currentModeId_)) { 427094332d3Sopenharmony_ci HDF_LOGE("Chip not configured in a mode yet"); 428094332d3Sopenharmony_ci return false; 429094332d3Sopenharmony_ci } 430094332d3Sopenharmony_ci const auto combinations = GetCurrentCombinations(); 431094332d3Sopenharmony_ci for (const auto& combination : combinations) { 432094332d3Sopenharmony_ci const auto expandedCombos = ExpandIfaceCombinations(combination); 433094332d3Sopenharmony_ci for (const auto& expandedCombo : expandedCombos) { 434094332d3Sopenharmony_ci if (CanExpandedIfaceComboSupportIfaceCombo(expandedCombo, reqCombo)) { 435094332d3Sopenharmony_ci return true; 436094332d3Sopenharmony_ci } 437094332d3Sopenharmony_ci } 438094332d3Sopenharmony_ci } 439094332d3Sopenharmony_ci return false; 440094332d3Sopenharmony_ci} 441094332d3Sopenharmony_ci 442094332d3Sopenharmony_cibool WifiChip::IsDualStaSupportInCurrentMode() 443094332d3Sopenharmony_ci{ 444094332d3Sopenharmony_ci std::map<IfaceType, size_t> reqIfaceCombo; 445094332d3Sopenharmony_ci reqIfaceCombo[IfaceType::STA] = IFACE_TYPE_STA; 446094332d3Sopenharmony_ci return CanCurrentModeSupportIfaceCombo(reqIfaceCombo); 447094332d3Sopenharmony_ci} 448094332d3Sopenharmony_ci 449094332d3Sopenharmony_cibool WifiChip::IsStaApCoexInCurrentMode() 450094332d3Sopenharmony_ci{ 451094332d3Sopenharmony_ci std::map<IfaceType, size_t> reqIfaceCombo; 452094332d3Sopenharmony_ci reqIfaceCombo[IfaceType::AP] = 1; 453094332d3Sopenharmony_ci reqIfaceCombo[IfaceType::STA] = 1; 454094332d3Sopenharmony_ci return CanCurrentModeSupportIfaceCombo(reqIfaceCombo); 455094332d3Sopenharmony_ci} 456094332d3Sopenharmony_ci 457094332d3Sopenharmony_ciuint32_t WifiChip::IdxOfApIface() 458094332d3Sopenharmony_ci{ 459094332d3Sopenharmony_ci if (IsDualStaSupportInCurrentMode()) { 460094332d3Sopenharmony_ci return IFACE_TYPE_STA; 461094332d3Sopenharmony_ci } else if (IsStaApCoexInCurrentMode()) { 462094332d3Sopenharmony_ci return 1; 463094332d3Sopenharmony_ci } 464094332d3Sopenharmony_ci return 0; 465094332d3Sopenharmony_ci} 466094332d3Sopenharmony_ci 467094332d3Sopenharmony_cistd::string WifiChip::AllocateApIfaceName() 468094332d3Sopenharmony_ci{ 469094332d3Sopenharmony_ci bool isCoex; 470094332d3Sopenharmony_ci vendorHal_.lock()->IsSupportCoex(isCoex); 471094332d3Sopenharmony_ci if (isCoex) { 472094332d3Sopenharmony_ci return AP_CODEX_DEFAULT_IFACENAME; 473094332d3Sopenharmony_ci } 474094332d3Sopenharmony_ci return AllocIfaceName(IfaceType::AP, IdxOfApIface()); 475094332d3Sopenharmony_ci} 476094332d3Sopenharmony_ci 477094332d3Sopenharmony_civoid WifiChip::SetUsedIfaceNameProperty(const std::string& ifname) 478094332d3Sopenharmony_ci{ 479094332d3Sopenharmony_ci int res = SetParameter(K_ACTIVE_WLAN_IFACE_NAME_PROPERTY, ifname.c_str()); 480094332d3Sopenharmony_ci if (res != 0) { 481094332d3Sopenharmony_ci HDF_LOGE("Failed to set active wlan iface name property"); 482094332d3Sopenharmony_ci } 483094332d3Sopenharmony_ci} 484094332d3Sopenharmony_ci 485094332d3Sopenharmony_cisptr<WifiApIface> WifiChip::NewApIface(std::string& ifname) 486094332d3Sopenharmony_ci{ 487094332d3Sopenharmony_ci std::vector<std::string> ap_instances; 488094332d3Sopenharmony_ci sptr<WifiApIface> iface = 489094332d3Sopenharmony_ci new WifiApIface(ifname, ap_instances, vendorHal_, ifaceUtil_); 490094332d3Sopenharmony_ci apIfaces_.push_back(iface); 491094332d3Sopenharmony_ci SetUsedIfaceNameProperty(GetUsedIfaceName()); 492094332d3Sopenharmony_ci return iface; 493094332d3Sopenharmony_ci} 494094332d3Sopenharmony_ci 495094332d3Sopenharmony_ciint32_t WifiChip::CreateVirtualApInterface(const std::string& apVirtIf) 496094332d3Sopenharmony_ci{ 497094332d3Sopenharmony_ci WifiError status = vendorHal_.lock()->CreateVirtualInterface( 498094332d3Sopenharmony_ci apVirtIf, HalIfaceType::HAL_TYPE_AP); 499094332d3Sopenharmony_ci if (status != WifiError::HAL_SUCCESS) { 500094332d3Sopenharmony_ci HDF_LOGE("Failed to add interface: %{public}s, error: %{public}d", apVirtIf.c_str(), status); 501094332d3Sopenharmony_ci return HDF_FAILURE; 502094332d3Sopenharmony_ci } 503094332d3Sopenharmony_ci return HDF_SUCCESS; 504094332d3Sopenharmony_ci} 505094332d3Sopenharmony_ci 506094332d3Sopenharmony_ciint32_t WifiChip::CreateApService(sptr<OHOS::HDI::Wlan::Chip::V1_0::IChipIface>& iface) 507094332d3Sopenharmony_ci{ 508094332d3Sopenharmony_ci if (!CanSupportIfaceType(IfaceType::AP)) { 509094332d3Sopenharmony_ci return HDF_FAILURE; 510094332d3Sopenharmony_ci } 511094332d3Sopenharmony_ci std::string ifname = AllocateApIfaceName(); 512094332d3Sopenharmony_ci int32_t status = CreateVirtualApInterface(ifname); 513094332d3Sopenharmony_ci if (status != HDF_SUCCESS) { 514094332d3Sopenharmony_ci return HDF_FAILURE; 515094332d3Sopenharmony_ci } 516094332d3Sopenharmony_ci iface = NewApIface(ifname); 517094332d3Sopenharmony_ci return HDF_SUCCESS; 518094332d3Sopenharmony_ci} 519094332d3Sopenharmony_ci 520094332d3Sopenharmony_ciint32_t WifiChip::GetApServiceIfNames(std::vector<std::string>& ifnames) 521094332d3Sopenharmony_ci{ 522094332d3Sopenharmony_ci if (apIfaces_.empty()) { 523094332d3Sopenharmony_ci return HDF_FAILURE; 524094332d3Sopenharmony_ci } 525094332d3Sopenharmony_ci ifnames = GetApNames(apIfaces_); 526094332d3Sopenharmony_ci return HDF_SUCCESS; 527094332d3Sopenharmony_ci} 528094332d3Sopenharmony_ci 529094332d3Sopenharmony_ciint32_t WifiChip::GetApService(const std::string& ifname, sptr<IChipIface>& iface) 530094332d3Sopenharmony_ci{ 531094332d3Sopenharmony_ci iface = FindApUsingName(apIfaces_, ifname); 532094332d3Sopenharmony_ci if (iface == nullptr) { 533094332d3Sopenharmony_ci return HDF_FAILURE; 534094332d3Sopenharmony_ci } 535094332d3Sopenharmony_ci return HDF_SUCCESS; 536094332d3Sopenharmony_ci} 537094332d3Sopenharmony_ci 538094332d3Sopenharmony_ciint32_t WifiChip::RemoveApService(const std::string& ifname) 539094332d3Sopenharmony_ci{ 540094332d3Sopenharmony_ci const auto iface = FindApUsingName(apIfaces_, ifname); 541094332d3Sopenharmony_ci if (iface == nullptr) { 542094332d3Sopenharmony_ci return HDF_FAILURE; 543094332d3Sopenharmony_ci } 544094332d3Sopenharmony_ci InvalidateAndClearApIface(apIfaces_); 545094332d3Sopenharmony_ci SetUsedIfaceNameProperty(GetUsedIfaceName()); 546094332d3Sopenharmony_ci return HDF_SUCCESS; 547094332d3Sopenharmony_ci} 548094332d3Sopenharmony_ci 549094332d3Sopenharmony_ciint32_t WifiChip::CreateP2pService(sptr<IChipIface>& iface) 550094332d3Sopenharmony_ci{ 551094332d3Sopenharmony_ci if (!CanSupportIfaceType(IfaceType::P2P)) { 552094332d3Sopenharmony_ci return HDF_FAILURE; 553094332d3Sopenharmony_ci } 554094332d3Sopenharmony_ci std::string ifname = GetDefaultP2pIfaceName(); 555094332d3Sopenharmony_ci sptr<WifiP2pIface> ifa = new WifiP2pIface(ifname, vendorHal_, ifaceUtil_); 556094332d3Sopenharmony_ci p2pIfaces_.push_back(ifa); 557094332d3Sopenharmony_ci iface = ifa; 558094332d3Sopenharmony_ci return HDF_SUCCESS; 559094332d3Sopenharmony_ci} 560094332d3Sopenharmony_ci 561094332d3Sopenharmony_cistd::string WifiChip::GetDefaultP2pIfaceName() 562094332d3Sopenharmony_ci{ 563094332d3Sopenharmony_ci return "p2p0"; 564094332d3Sopenharmony_ci} 565094332d3Sopenharmony_ci 566094332d3Sopenharmony_ciint32_t WifiChip::GetP2pServiceIfNames(std::vector<std::string>& ifnames) 567094332d3Sopenharmony_ci{ 568094332d3Sopenharmony_ci if (p2pIfaces_.empty()) { 569094332d3Sopenharmony_ci return HDF_FAILURE; 570094332d3Sopenharmony_ci } 571094332d3Sopenharmony_ci ifnames = GetP2pNames(p2pIfaces_); 572094332d3Sopenharmony_ci return HDF_SUCCESS; 573094332d3Sopenharmony_ci} 574094332d3Sopenharmony_ci 575094332d3Sopenharmony_ciint32_t WifiChip::GetP2pService(const std::string& ifname, sptr<IChipIface>& iface) 576094332d3Sopenharmony_ci{ 577094332d3Sopenharmony_ci iface = FindP2pUsingName(p2pIfaces_, ifname); 578094332d3Sopenharmony_ci if (iface == nullptr) { 579094332d3Sopenharmony_ci return HDF_FAILURE; 580094332d3Sopenharmony_ci } 581094332d3Sopenharmony_ci return HDF_SUCCESS; 582094332d3Sopenharmony_ci} 583094332d3Sopenharmony_ci 584094332d3Sopenharmony_ciint32_t WifiChip::RemoveP2pService(const std::string& ifname) 585094332d3Sopenharmony_ci{ 586094332d3Sopenharmony_ci const auto iface = FindP2pUsingName(p2pIfaces_, ifname); 587094332d3Sopenharmony_ci if (iface == nullptr) { 588094332d3Sopenharmony_ci return HDF_FAILURE; 589094332d3Sopenharmony_ci } 590094332d3Sopenharmony_ci InvalidateAndClearP2pIface(p2pIfaces_); 591094332d3Sopenharmony_ci return HDF_SUCCESS; 592094332d3Sopenharmony_ci} 593094332d3Sopenharmony_ci 594094332d3Sopenharmony_ciint32_t WifiChip::CreateStaService(sptr<IChipIface>& iface) 595094332d3Sopenharmony_ci{ 596094332d3Sopenharmony_ci HDF_LOGI("enter CreateStaService"); 597094332d3Sopenharmony_ci if (!CanSupportIfaceType(IfaceType::STA)) { 598094332d3Sopenharmony_ci HDF_LOGE("%{public}s: Current Mode Not Support Iface Of Type With Current Ifaces", __FUNCTION__); 599094332d3Sopenharmony_ci return HDF_FAILURE; 600094332d3Sopenharmony_ci } 601094332d3Sopenharmony_ci WifiError status; 602094332d3Sopenharmony_ci std::string ifname = AllocateStaIfaceName(); 603094332d3Sopenharmony_ci status = vendorHal_.lock()->CreateVirtualInterface(ifname, 604094332d3Sopenharmony_ci HalIfaceType::HAL_TYPE_STA); 605094332d3Sopenharmony_ci if (status != WifiError::HAL_SUCCESS) { 606094332d3Sopenharmony_ci HDF_LOGE("Failed to add interface: %{public}s, error: %{public}d", ifname.c_str(), status); 607094332d3Sopenharmony_ci return HDF_FAILURE; 608094332d3Sopenharmony_ci } 609094332d3Sopenharmony_ci sptr<WifiStaIface> ifa = new WifiStaIface(ifname, vendorHal_, ifaceUtil_); 610094332d3Sopenharmony_ci staIfaces_.push_back(ifa); 611094332d3Sopenharmony_ci iface = ifa; 612094332d3Sopenharmony_ci SetUsedIfaceNameProperty(GetUsedIfaceName()); 613094332d3Sopenharmony_ci return HDF_SUCCESS; 614094332d3Sopenharmony_ci} 615094332d3Sopenharmony_ci 616094332d3Sopenharmony_cistd::string WifiChip::AllocateStaIfaceName() 617094332d3Sopenharmony_ci{ 618094332d3Sopenharmony_ci return AllocIfaceName(IfaceType::STA, 0); 619094332d3Sopenharmony_ci} 620094332d3Sopenharmony_ci 621094332d3Sopenharmony_ciint32_t WifiChip::GetStaServiceIfNames(std::vector<std::string>& ifnames) 622094332d3Sopenharmony_ci{ 623094332d3Sopenharmony_ci if (staIfaces_.empty()) { 624094332d3Sopenharmony_ci return HDF_FAILURE; 625094332d3Sopenharmony_ci } 626094332d3Sopenharmony_ci ifnames = GetStaNames(staIfaces_); 627094332d3Sopenharmony_ci return HDF_SUCCESS; 628094332d3Sopenharmony_ci} 629094332d3Sopenharmony_ci 630094332d3Sopenharmony_ciint32_t WifiChip::GetStaService(const std::string& ifname, sptr<IChipIface>& iface) 631094332d3Sopenharmony_ci{ 632094332d3Sopenharmony_ci iface = FindStaUsingName(staIfaces_, ifname); 633094332d3Sopenharmony_ci if (iface == nullptr) { 634094332d3Sopenharmony_ci return HDF_FAILURE; 635094332d3Sopenharmony_ci } 636094332d3Sopenharmony_ci return HDF_SUCCESS; 637094332d3Sopenharmony_ci} 638094332d3Sopenharmony_ci 639094332d3Sopenharmony_ciint32_t WifiChip::RemoveStaService(const std::string& ifname) 640094332d3Sopenharmony_ci{ 641094332d3Sopenharmony_ci const auto iface = FindStaUsingName(staIfaces_, ifname); 642094332d3Sopenharmony_ci if (iface == nullptr) { 643094332d3Sopenharmony_ci return HDF_FAILURE; 644094332d3Sopenharmony_ci } 645094332d3Sopenharmony_ci WifiError status = 646094332d3Sopenharmony_ci vendorHal_.lock()->DeleteVirtualInterface(ifname); 647094332d3Sopenharmony_ci if (status != WifiError::HAL_SUCCESS) { 648094332d3Sopenharmony_ci HDF_LOGE("Failed to remove interface: %{public}s, error: %{public}d", ifname.c_str(), status); 649094332d3Sopenharmony_ci } 650094332d3Sopenharmony_ci HDF_LOGI("RemoveStaService Invalidate and erase iface:%{public}s", ifname.c_str()); 651094332d3Sopenharmony_ci iface->Invalidate(); 652094332d3Sopenharmony_ci staIfaces_.erase(std::remove(staIfaces_.begin(), staIfaces_.end(), iface), staIfaces_.end()); 653094332d3Sopenharmony_ci SetUsedIfaceNameProperty(GetUsedIfaceName()); 654094332d3Sopenharmony_ci return HDF_SUCCESS; 655094332d3Sopenharmony_ci} 656094332d3Sopenharmony_ci 657094332d3Sopenharmony_ciint32_t WifiChip::CreateExtService(const std::string& ifName, sptr<IChipIface>& iface) 658094332d3Sopenharmony_ci{ 659094332d3Sopenharmony_ci HDF_LOGI("enter CreateExtService"); 660094332d3Sopenharmony_ci WifiError status = vendorHal_.lock()->CreateVirtualInterface(ifName, HalIfaceType::HAL_TYPE_P2P); 661094332d3Sopenharmony_ci if (status != WifiError::HAL_SUCCESS) { 662094332d3Sopenharmony_ci HDF_LOGE("Failed to add interface: %{public}s, error: %{public}d", ifName.c_str(), status); 663094332d3Sopenharmony_ci return HDF_FAILURE; 664094332d3Sopenharmony_ci } 665094332d3Sopenharmony_ci sptr<WifiExtIface> ifa = new WifiExtIface(ifName, vendorHal_, ifaceUtil_); 666094332d3Sopenharmony_ci extIfaces_.push_back(ifa); 667094332d3Sopenharmony_ci iface = ifa; 668094332d3Sopenharmony_ci return HDF_SUCCESS; 669094332d3Sopenharmony_ci} 670094332d3Sopenharmony_ci 671094332d3Sopenharmony_ciint32_t WifiChip::GetExtService(const std::string& ifName, sptr<IChipIface>& iface) 672094332d3Sopenharmony_ci{ 673094332d3Sopenharmony_ci iface = FindExtUsingName(extIfaces_, ifName); 674094332d3Sopenharmony_ci if (iface == nullptr) { 675094332d3Sopenharmony_ci return HDF_FAILURE; 676094332d3Sopenharmony_ci } 677094332d3Sopenharmony_ci return HDF_SUCCESS; 678094332d3Sopenharmony_ci} 679094332d3Sopenharmony_ci 680094332d3Sopenharmony_ciint32_t WifiChip::RemoveExtService(const std::string& ifName) 681094332d3Sopenharmony_ci{ 682094332d3Sopenharmony_ci const auto iface = FindExtUsingName(extIfaces_, ifName); 683094332d3Sopenharmony_ci if (iface == nullptr) { 684094332d3Sopenharmony_ci return HDF_FAILURE; 685094332d3Sopenharmony_ci } 686094332d3Sopenharmony_ci WifiError status = vendorHal_.lock()->DeleteVirtualInterface(ifName); 687094332d3Sopenharmony_ci if (status != WifiError::HAL_SUCCESS) { 688094332d3Sopenharmony_ci HDF_LOGE("Failed to remove interface: %{public}s, error: %{public}d", ifName.c_str(), status); 689094332d3Sopenharmony_ci } 690094332d3Sopenharmony_ci InvalidateAndClearExtIface(extIfaces_); 691094332d3Sopenharmony_ci return HDF_SUCCESS; 692094332d3Sopenharmony_ci} 693094332d3Sopenharmony_ci 694094332d3Sopenharmony_ci} 695094332d3Sopenharmony_ci} 696094332d3Sopenharmony_ci} 697094332d3Sopenharmony_ci} 698094332d3Sopenharmony_ci}