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 <array>
17 #include <chrono>
18 #include <net/if.h>
19 #include <csignal>
20 #include "wifi_vendor_hal.h"
21 #include <hdf_log.h>
22 #include "hdi_sync_util.h"
23 #include "parameter.h"
24 #include "wifi_sta_iface.h"
25
26 static constexpr uint32_t K_MAX_STOP_COMPLETE_WAIT_MS = 1000;
27
28 namespace OHOS {
29 namespace HDI {
30 namespace Wlan {
31 namespace Chip {
32 namespace V1_0 {
33 std::function<void(wifiHandle handle)> onStopCompleteCallback;
34 std::function<void(const char*)> onVendorHalRestartCallback;
35 std::function<void(int)> onFullScanResultCallback;
36
OnAsyncStopComplete(wifiHandle handle)37 void OnAsyncStopComplete(wifiHandle handle)
38 {
39 const auto lock = AcquireGlobalLock();
40 if (onStopCompleteCallback) {
41 onStopCompleteCallback(handle);
42 onStopCompleteCallback = nullptr;
43 }
44 }
45
OnAsyncSubsystemRestart(const char* error)46 void OnAsyncSubsystemRestart(const char* error)
47 {
48 const auto lock = AcquireGlobalLock();
49 if (onVendorHalRestartCallback) {
50 onVendorHalRestartCallback(error);
51 }
52 }
53
54 CallbackHandler<IChipIfaceCallback> WifiVendorHal::vendorHalCbHandler_;
55 CallbackHandler<IChipIfaceCallback> WifiVendorHal::vendorHalExtCbHandler_;
WifiVendorHal( const std::weak_ptr<IfaceTool> ifaceTool, const WifiHalFn& fn, bool isPrimary)56 WifiVendorHal::WifiVendorHal(
57 const std::weak_ptr<IfaceTool> ifaceTool,
58 const WifiHalFn& fn, bool isPrimary)
59 : globalFuncTable_(fn),
60 globalHandle_(nullptr),
61 awaitingEventLoopTermination_(false),
62 isInited_(false),
63 ifaceTool_(ifaceTool),
64 isPrimary_(isPrimary) {
65 }
66
Initialize()67 WifiError WifiVendorHal::Initialize()
68 {
69 HDF_LOGI("Initialize vendor HAL");
70 return HAL_SUCCESS;
71 }
72
Start()73 WifiError WifiVendorHal::Start()
74 {
75 if (!globalFuncTable_.vendorHalInit || globalHandle_ ||
76 !ifaceNameHandle_.empty() || awaitingEventLoopTermination_) {
77 return HAL_UNKNOWN;
78 }
79 if (isInited_) {
80 HDF_LOGI("Vendor HAL already started");
81 return HAL_SUCCESS;
82 }
83 HDF_LOGI("Waiting for the driver ready");
84 WifiError status = globalFuncTable_.waitDriverStart();
85 if (status == HAL_TIMED_OUT || status == HAL_UNKNOWN) {
86 HDF_LOGE("Failed or timed out awaiting driver ready");
87 return status;
88 }
89 HDF_LOGI("Starting vendor HAL");
90 status = globalFuncTable_.vendorHalInit(&globalHandle_);
91 if (status != HAL_SUCCESS || !globalHandle_) {
92 HDF_LOGE("Failed to retrieve global handle");
93 return status;
94 }
95 std::thread(&WifiVendorHal::RunEventLoop, this).detach();
96 status = RetrieveIfaceHandles();
97 if (status != HAL_SUCCESS || ifaceNameHandle_.empty()) {
98 HDF_LOGE("Failed to retrieve wlan interface handle");
99 return status;
100 }
101 HDF_LOGI("Vendor HAL start complete");
102 isInited_ = true;
103 return HAL_SUCCESS;
104 }
105
RunEventLoop()106 void WifiVendorHal::RunEventLoop()
107 {
108 pthread_setname_np(pthread_self(), "VendorHalThread");
109 HDF_LOGD("Starting vendor HAL event loop");
110 globalFuncTable_.startHalLoop(globalHandle_);
111 const auto lock = AcquireGlobalLock();
112 if (!awaitingEventLoopTermination_) {
113 HDF_LOGE("Vendor HAL event loop terminated, but HAL was not stopping");
114 }
115 HDF_LOGD("Vendor HAL event loop terminated");
116 awaitingEventLoopTermination_ = false;
117 stopWaitCv_.notify_one();
118 }
119
OnAsyncGscanFullResult(int event)120 void WifiVendorHal::OnAsyncGscanFullResult(int event)
121 {
122 const auto lock = AcquireGlobalLock();
123
124 HDF_LOGD("OnAsyncGscanFullResult::OnScanResultsCallback");
125 for (const auto& callback : vendorHalCbHandler_.GetCallbacks()) {
126 if (callback) {
127 callback->OnScanResultsCallback(event);
128 }
129 }
130 }
131
OnAsyncRssiReport(int32_t index, int32_t c0Rssi, int32_t c1Rssi)132 void WifiVendorHal::OnAsyncRssiReport(int32_t index, int32_t c0Rssi, int32_t c1Rssi)
133 {
134 const auto lock = AcquireGlobalLock();
135
136 HDF_LOGD("OnAsyncRssiReport::OnRssiReport");
137 for (const auto& callback : vendorHalCbHandler_.GetCallbacks()) {
138 if (callback) {
139 callback->OnRssiReport(index, c0Rssi, c1Rssi);
140 }
141 }
142 }
143
OnAsyncWifiNetlinkMsgReport(uint32_t type, const std::vector<uint8_t>& recvMsg)144 void WifiVendorHal::OnAsyncWifiNetlinkMsgReport(uint32_t type, const std::vector<uint8_t>& recvMsg)
145 {
146 const auto lock = AcquireGlobalLock();
147 HDF_LOGD("OnAsyncWifiNetlinkMsgReport::OnWifiNetlinkMessage");
148 for (const auto& callback : vendorHalExtCbHandler_.GetCallbacks()) {
149 if (callback) {
150 callback->OnWifiNetlinkMessage(type, recvMsg);
151 }
152 }
153 }
154
Stop(std::unique_lock<std::recursive_mutex>* lock, const std::function<void()>& onStopCompleteUserCallback)155 WifiError WifiVendorHal::Stop(std::unique_lock<std::recursive_mutex>* lock,
156 const std::function<void()>& onStopCompleteUserCallback)
157 {
158 if (!isInited_) {
159 HDF_LOGE("Vendor HAL already stopped");
160 onStopCompleteUserCallback();
161 return HAL_SUCCESS;
162 }
163 HDF_LOGD("Stopping vendor HAL");
164 onStopCompleteCallback = [onStopCompleteUserCallback,
165 this](wifiHandle handle) {
166 if (globalHandle_ != handle) {
167 HDF_LOGE("handle mismatch");
168 }
169 HDF_LOGI("Vendor HAL stop complete callback received");
170 Invalidate();
171 if (isPrimary_) ifaceTool_.lock()->SetWifiUpState(false);
172 onStopCompleteUserCallback();
173 isInited_ = false;
174 };
175 awaitingEventLoopTermination_ = true;
176 globalFuncTable_.vendorHalExit(globalHandle_, OnAsyncStopComplete);
177 const auto status = stopWaitCv_.wait_for(
178 *lock, std::chrono::milliseconds(K_MAX_STOP_COMPLETE_WAIT_MS),
179 [this] { return !awaitingEventLoopTermination_; });
180 if (!status) {
181 HDF_LOGE("Vendor HAL stop failed or timed out");
182 return HAL_UNKNOWN;
183 }
184 HDF_LOGE("Vendor HAL stop complete");
185 return HAL_SUCCESS;
186 }
187
GetIfaceHandle(const std::string& ifaceName)188 wifiInterfaceHandle WifiVendorHal::GetIfaceHandle(const std::string& ifaceName)
189 {
190 const auto iface_handle_iter = ifaceNameHandle_.find(ifaceName);
191 if (iface_handle_iter == ifaceNameHandle_.end()) {
192 HDF_LOGE("Unknown iface name: %{public}s", ifaceName.c_str());
193 return nullptr;
194 }
195 return iface_handle_iter->second;
196 }
197
GetChipCaps(const std::string& ifaceName, uint32_t& capabilities)198 WifiError WifiVendorHal::GetChipCaps(const std::string& ifaceName, uint32_t& capabilities)
199 {
200 capabilities = globalFuncTable_.getChipCaps(ifaceName.c_str());
201 if (capabilities == 0) {
202 return HAL_UNKNOWN;
203 }
204 return HAL_SUCCESS;
205 }
206
GetSupportedFeatureSet(const std::string& ifaceName, uint32_t& capabilities)207 WifiError WifiVendorHal::GetSupportedFeatureSet(const std::string& ifaceName, uint32_t& capabilities)
208 {
209 capabilities = globalFuncTable_.wifiGetSupportedFeatureSet(ifaceName.c_str());
210 if (capabilities == 0) {
211 return HAL_UNKNOWN;
212 }
213 return HAL_SUCCESS;
214 }
215
GetValidFrequenciesForBand( const std::string& ifaceName, int band)216 std::pair<WifiError, std::vector<uint32_t>>WifiVendorHal::GetValidFrequenciesForBand(
217 const std::string& ifaceName, int band)
218 {
219 std::vector<uint32_t> freqs;
220
221 WifiError status = globalFuncTable_.vendorHalGetChannelsInBand(
222 GetIfaceHandle(ifaceName), band, freqs);
223 return {status, std::move(freqs)};
224 }
225
CreateVirtualInterface(const std::string& ifname, HalIfaceType iftype)226 WifiError WifiVendorHal::CreateVirtualInterface(const std::string& ifname, HalIfaceType iftype)
227 {
228 WifiError status = globalFuncTable_.vendorHalCreateIface(
229 globalHandle_, ifname.c_str(), iftype);
230 status = HandleIfaceChangeStatus(ifname, status);
231 if (status == HAL_SUCCESS && iftype == HalIfaceType::HAL_TYPE_STA) {
232 ifaceTool_.lock()->SetUpState(ifname.c_str(), true);
233 }
234 return status;
235 }
236
DeleteVirtualInterface(const std::string& ifname)237 WifiError WifiVendorHal::DeleteVirtualInterface(const std::string& ifname)
238 {
239 WifiError status = globalFuncTable_.vendorHalDeleteIface(
240 globalHandle_, ifname.c_str());
241 return HandleIfaceChangeStatus(ifname, status);
242 }
243
HandleIfaceChangeStatus( const std::string& ifname, WifiError status)244 WifiError WifiVendorHal::HandleIfaceChangeStatus(
245 const std::string& ifname, WifiError status)
246 {
247 if (status == HAL_SUCCESS) {
248 status = RetrieveIfaceHandles();
249 } else if (status == HAL_NOT_SUPPORTED) {
250 if (if_nametoindex(ifname.c_str())) {
251 status = RetrieveIfaceHandles();
252 }
253 }
254 return status;
255 }
256
RetrieveIfaceHandles()257 WifiError WifiVendorHal::RetrieveIfaceHandles()
258 {
259 wifiInterfaceHandle* ifaceHandles = nullptr;
260 int numIfaceHandles = 0;
261 WifiError status = globalFuncTable_.vendorHalGetIfaces(
262 globalHandle_, &numIfaceHandles, &ifaceHandles);
263 if (status != HAL_SUCCESS) {
264 HDF_LOGE("Failed to enumerate interface handles");
265 return status;
266 }
267 ifaceNameHandle_.clear();
268 for (int i = 0; i < numIfaceHandles; ++i) {
269 std::array<char, IFNAMSIZ> iface_name_arr = {};
270 status = globalFuncTable_.vendorHalGetIfName(
271 ifaceHandles[i], iface_name_arr.data(), iface_name_arr.size());
272 if (status != HAL_SUCCESS) {
273 HDF_LOGE("Failed to get interface handle name");
274 continue;
275 }
276 std::string ifaceName(iface_name_arr.data());
277 HDF_LOGI("Adding interface handle for %{public}s", ifaceName.c_str());
278 ifaceNameHandle_[ifaceName] = ifaceHandles[i];
279 }
280 return HAL_SUCCESS;
281 }
282
RegisterRestartCallback( const OnVendorHalRestartCallback& onRestartCallback)283 WifiError WifiVendorHal::RegisterRestartCallback(
284 const OnVendorHalRestartCallback& onRestartCallback)
285 {
286 if (onVendorHalRestartCallback) {
287 return HAL_NOT_AVAILABLE;
288 }
289 onVendorHalRestartCallback =
290 [onRestartCallback](const char* error) {
291 onRestartCallback(error);
292 };
293 WifiError status = globalFuncTable_.vendorHalSetRestartHandler(
294 globalHandle_, {OnAsyncSubsystemRestart});
295 if (status != HAL_SUCCESS) {
296 onVendorHalRestartCallback = nullptr;
297 }
298 return status;
299 }
300
Invalidate()301 void WifiVendorHal::Invalidate()
302 {
303 globalHandle_ = nullptr;
304 ifaceNameHandle_.clear();
305 vendorHalCbHandler_.Invalidate();
306 vendorHalExtCbHandler_.Invalidate();
307 }
308
SetCountryCode(const std::string& ifaceName, const std::string& code)309 WifiError WifiVendorHal::SetCountryCode(const std::string& ifaceName, const std::string& code)
310 {
311 return globalFuncTable_.wifiSetCountryCode(GetIfaceHandle(ifaceName), code.c_str());
312 }
313
GetSignalPollInfo(const std::string& ifaceName, SignalPollResult& signalPollResult)314 WifiError WifiVendorHal::GetSignalPollInfo(const std::string& ifaceName,
315 SignalPollResult& signalPollResult)
316 {
317 return globalFuncTable_.getSignalPollInfo(GetIfaceHandle(ifaceName), signalPollResult);
318 }
319
GetPowerMode(const std::string& ifaceName)320 std::pair<WifiError, int> WifiVendorHal::GetPowerMode(const std::string& ifaceName)
321 {
322 int mode;
323 WifiError status = globalFuncTable_.getPowerMode(ifaceName.c_str(), &mode);
324 return {status, mode};
325 }
326
SetPowerMode(const std::string& ifaceName, int mode)327 WifiError WifiVendorHal::SetPowerMode(const std::string& ifaceName, int mode)
328 {
329 return globalFuncTable_.setPowerMode(ifaceName.c_str(), mode);
330 }
331
IsSupportCoex(bool& isCoex)332 WifiError WifiVendorHal::IsSupportCoex(bool& isCoex)
333 {
334 return globalFuncTable_.isSupportCoex(isCoex);
335 }
336
EnablePowerMode(const std::string& ifaceName, int mode)337 WifiError WifiVendorHal::EnablePowerMode(const std::string& ifaceName, int mode)
338 {
339 return globalFuncTable_.enablePowerMode(ifaceName.c_str(), mode);
340 }
341
StartScan( const std::string& ifaceName, const ScanParams& params)342 WifiError WifiVendorHal::StartScan(
343 const std::string& ifaceName, const ScanParams& params)
344 {
345 WifiError status = globalFuncTable_.wifiStartScan(GetIfaceHandle(ifaceName), params);
346 return status;
347 }
348
StartPnoScan(const std::string& ifaceName, const PnoScanParams& pnoParams)349 WifiError WifiVendorHal::StartPnoScan(const std::string& ifaceName, const PnoScanParams& pnoParams)
350 {
351 WifiError status = globalFuncTable_.wifiStartPnoScan(GetIfaceHandle(ifaceName), pnoParams);
352 return status;
353 }
354
StopPnoScan(const std::string& ifaceName)355 WifiError WifiVendorHal::StopPnoScan(const std::string& ifaceName)
356 {
357 WifiError status = globalFuncTable_.wifiStopPnoScan(GetIfaceHandle(ifaceName));
358 return status;
359 }
360
GetScanInfos(const std::string& ifaceName, std::vector<ScanResultsInfo>& scanResultsInfo)361 WifiError WifiVendorHal::GetScanInfos(const std::string& ifaceName,
362 std::vector<ScanResultsInfo>& scanResultsInfo)
363 {
364 WifiError status = globalFuncTable_.getScanResults(GetIfaceHandle(ifaceName), scanResultsInfo);
365 return status;
366 }
367
SetDpiMarkRule(int32_t uid, int32_t protocol, int32_t enable)368 WifiError WifiVendorHal::SetDpiMarkRule(int32_t uid, int32_t protocol, int32_t enable)
369 {
370 return globalFuncTable_.setDpiMarkRule(uid, protocol, enable);
371 }
372
RegisterIfaceCallBack(const std::string& ifaceName, const sptr<IChipIfaceCallback>& chipIfaceCallback)373 WifiError WifiVendorHal::RegisterIfaceCallBack(const std::string& ifaceName,
374 const sptr<IChipIfaceCallback>& chipIfaceCallback)
375 {
376 vendorHalCbHandler_.AddCallback(chipIfaceCallback);
377 WifiCallbackHandler handler = {OnAsyncGscanFullResult, OnAsyncRssiReport};
378 globalFuncTable_.registerIfaceCallBack(ifaceName.c_str(), handler);
379 return HAL_SUCCESS;
380 }
381
UnRegisterIfaceCallBack(const std::string& ifaceName, const sptr<IChipIfaceCallback>& chipIfaceCallback)382 WifiError WifiVendorHal::UnRegisterIfaceCallBack(const std::string& ifaceName,
383 const sptr<IChipIfaceCallback>& chipIfaceCallback)
384 {
385 WifiCallbackHandler handler = {};
386 globalFuncTable_.registerIfaceCallBack(ifaceName.c_str(), handler);
387 vendorHalCbHandler_.Invalidate(); // instead of RemoveCallback temporarily
388 return HAL_SUCCESS;
389 }
390
RegisterExtIfaceCallBack(const std::string& ifaceName, const sptr<IChipIfaceCallback>& chipIfaceCallback)391 WifiError WifiVendorHal::RegisterExtIfaceCallBack(const std::string& ifaceName,
392 const sptr<IChipIfaceCallback>& chipIfaceCallback)
393 {
394 vendorHalExtCbHandler_.AddCallback(chipIfaceCallback);
395 WifiExtCallbackHandler handler = {OnAsyncWifiNetlinkMsgReport};
396 globalFuncTable_.registerExtIfaceCallBack(ifaceName.c_str(), handler);
397 return HAL_SUCCESS;
398 }
399
UnRegisterExtIfaceCallBack(const std::string& ifaceName, const sptr<IChipIfaceCallback>& chipIfaceCallback)400 WifiError WifiVendorHal::UnRegisterExtIfaceCallBack(const std::string& ifaceName,
401 const sptr<IChipIfaceCallback>& chipIfaceCallback)
402 {
403 WifiExtCallbackHandler handler = {};
404 globalFuncTable_.registerExtIfaceCallBack(ifaceName.c_str(), handler);
405 vendorHalExtCbHandler_.Invalidate(); // instead of RemoveCallback temporarily
406 return HAL_SUCCESS;
407 }
408
SetTxPower(const std::string& ifaceName, int mode)409 WifiError WifiVendorHal::SetTxPower(const std::string& ifaceName, int mode)
410 {
411 return globalFuncTable_.setTxPower(ifaceName.c_str(), mode);
412 }
413
SendCmdToDriver(const std::string& ifaceName, int32_t cmdId, const std::vector<int8_t>& paramBuf)414 WifiError WifiVendorHal::SendCmdToDriver(const std::string& ifaceName, int32_t cmdId,
415 const std::vector<int8_t>& paramBuf)
416 {
417 return globalFuncTable_.sendCmdToDriver(ifaceName.c_str(), cmdId, paramBuf);
418 }
419
SendActionFrame(const std::string& ifaceName, uint32_t freq, const std::vector<uint8_t>& frameData)420 WifiError WifiVendorHal::SendActionFrame(const std::string& ifaceName, uint32_t freq,
421 const std::vector<uint8_t>& frameData)
422 {
423 return globalFuncTable_.sendActionFrame(GetIfaceHandle(ifaceName), freq, frameData);
424 }
425
RegisterActionFrameReceiver(const std::string& ifaceName, const std::vector<uint8_t>& match)426 WifiError WifiVendorHal::RegisterActionFrameReceiver(const std::string& ifaceName, const std::vector<uint8_t>& match)
427 {
428 return globalFuncTable_.registerActionFrameReceiver(GetIfaceHandle(ifaceName), match);
429 }
430
GetCoexictenceChannelList(const std::string& ifaceName, std::vector<uint8_t>& paramBuf)431 WifiError WifiVendorHal::GetCoexictenceChannelList(const std::string& ifaceName, std::vector<uint8_t>& paramBuf)
432 {
433 return globalFuncTable_.getCoexictenceChannelList(ifaceName, paramBuf);
434 }
435
436 } // namespace v1_0
437 } // namespace Chip
438 } // namespace Wlan
439 } // namespace HDI
440 } // namespace OHOS