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
148 HDF_LOGD("OnAsyncWifiNetlinkMsgReport::OnWifiNetlinkMessage");
149 for (const auto& callback : vendorHalCbHandler_.GetCallbacks()) {
150 if (callback) {
151 callback->OnWifiNetlinkMessage(type, recvMsg);
152 }
153 }
154 }
155
OnAsyncWifiNetlinkMsgExtReport(uint32_t type,const std::vector<uint8_t> & recvMsg)156 void WifiVendorHal::OnAsyncWifiNetlinkMsgExtReport(uint32_t type, const std::vector<uint8_t>& recvMsg)
157 {
158 const auto lock = AcquireGlobalLock();
159
160 HDF_LOGD("OnAsyncWifiNetlinkMsgExtReport::OnWifiNetlinkMessage");
161 for (const auto& callback : vendorHalExtCbHandler_.GetCallbacks()) {
162 if (callback) {
163 callback->OnWifiNetlinkMessage(type, recvMsg);
164 }
165 }
166 }
167
Stop(std::unique_lock<std::recursive_mutex> * lock,const std::function<void ()> & onStopCompleteUserCallback)168 WifiError WifiVendorHal::Stop(std::unique_lock<std::recursive_mutex>* lock,
169 const std::function<void()>& onStopCompleteUserCallback)
170 {
171 if (!isInited_) {
172 HDF_LOGE("Vendor HAL already stopped");
173 onStopCompleteUserCallback();
174 return HAL_SUCCESS;
175 }
176 HDF_LOGD("Stopping vendor HAL");
177 onStopCompleteCallback = [onStopCompleteUserCallback,
178 this](wifiHandle handle) {
179 if (globalHandle_ != handle) {
180 HDF_LOGE("handle mismatch");
181 }
182 HDF_LOGI("Vendor HAL stop complete callback received");
183 Invalidate();
184 if (isPrimary_) ifaceTool_.lock()->SetWifiUpState(false);
185 onStopCompleteUserCallback();
186 isInited_ = false;
187 };
188 awaitingEventLoopTermination_ = true;
189 globalFuncTable_.vendorHalExit(globalHandle_, OnAsyncStopComplete);
190 const auto status = stopWaitCv_.wait_for(
191 *lock, std::chrono::milliseconds(K_MAX_STOP_COMPLETE_WAIT_MS),
192 [this] { return !awaitingEventLoopTermination_; });
193 if (!status) {
194 HDF_LOGE("Vendor HAL stop failed or timed out");
195 return HAL_UNKNOWN;
196 }
197 HDF_LOGE("Vendor HAL stop complete");
198 return HAL_SUCCESS;
199 }
200
GetIfaceHandle(const std::string & ifaceName)201 wifiInterfaceHandle WifiVendorHal::GetIfaceHandle(const std::string& ifaceName)
202 {
203 const auto iface_handle_iter = ifaceNameHandle_.find(ifaceName);
204 if (iface_handle_iter == ifaceNameHandle_.end()) {
205 HDF_LOGE("Unknown iface name: %{public}s", ifaceName.c_str());
206 return nullptr;
207 }
208 return iface_handle_iter->second;
209 }
210
GetChipCaps(const std::string & ifaceName,uint32_t & capabilities)211 WifiError WifiVendorHal::GetChipCaps(const std::string& ifaceName, uint32_t& capabilities)
212 {
213 capabilities = globalFuncTable_.getChipCaps(ifaceName.c_str());
214 if (capabilities == 0) {
215 return HAL_UNKNOWN;
216 }
217 return HAL_SUCCESS;
218 }
219
GetSupportedFeatureSet(const std::string & ifaceName,uint32_t & capabilities)220 WifiError WifiVendorHal::GetSupportedFeatureSet(const std::string& ifaceName, uint32_t& capabilities)
221 {
222 capabilities = globalFuncTable_.wifiGetSupportedFeatureSet(ifaceName.c_str());
223 if (capabilities == 0) {
224 return HAL_UNKNOWN;
225 }
226 return HAL_SUCCESS;
227 }
228
GetValidFrequenciesForBand(const std::string & ifaceName,int band)229 std::pair<WifiError, std::vector<uint32_t>>WifiVendorHal::GetValidFrequenciesForBand(
230 const std::string& ifaceName, int band)
231 {
232 std::vector<uint32_t> freqs;
233
234 WifiError status = globalFuncTable_.vendorHalGetChannelsInBand(
235 GetIfaceHandle(ifaceName), band, freqs);
236 return {status, std::move(freqs)};
237 }
238
CreateVirtualInterface(const std::string & ifname,HalIfaceType iftype)239 WifiError WifiVendorHal::CreateVirtualInterface(const std::string& ifname, HalIfaceType iftype)
240 {
241 WifiError status = globalFuncTable_.vendorHalCreateIface(
242 globalHandle_, ifname.c_str(), iftype);
243 status = HandleIfaceChangeStatus(ifname, status);
244 if (status == HAL_SUCCESS && iftype == HalIfaceType::HAL_TYPE_STA) {
245 ifaceTool_.lock()->SetUpState(ifname.c_str(), true);
246 }
247 return status;
248 }
249
DeleteVirtualInterface(const std::string & ifname)250 WifiError WifiVendorHal::DeleteVirtualInterface(const std::string& ifname)
251 {
252 std::unique_lock<std::mutex> lock(vendorHalMutex);
253 WifiError status = globalFuncTable_.vendorHalDeleteIface(
254 globalHandle_, ifname.c_str());
255 return HandleIfaceChangeStatus(ifname, status);
256 }
257
HandleIfaceChangeStatus(const std::string & ifname,WifiError status)258 WifiError WifiVendorHal::HandleIfaceChangeStatus(
259 const std::string& ifname, WifiError status)
260 {
261 if (status == HAL_SUCCESS) {
262 status = RetrieveIfaceHandles();
263 } else if (status == HAL_NOT_SUPPORTED) {
264 if (if_nametoindex(ifname.c_str())) {
265 status = RetrieveIfaceHandles();
266 }
267 }
268 return status;
269 }
270
RetrieveIfaceHandles()271 WifiError WifiVendorHal::RetrieveIfaceHandles()
272 {
273 wifiInterfaceHandle* ifaceHandles = nullptr;
274 int numIfaceHandles = 0;
275 WifiError status = globalFuncTable_.vendorHalGetIfaces(
276 globalHandle_, &numIfaceHandles, &ifaceHandles);
277 if (status != HAL_SUCCESS) {
278 HDF_LOGE("Failed to enumerate interface handles");
279 return status;
280 }
281 ifaceNameHandle_.clear();
282 for (int i = 0; i < numIfaceHandles; ++i) {
283 std::array<char, IFNAMSIZ> iface_name_arr = {};
284 status = globalFuncTable_.vendorHalGetIfName(
285 ifaceHandles[i], iface_name_arr.data(), iface_name_arr.size());
286 if (status != HAL_SUCCESS) {
287 HDF_LOGE("Failed to get interface handle name");
288 continue;
289 }
290 std::string ifaceName(iface_name_arr.data());
291 HDF_LOGI("Adding interface handle for %{public}s", ifaceName.c_str());
292 ifaceNameHandle_[ifaceName] = ifaceHandles[i];
293 }
294 return HAL_SUCCESS;
295 }
296
RegisterRestartCallback(const OnVendorHalRestartCallback & onRestartCallback)297 WifiError WifiVendorHal::RegisterRestartCallback(
298 const OnVendorHalRestartCallback& onRestartCallback)
299 {
300 if (onVendorHalRestartCallback) {
301 return HAL_NOT_AVAILABLE;
302 }
303 onVendorHalRestartCallback =
304 [onRestartCallback](const char* error) {
305 onRestartCallback(error);
306 };
307 WifiError status = globalFuncTable_.vendorHalSetRestartHandler(
308 globalHandle_, {OnAsyncSubsystemRestart});
309 if (status != HAL_SUCCESS) {
310 onVendorHalRestartCallback = nullptr;
311 }
312 return status;
313 }
314
Invalidate()315 void WifiVendorHal::Invalidate()
316 {
317 globalHandle_ = nullptr;
318 ifaceNameHandle_.clear();
319 vendorHalCbHandler_.Invalidate();
320 vendorHalExtCbHandler_.Invalidate();
321 }
322
SetCountryCode(const std::string & ifaceName,const std::string & code)323 WifiError WifiVendorHal::SetCountryCode(const std::string& ifaceName, const std::string& code)
324 {
325 return globalFuncTable_.wifiSetCountryCode(GetIfaceHandle(ifaceName), code.c_str());
326 }
327
GetSignalPollInfo(const std::string & ifaceName,SignalPollResult & signalPollResult)328 WifiError WifiVendorHal::GetSignalPollInfo(const std::string& ifaceName,
329 SignalPollResult& signalPollResult)
330 {
331 return globalFuncTable_.getSignalPollInfo(GetIfaceHandle(ifaceName), signalPollResult);
332 }
333
GetPowerMode(const std::string & ifaceName)334 std::pair<WifiError, int> WifiVendorHal::GetPowerMode(const std::string& ifaceName)
335 {
336 int mode;
337 WifiError status = globalFuncTable_.getPowerMode(ifaceName.c_str(), &mode);
338 return {status, mode};
339 }
340
SetPowerMode(const std::string & ifaceName,int mode)341 WifiError WifiVendorHal::SetPowerMode(const std::string& ifaceName, int mode)
342 {
343 return globalFuncTable_.setPowerMode(ifaceName.c_str(), mode);
344 }
345
IsSupportCoex(bool & isCoex)346 WifiError WifiVendorHal::IsSupportCoex(bool& isCoex)
347 {
348 return globalFuncTable_.isSupportCoex(isCoex);
349 }
350
EnablePowerMode(const std::string & ifaceName,int mode)351 WifiError WifiVendorHal::EnablePowerMode(const std::string& ifaceName, int mode)
352 {
353 return globalFuncTable_.enablePowerMode(ifaceName.c_str(), mode);
354 }
355
StartScan(const std::string & ifaceName,const ScanParams & params)356 WifiError WifiVendorHal::StartScan(
357 const std::string& ifaceName, const ScanParams& params)
358 {
359 WifiError status = globalFuncTable_.wifiStartScan(GetIfaceHandle(ifaceName), params);
360 return status;
361 }
362
StartPnoScan(const std::string & ifaceName,const PnoScanParams & pnoParams)363 WifiError WifiVendorHal::StartPnoScan(const std::string& ifaceName, const PnoScanParams& pnoParams)
364 {
365 WifiError status = globalFuncTable_.wifiStartPnoScan(GetIfaceHandle(ifaceName), pnoParams);
366 return status;
367 }
368
StopPnoScan(const std::string & ifaceName)369 WifiError WifiVendorHal::StopPnoScan(const std::string& ifaceName)
370 {
371 WifiError status = globalFuncTable_.wifiStopPnoScan(GetIfaceHandle(ifaceName));
372 return status;
373 }
374
GetScanInfos(const std::string & ifaceName,std::vector<ScanResultsInfo> & scanResultsInfo)375 WifiError WifiVendorHal::GetScanInfos(const std::string& ifaceName,
376 std::vector<ScanResultsInfo>& scanResultsInfo)
377 {
378 WifiError status = globalFuncTable_.getScanResults(GetIfaceHandle(ifaceName), scanResultsInfo);
379 return status;
380 }
381
SetDpiMarkRule(int32_t uid,int32_t protocol,int32_t enable)382 WifiError WifiVendorHal::SetDpiMarkRule(int32_t uid, int32_t protocol, int32_t enable)
383 {
384 return globalFuncTable_.setDpiMarkRule(uid, protocol, enable);
385 }
386
RegisterIfaceCallBack(const std::string & ifaceName,const sptr<IChipIfaceCallback> & chipIfaceCallback)387 WifiError WifiVendorHal::RegisterIfaceCallBack(const std::string& ifaceName,
388 const sptr<IChipIfaceCallback>& chipIfaceCallback)
389 {
390 vendorHalCbHandler_.AddCallback(chipIfaceCallback);
391 WifiCallbackHandler handler = {OnAsyncGscanFullResult, OnAsyncRssiReport, OnAsyncWifiNetlinkMsgReport};
392 globalFuncTable_.registerIfaceCallBack(ifaceName.c_str(), handler);
393 return HAL_SUCCESS;
394 }
395
UnRegisterIfaceCallBack(const std::string & ifaceName,const sptr<IChipIfaceCallback> & chipIfaceCallback)396 WifiError WifiVendorHal::UnRegisterIfaceCallBack(const std::string& ifaceName,
397 const sptr<IChipIfaceCallback>& chipIfaceCallback)
398 {
399 WifiCallbackHandler handler = {};
400 globalFuncTable_.registerIfaceCallBack(ifaceName.c_str(), handler);
401 vendorHalCbHandler_.Invalidate(); // instead of RemoveCallback temporarily
402 return HAL_SUCCESS;
403 }
404
RegisterExtIfaceCallBack(const std::string & ifaceName,const sptr<IChipIfaceCallback> & chipIfaceCallback)405 WifiError WifiVendorHal::RegisterExtIfaceCallBack(const std::string& ifaceName,
406 const sptr<IChipIfaceCallback>& chipIfaceCallback)
407 {
408 vendorHalExtCbHandler_.AddCallback(chipIfaceCallback);
409 WifiExtCallbackHandler handler = {OnAsyncWifiNetlinkMsgExtReport};
410 globalFuncTable_.registerExtIfaceCallBack(ifaceName.c_str(), handler);
411 return HAL_SUCCESS;
412 }
413
UnRegisterExtIfaceCallBack(const std::string & ifaceName,const sptr<IChipIfaceCallback> & chipIfaceCallback)414 WifiError WifiVendorHal::UnRegisterExtIfaceCallBack(const std::string& ifaceName,
415 const sptr<IChipIfaceCallback>& chipIfaceCallback)
416 {
417 WifiExtCallbackHandler handler = {};
418 globalFuncTable_.registerExtIfaceCallBack(ifaceName.c_str(), handler);
419 vendorHalExtCbHandler_.Invalidate(); // instead of RemoveCallback temporarily
420 return HAL_SUCCESS;
421 }
422
SetTxPower(const std::string & ifaceName,int mode)423 WifiError WifiVendorHal::SetTxPower(const std::string& ifaceName, int mode)
424 {
425 return globalFuncTable_.setTxPower(ifaceName.c_str(), mode);
426 }
427
SendCmdToDriver(const std::string & ifaceName,int32_t cmdId,const std::vector<int8_t> & paramBuf)428 WifiError WifiVendorHal::SendCmdToDriver(const std::string& ifaceName, int32_t cmdId,
429 const std::vector<int8_t>& paramBuf)
430 {
431 return globalFuncTable_.sendCmdToDriver(ifaceName.c_str(), cmdId, paramBuf);
432 }
433
SendActionFrame(const std::string & ifaceName,uint32_t freq,const std::vector<uint8_t> & frameData)434 WifiError WifiVendorHal::SendActionFrame(const std::string& ifaceName, uint32_t freq,
435 const std::vector<uint8_t>& frameData)
436 {
437 return globalFuncTable_.sendActionFrame(GetIfaceHandle(ifaceName), freq, frameData);
438 }
439
RegisterActionFrameReceiver(const std::string & ifaceName,const std::vector<uint8_t> & match)440 WifiError WifiVendorHal::RegisterActionFrameReceiver(const std::string& ifaceName, const std::vector<uint8_t>& match)
441 {
442 return globalFuncTable_.registerActionFrameReceiver(GetIfaceHandle(ifaceName), match);
443 }
444
GetCoexictenceChannelList(const std::string & ifaceName,std::vector<uint8_t> & paramBuf)445 WifiError WifiVendorHal::GetCoexictenceChannelList(const std::string& ifaceName, std::vector<uint8_t>& paramBuf)
446 {
447 return globalFuncTable_.getCoexictenceChannelList(ifaceName.c_str(), paramBuf);
448 }
449
SetProjectionScreenParam(const std::string & ifaceName,const ProjectionScreenCmdParam & param)450 WifiError WifiVendorHal::SetProjectionScreenParam(const std::string& ifaceName, const ProjectionScreenCmdParam& param)
451 {
452 return globalFuncTable_.setProjectionScreenParam(GetIfaceHandle(ifaceName), param);
453 }
454 } // namespace v1_0
455 } // namespace Chip
456 } // namespace Wlan
457 } // namespace HDI
458 } // namespace OHOS