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