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