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