• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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