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