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