1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "wifi.h"
17 #include <hdf_base.h>
18 #include <hdf_log.h>
19 #include "wifi_hal.h"
20 #include "hdi_sync_util.h"
21 #include "iproxy_broker.h"
22 
23 namespace OHOS {
24 namespace HDI {
25 namespace Wlan {
26 namespace Chip {
27 namespace V1_0 {
28 #ifdef FEATURE_ANCO_WIFI
29 const int CHIP_ID_STA = 1;
30 const int CHIP_ID_P2P = 2;
31 const int CHIP_ID_AP = 3;
32 #endif
33 
34 static constexpr int32_t K_PRIMARY_CHIP_ID = 0;
35 
ChipControllerImplGetInstance(void)36 extern "C" IChipController *ChipControllerImplGetInstance(void)
37 {
38     return new (std::nothrow) Wifi();
39 }
40 
Wifi()41 Wifi::Wifi()
42     :ifaceTool_(std::make_shared<IfaceTool>()),
43     vendorHalList_(std::make_shared<WifiVendorHalList>(ifaceTool_)),
44     runState_(RunState::STOPPED) {
45     remoteDeathRecipient_ =
46         new RemoteDeathRecipient(std::bind(&Wifi::OnRemoteDied, this, std::placeholders::_1));
47 }
48 
~Wifi()49 Wifi::~Wifi()
50 {
51     for (const auto& callback : cbHandler_.GetCallbacks()) {
52         if (callback != nullptr) {
53             RemoveWifiDeathRecipient(callback);
54         }
55     }
56     cbHandler_.Invalidate();
57 }
58 
RegisterWifiEventCallback(const sptr<IChipControllerCallback> & eventCallback)59 int32_t Wifi::RegisterWifiEventCallback(const sptr<IChipControllerCallback>& eventCallback)
60 {
61     if (cbHandler_.GetCallbacks().empty()) {
62         AddWifiDeathRecipient(eventCallback);
63     }
64 
65     if (!cbHandler_.AddCallback(eventCallback)) {
66         return HDF_FAILURE;
67     }
68     return HDF_SUCCESS;
69 }
70 
IsInit(bool & inited)71 int32_t Wifi::IsInit(bool& inited)
72 {
73     inited = runState_ != RunState::STOPPED;
74     return HDF_SUCCESS;
75 }
76 
Init()77 int32_t Wifi::Init()
78 {
79     HDF_LOGI("Wifi HAL start enter");
80     if (runState_ == RunState::STARTED) {
81         return HDF_SUCCESS;
82     } else if (runState_ == RunState::STOPPING) {
83         return HDF_FAILURE;
84     }
85     ErrorCode res = InitializVendorHal();
86     if (res == ErrorCode::SUCCESS) {
87         const auto& onVendorHalRestartCallback =
88             [this](const std::string& error) {
89             ErrorCode res = ErrorCode::UNKNOWN;
90             for (const auto& callback : cbHandler_.GetCallbacks()) {
91                 callback->OnVendorHalRestart(res);
92             }
93         };
94 
95         int32_t chipId = K_PRIMARY_CHIP_ID;
96         for (auto& hal : vendorHals_) {
97             chips_.push_back(new WifiChip(
98                 chipId, chipId == K_PRIMARY_CHIP_ID, hal,
99                 std::make_shared<IfaceUtil>(ifaceTool_),
100                 onVendorHalRestartCallback));
101             chipId++;
102         }
103         runState_ = RunState::STARTED;
104         HDF_LOGI("Wifi HAL started");
105         return HDF_SUCCESS;
106     } else {
107         HDF_LOGE("Wifi HAL start failed.");
108         return HDF_FAILURE;
109     }
110 }
111 
Release()112 int32_t Wifi::Release()
113 {
114     if (runState_ == RunState::STOPPED) {
115         return HDF_SUCCESS;
116     } else if (runState_ == RunState::STOPPING) {
117         return HDF_SUCCESS;
118     }
119     for (auto& chip : chips_) {
120         if (chip) {
121             chip->Invalidate();
122         }
123     }
124     chips_.clear();
125     auto lock = AcquireGlobalLock();
126     ErrorCode res = StopVendorHal(&lock);
127     if (res == ErrorCode::SUCCESS) {
128         return HDF_SUCCESS;
129         HDF_LOGI("Wifi HAL stopped");
130     } else {
131         return HDF_FAILURE;
132         HDF_LOGE("Wifi HAL stop failed");
133     }
134 }
135 
GetAvailableChips(std::vector<uint32_t> & chipIds)136 int32_t Wifi::GetAvailableChips(std::vector<uint32_t>& chipIds)
137 {
138     for (auto& chip : chips_) {
139         uint32_t chipId = GetChipIdFromWifiChip(chip);
140         if (chipId != UINT32_MAX) chipIds.emplace_back(chipId);
141     }
142 #ifdef FEATURE_ANCO_WIFI
143     if (chipIds.empty()) {
144         chipIds.emplace_back(CHIP_ID_STA);
145         chipIds.emplace_back(CHIP_ID_P2P);
146         chipIds.emplace_back(CHIP_ID_AP);
147     }
148 #endif
149     return HDF_SUCCESS;
150 }
151 
GetChipService(uint32_t chipId,sptr<IConcreteChip> & chip)152 int32_t Wifi::GetChipService(uint32_t chipId, sptr<IConcreteChip>& chip)
153 {
154     for (auto& ch : chips_) {
155         uint32_t cand_id = GetChipIdFromWifiChip(ch);
156         if ((cand_id != UINT32_MAX) && (cand_id == chipId)) {
157             chip = ch;
158             return HDF_SUCCESS;
159         }
160     }
161     chip = nullptr;
162     return HDF_FAILURE;
163 }
164 
StopVendorHal(std::unique_lock<std::recursive_mutex> * lock)165 ErrorCode Wifi::StopVendorHal(std::unique_lock<std::recursive_mutex>* lock)
166 {
167     WifiError legacyStatus = HAL_SUCCESS;
168     int index = 0;
169     ErrorCode res;
170 
171     runState_ = RunState::STOPPING;
172     for (auto& hal : vendorHals_) {
173         WifiError tmp = hal->Stop(lock, [&]() {});
174         if (tmp != HAL_SUCCESS) {
175             HDF_LOGE("Failed to stop vendor hal index: %{public}d, error %{public}d", index, tmp);
176             legacyStatus = tmp;
177         }
178         index++;
179     }
180     runState_ = RunState::STOPPED;
181 
182     if (legacyStatus != HAL_SUCCESS) {
183         HDF_LOGE("One or more vendor hals failed to stop error is %{public}d", legacyStatus);
184         res = ErrorCode::UNKNOWN;
185         return res;
186     }
187     res = ErrorCode::SUCCESS;
188     return res;
189 }
190 
InitializVendorHal()191 ErrorCode Wifi::InitializVendorHal()
192 {
193     ErrorCode res;
194 
195     vendorHals_ = vendorHalList_->GetHals();
196     if (vendorHals_.empty()) {
197         res = ErrorCode::UNKNOWN;
198         return res;
199     }
200     int index = 0;
201     for (auto& hal : vendorHals_) {
202         WifiError legacyStatus = hal->Initialize();
203         if (legacyStatus != HAL_SUCCESS) {
204             res = ErrorCode::UNKNOWN;
205             return res;
206         }
207         index++;
208     }
209 
210     res = ErrorCode::SUCCESS;
211     return res;
212 }
213 
GetChipIdFromWifiChip(sptr<WifiChip> & chip)214 uint32_t Wifi::GetChipIdFromWifiChip(sptr <WifiChip>& chip)
215 {
216     uint32_t chipId = UINT32_MAX;
217     int32_t id;
218 
219     if (chip) {
220         chip->GetChipId(id);
221         chipId = static_cast<uint32_t>(id);
222     }
223     return chipId;
224 }
225 
OnRemoteDied(const wptr<IRemoteObject> & object)226 void Wifi::OnRemoteDied(const wptr<IRemoteObject> &object)
227 {
228     HDF_LOGI("chip service OnRemoteDied");
229     runState_ = RunState::STOPPING;
230     cbHandler_.Invalidate();
231     for (auto& chip : chips_) {
232         if (chip) {
233             chip->Invalidate();
234         }
235     }
236     chips_.clear();
237     auto lock = AcquireGlobalLock();
238     StopVendorHal(&lock);
239     runState_ = RunState::STOPPED;
240 }
241 
AddWifiDeathRecipient(const sptr<IChipControllerCallback> & eventCallback)242 int32_t Wifi::AddWifiDeathRecipient(const sptr<IChipControllerCallback>& eventCallback)
243 {
244     HDF_LOGI("AddWifiDeathRecipient");
245     const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IChipControllerCallback>(eventCallback);
246     bool result = remote->AddDeathRecipient(remoteDeathRecipient_);
247     if (!result) {
248         HDF_LOGE("Wifi AddDeathRecipient fail");
249         return HDF_FAILURE;
250     }
251     return HDF_SUCCESS;
252 }
253 
RemoveWifiDeathRecipient(const sptr<IChipControllerCallback> & eventCallback)254 int32_t Wifi::RemoveWifiDeathRecipient(const sptr<IChipControllerCallback>& eventCallback)
255 {
256     HDF_LOGI("RemoveWifiDeathRecipient");
257     const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IChipControllerCallback>(eventCallback);
258     bool result = remote->RemoveDeathRecipient(remoteDeathRecipient_);
259     if (!result) {
260         HDF_LOGE("Wifi RemoveDeathRecipient fail");
261         return HDF_FAILURE;
262     }
263     return HDF_SUCCESS;
264 }
265 
266 } // namespace V1_0
267 } // namespace Chip
268 } // namespace Wlan
269 } // namespace HDI
270 } // namespace OHOS