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}