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