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 chipModes_(std::make_shared<WifiChipModes>()),
45 runState_(RunState::STOPPED) {
46 remoteDeathRecipient_ =
47 new RemoteDeathRecipient(std::bind(&Wifi::OnRemoteDied, this, std::placeholders::_1));
48 }
49
~Wifi()50 Wifi::~Wifi()
51 {
52 for (const auto& callback : cbHandler_.GetCallbacks()) {
53 if (callback != nullptr) {
54 RemoveWifiDeathRecipient(callback);
55 }
56 }
57 cbHandler_.Invalidate();
58 }
59
RegisterWifiEventCallback(const sptr<IChipControllerCallback> & eventCallback)60 int32_t Wifi::RegisterWifiEventCallback(const sptr<IChipControllerCallback>& eventCallback)
61 {
62 if (AddWifiDeathRecipient(eventCallback) != HDF_SUCCESS) {
63 return HDF_FAILURE;
64 }
65
66 if (!cbHandler_.AddCallback(eventCallback)) {
67 return HDF_FAILURE;
68 }
69 return HDF_SUCCESS;
70 }
71
IsInit(bool & inited)72 int32_t Wifi::IsInit(bool& inited)
73 {
74 inited = runState_ != RunState::STOPPED;
75 return HDF_SUCCESS;
76 }
77
Init()78 int32_t Wifi::Init()
79 {
80 HDF_LOGI("Wifi HAL start enter");
81 if (runState_ == RunState::STARTED) {
82 return HDF_SUCCESS;
83 } else if (runState_ == RunState::STOPPING) {
84 return HDF_FAILURE;
85 }
86 ErrorCode res = InitializVendorHal();
87 if (res == ErrorCode::SUCCESS) {
88 const auto& onVendorHalRestartCallback =
89 [this](const std::string& error) {
90 ErrorCode res = ErrorCode::UNKNOWN;
91 for (const auto& callback : cbHandler_.GetCallbacks()) {
92 callback->OnVendorHalRestart(res);
93 }
94 };
95
96 int32_t chipId = K_PRIMARY_CHIP_ID;
97 for (auto& hal : vendorHals_) {
98 chips_.push_back(new WifiChip(
99 chipId, chipId == K_PRIMARY_CHIP_ID, hal,
100 std::make_shared<IfaceUtil>(ifaceTool_),
101 chipModes_, onVendorHalRestartCallback));
102 chipId++;
103 }
104 runState_ = RunState::STARTED;
105 HDF_LOGI("Wifi HAL started");
106 return HDF_SUCCESS;
107 } else {
108 HDF_LOGE("Wifi HAL start failed");
109 return HDF_FAILURE;
110 }
111 }
112
Release()113 int32_t Wifi::Release()
114 {
115 if (runState_ == RunState::STOPPED) {
116 return HDF_SUCCESS;
117 } else if (runState_ == RunState::STOPPING) {
118 return HDF_SUCCESS;
119 }
120 for (auto& chip : chips_) {
121 if (chip) {
122 chip->Invalidate();
123 }
124 }
125 chips_.clear();
126 auto lock = AcquireGlobalLock();
127 ErrorCode res = StopVendorHal(&lock);
128 if (res == ErrorCode::SUCCESS) {
129 return HDF_SUCCESS;
130 HDF_LOGI("Wifi HAL stopped");
131 } else {
132 return HDF_FAILURE;
133 HDF_LOGE("Wifi HAL stop failed");
134 }
135 }
136
GetAvailableChips(std::vector<uint32_t> & chipIds)137 int32_t Wifi::GetAvailableChips(std::vector<uint32_t>& chipIds)
138 {
139 for (auto& chip : chips_) {
140 int32_t chipId = GetChipIdFromWifiChip(chip);
141 if (chipId != UINT32_MAX) chipIds.emplace_back(chipId);
142 }
143 #ifdef FEATURE_ANCO_WIFI
144 if (chipIds.empty()) {
145 chipIds.emplace_back(CHIP_ID_STA);
146 chipIds.emplace_back(CHIP_ID_P2P);
147 chipIds.emplace_back(CHIP_ID_AP);
148 }
149 #endif
150 return HDF_SUCCESS;
151 }
152
GetChipService(uint32_t chipId,sptr<IConcreteChip> & chip)153 int32_t Wifi::GetChipService(uint32_t chipId, sptr<IConcreteChip>& chip)
154 {
155 for (auto& ch : chips_) {
156 uint32_t cand_id = GetChipIdFromWifiChip(ch);
157 if ((cand_id != UINT32_MAX) && (cand_id == chipId)) {
158 chip = ch;
159 return HDF_SUCCESS;
160 }
161 }
162 chip = nullptr;
163 return HDF_FAILURE;
164 }
165
StopVendorHal(std::unique_lock<std::recursive_mutex> * lock)166 ErrorCode Wifi::StopVendorHal(std::unique_lock<std::recursive_mutex>* lock)
167 {
168 WifiError legacyStatus = HAL_SUCCESS;
169 int index = 0;
170 ErrorCode res;
171
172 runState_ = RunState::STOPPING;
173 for (auto& hal : vendorHals_) {
174 WifiError tmp = hal->Stop(lock, [&]() {});
175 if (tmp != HAL_SUCCESS) {
176 HDF_LOGE("Failed to stop vendor hal index: %{public}d, error %{public}d", index, tmp);
177 legacyStatus = tmp;
178 }
179 index++;
180 }
181 runState_ = RunState::STOPPED;
182
183 if (legacyStatus != HAL_SUCCESS) {
184 HDF_LOGE("One or more vendor hals failed to stop error is %{public}d", legacyStatus);
185 res = ErrorCode::UNKNOWN;
186 return res;
187 }
188 res = ErrorCode::SUCCESS;
189 return res;
190 }
191
InitializVendorHal()192 ErrorCode Wifi::InitializVendorHal()
193 {
194 ErrorCode res;
195
196 vendorHals_ = vendorHalList_->GetHals();
197 if (vendorHals_.empty()) {
198 res = ErrorCode::UNKNOWN;
199 return res;
200 }
201 int index = 0;
202 for (auto& hal : vendorHals_) {
203 WifiError legacyStatus = hal->Initialize();
204 if (legacyStatus != HAL_SUCCESS) {
205 res = ErrorCode::UNKNOWN;
206 return res;
207 }
208 index++;
209 }
210
211 res = ErrorCode::SUCCESS;
212 return res;
213 }
214
GetChipIdFromWifiChip(sptr<WifiChip> & chip)215 int32_t Wifi::GetChipIdFromWifiChip(sptr <WifiChip>& chip)
216 {
217 int chipId = UINT32_MAX;
218 int32_t id;
219
220 if (chip) {
221 chip->GetChipId(id);
222 chipId = id;
223 }
224 return chipId;
225 }
226
OnRemoteDied(const wptr<IRemoteObject> & object)227 void Wifi::OnRemoteDied(const wptr<IRemoteObject> &object)
228 {
229 HDF_LOGI("chip service OnRemoteDied");
230 runState_ = RunState::STOPPING;
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