1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
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 <cerrno>
17 #include <cstdint>
18 #include <cstdio>
19 #include <fcntl.h>
20 #include <sys/socket.h>
21 #include <linux/rtnetlink.h>
22 #include <netpacket/packet.h>
23 #include <linux/filter.h>
24 #include <linux/pkt_sched.h>
25 #include <netlink/genl/genl.h>
26 #include <netlink/genl/family.h>
27 #include <netlink/genl/ctrl.h>
28 #include <netlink/object-api.h>
29 #include <netlink/netlink.h>
30 #include <netlink/socket.h>
31 #include <netlink/attr.h>
32 #include <netlink/handlers.h>
33 #include <netlink/msg.h>
34 #include <dirent.h>
35 #include <net/if.h>
36 #include <sys/types.h>
37 #include <unistd.h>
38
39 #include <string>
40 #include <vector>
41 #include "wifi_hal.h"
42 #include "cpp_bindings.h"
43 #include "common.h"
44 #include <hdf_log.h>
45 #include "securec.h"
46 #include "gscan.h"
47 #include "wifi_ioctl.h"
48 #include "wifi_scan.h"
49 #include "v1_0/ichip_iface.h"
50
51 constexpr int32_t WIFI_HAL_CMD_SOCK_PORT = 644;
52 constexpr int32_t WIFI_HAL_EVENT_SOCK_PORT = 645;
53 constexpr int32_t MAX_VIRTUAL_IFACES = 5;
54 constexpr int32_t WIFI_HAL_EVENT_BUFFER_NOT_AVAILABLE = 105;
55 constexpr int32_t EVENT_BUF_SIZE = 2048;
56 constexpr int32_t POLL_DRIVER_DURATION_US = 100000;
57 constexpr int32_t POLL_DRIVER_MAX_TIME_MS = 10000;
58 constexpr int32_t SIZE_BATE = 256;
59 constexpr int32_t SIZE_1K = 1024;
60 constexpr int32_t NUM_4 = 4;
61 constexpr int32_t DEFAULT_OFFSET = 22;
62 constexpr int32_t CALLOC_MAX_VALUE = 10;
63 constexpr int32_t OFFSET_8 = 8;
64 constexpr int32_t OFFSET_16 = 16;
65 constexpr int32_t OFFSET_24 = 24;
66 constexpr int32_t MASK_CSMA = 0xFF;
67
68 static std::mutex g_callbackMutex;
69
70 static int WifiGetMulticastId(wifiHandle handle, const char *name, const char *group);
71 static int wifiAddMemberShip(wifiHandle handle, const char *group);
72 static WifiError WifiInitInterfaces(wifiHandle handle);
73 static int GetInterface(const char *name, InterfaceInfo *info);
74 static bool IsWifiInterface(const char *name);
75 static void WifiCleanupDynamicIfaces(wifiHandle handle);
76 static void InternalCleanedUpHandler(wifiHandle handle);
77 static int InternalPollinHandler(wifiHandle handle);
78 static WifiError WifiSetCountryCode(wifiInterfaceHandle handle, const char *country_code);
79 static WifiError WifiGetSignalInfo(wifiInterfaceHandle handle,
80 OHOS::HDI::Wlan::Chip::V1_0::SignalPollResult& signalPollresult);
81 static WifiError RegisterIfaceCallBack(const char *ifaceName,
82 WifiCallbackHandler OnCallbackEvent);
83 static WifiError VendorHalCreateIface(wifiHandle handle, const char* ifname,
84 HalIfaceType ifaceType);
85 static WifiError VendorHalDeleteIface(wifiHandle handle, const char* ifname);
86 static void CheckWhetherAddIface(wifiHandle handle, const char* ifname);
87 WifiError IsSupportCoex(bool& isCoex);
88 static WifiError SendCmdToDriver(const char *ifaceName, int32_t commandId, const std::vector<int8_t>& paramData);
89
90 typedef enum WifiAttr {
91 HAL_INVALID = 0,
92 HAL_FEATURE_SET_NUM = 1,
93 HAL_FEATURE_SET = 2,
94 HAL_PNO_RANDOM_MAC_OUI = 3,
95 HAL_NODFS_SET = 4,
96 HAL_COUNTRY = 5,
97 HAL_ND_OFFLOAD_VALUE = 6,
98 HAL_TCPACK_SUP_VALUE = 7,
99 HAL_LATENCY_MODE = 8,
100 HAL_RANDOM_MAC = 9,
101 HAL_TX_POWER_SCENARIO = 10,
102 HAL_THERMAL_MITIGATION = 11,
103 HAL_THERMAL_COMPLETION_WINDOW = 12,
104 HAL_VOIP_MODE = 13,
105 HAL_DTIM_MULTIPLIER = 14,
106 HAL_MAX
107 } WifiAttrT;
108
109 #define NET_FILE_PATH "/sys/class/net/wlan0"
110
111 #define NL80211_SCAN_CMD(cmd) ((cmd) == NL80211_CMD_NEW_SCAN_RESULTS || (cmd) == NL80211_CMD_SCHED_SCAN_RESULTS || \
112 (cmd) == NL80211_CMD_SCAN_ABORTED)
113
114 static const int RSV_MAX_SIZE = 3;
115
116 typedef struct {
117 int index;
118 int c0Rssi;
119 int c1Rssi;
120 int rsv[RSV_MAX_SIZE];
121 } RssiReportStru;
122
123 HalInfo *g_halInfo = nullptr;
124
WifiPreDeinitialize(void)125 static void WifiPreDeinitialize(void)
126 {
127 HDF_LOGI("wifi_pre_uninitialize enter");
128 if (g_halInfo->cmdSock != nullptr) {
129 close(g_halInfo->cleanupSocks[0]);
130 close(g_halInfo->cleanupSocks[1]);
131 nl_socket_free(g_halInfo->cmdSock);
132 nl_socket_free(g_halInfo->eventSock);
133 g_halInfo->cmdSock = nullptr;
134 g_halInfo->eventSock = nullptr;
135 }
136 pthread_mutex_destroy(&g_halInfo->cbLock);
137 DestroyResponseLock();
138 free(g_halInfo);
139 g_halInfo = nullptr;
140 }
141
InitWifiVendorHalFuncTable(WifiHalFn * fn)142 WifiError InitWifiVendorHalFuncTable(WifiHalFn *fn)
143 {
144 if (fn == NULL) {
145 return HAL_UNKNOWN;
146 }
147 fn->vendorHalInit = VendorHalInit;
148 fn->waitDriverStart = WaitDriverStart;
149 fn->vendorHalExit = VendorHalExit;
150 fn->startHalLoop = StartHalLoop;
151 fn->vendorHalGetIfaces = VendorHalGetIfaces;
152 fn->vendorHalGetIfName = VendorHalGetIfName;
153 fn->vendorHalGetChannelsInBand = VendorHalGetChannelsInBand;
154 fn->vendorHalSetRestartHandler = VendorHalSetRestartHandler;
155 fn->vendorHalCreateIface = VendorHalCreateIface;
156 fn->vendorHalDeleteIface = VendorHalDeleteIface;
157 fn->triggerVendorHalRestart = TriggerVendorHalRestart;
158 fn->wifiSetCountryCode = WifiSetCountryCode;
159 fn->getSignalPollInfo = WifiGetSignalInfo;
160 fn->wifiStartScan = WifiStartScan;
161 fn->registerIfaceCallBack = RegisterIfaceCallBack;
162 fn->getScanResults = WifiGetScanInfo;
163 fn->wifiStartPnoScan = WifiStartPnoScan;
164 fn->wifiStopPnoScan = WifiStopPnoScan;
165 fn->wifiGetSupportedFeatureSet = WifiGetSupportedFeatureSet;
166 fn->getChipCaps = GetChipCaps;
167 fn->isSupportCoex = IsSupportCoex;
168 fn->sendCmdToDriver = SendCmdToDriver;
169 return HAL_SUCCESS;
170 }
171
WifiSocketSetLocalPort(struct nl_sock * sock,uint32_t port)172 static void WifiSocketSetLocalPort(struct nl_sock *sock, uint32_t port)
173 {
174 constexpr int32_t num = DEFAULT_OFFSET;
175 uint32_t pid = static_cast<uint32_t>(getpid()) & 0x3FFFFF;
176 nl_socket_set_local_port(sock, pid + (port << num));
177 }
178
WifiCreateNlSocket(int port)179 static nl_sock* WifiCreateNlSocket(int port)
180 {
181 struct nl_sock *sock = nl_socket_alloc();
182 if (sock == nullptr) {
183 HDF_LOGE("Could not create handle");
184 return nullptr;
185 }
186
187 WifiSocketSetLocalPort(sock, port);
188
189 if (nl_connect(sock, NETLINK_GENERIC)) {
190 HDF_LOGE("Could not connect handle");
191 nl_socket_free(sock);
192 return nullptr;
193 }
194 return sock;
195 }
196
ReportEventCallback(int cmd,WifiEvent & event)197 static int ReportEventCallback(int cmd, WifiEvent &event)
198 {
199 std::unique_lock<std::mutex> lock(g_callbackMutex);
200 if (NL80211_SCAN_CMD(cmd)) {
201 if (g_halInfo->ifaceCallBack.onScanEvent != nullptr) {
202 g_halInfo->ifaceCallBack.onScanEvent(cmd);
203 return NL_OK;
204 }
205 }
206 return NL_SKIP;
207 }
208
InternalNoSeqCheck(struct nl_msg * msg,void * arg)209 static int InternalNoSeqCheck(struct nl_msg *msg, void *arg)
210 {
211 return NL_OK;
212 }
213
InternalValidMessageHandler(nl_msg * msg,void * arg)214 static int InternalValidMessageHandler(nl_msg *msg, void *arg)
215 {
216 HalInfo *info = GetHalInfo((wifiHandle)arg);
217 WifiEvent event(msg);
218 int res = event.Parse();
219 if (res < 0 || info == nullptr) {
220 HDF_LOGE("Failed to Parse event: %{public}d", res);
221 return NL_SKIP;
222 }
223 int cmd = event.GetCmd();
224 uint32_t vendorId = 0;
225 int subcmd = 0;
226 if (cmd == NL80211_CMD_VENDOR) {
227 vendorId = event.GetU32(NL80211_ATTR_VENDOR_ID);
228 subcmd = static_cast<int>(event.GetU32(NL80211_ATTR_VENDOR_SUBCMD));
229 HDF_LOGD("event receive %{public}d, vendorId = 0x%{public}0x, subcmd = 0x%{public}0x", cmd, vendorId, subcmd);
230 }
231 if (ReportEventCallback(cmd, event) == NL_OK) {
232 return NL_OK;
233 }
234 pthread_mutex_lock(&info->cbLock);
235 for (int i = 0; i < info->numEventCb; i++) {
236 if (cmd == info->eventCb[i].nlCmd) {
237 if (cmd == NL80211_CMD_VENDOR && ((vendorId != info->eventCb[i].vendorId) ||
238 (subcmd != info->eventCb[i].vendorSubcmd))) {
239 continue;
240 }
241 CbInfo *cbi = &(info->eventCb[i]);
242 nl_recvmsg_msg_cb_t cbFunc = cbi->cbFunc;
243 WifiCommand *wifiCommand = (WifiCommand *)cbi->cbArg;
244 if (wifiCommand != nullptr) {
245 wifiCommand->AddRef();
246 }
247 pthread_mutex_unlock(&info->cbLock);
248 if (cbFunc) {
249 (*cbFunc)(msg, cbi->cbArg);
250 }
251 if (wifiCommand != nullptr) {
252 wifiCommand->ReleaseRef();
253 }
254 return NL_OK;
255 }
256 }
257 pthread_mutex_unlock(&info->cbLock);
258 return NL_OK;
259 }
260
wifiAddMemberShip(wifiHandle handle,const char * group)261 static int wifiAddMemberShip(wifiHandle handle, const char *group)
262 {
263 HalInfo *info = GetHalInfo(handle);
264 int id = WifiGetMulticastId(handle, "nl80211", group);
265 if (id < 0 || info == nullptr) {
266 HDF_LOGE("Could not find group %{public}s", group);
267 return id;
268 }
269
270 int ret = nl_socket_add_membership(info->eventSock, id);
271 if (ret < 0) {
272 HDF_LOGE("Could not add membership to group %{public}s", group);
273 }
274
275 return ret;
276 }
277
GetInterfaceNum(int * n)278 static WifiError GetInterfaceNum(int* n)
279 {
280 int cnt = 0;
281 DIR *d = opendir("/sys/class/net");
282 if (d == nullptr) {
283 return HAL_UNKNOWN;
284 }
285 struct dirent *de;
286 while ((de = readdir(d))) {
287 if (de->d_name[0] == '.') {
288 continue;
289 }
290 if (IsWifiInterface(de->d_name)) {
291 cnt++;
292 }
293 }
294 closedir(d);
295 *n = cnt;
296 return HAL_SUCCESS;
297 }
298
RelaseHalInfoSpace(HalInfo * info)299 static void RelaseHalInfoSpace(HalInfo *info)
300 {
301 if (info == nullptr || info->interfaces == nullptr || info->numInterfaces == 0) {
302 return;
303 }
304 int i = 0;
305 while (i < info->numInterfaces) {
306 free(info->interfaces[i]);
307 i++;
308 }
309 free(info->interfaces);
310 info->interfaces = nullptr;
311 info->numInterfaces = 0;
312 }
313
WifiInitInterfacesSplitting(wifiHandle handle,HalInfo * info,DIR * d,int & i,int & n)314 static WifiError WifiInitInterfacesSplitting(wifiHandle handle, HalInfo *info, DIR *d, int &i, int &n)
315 {
316 struct dirent *de;
317 while ((de = readdir(d)) && i < n) {
318 if (de->d_name[0] == '.') {
319 continue;
320 }
321 if (IsWifiInterface(de->d_name)) {
322 InterfaceInfo *ifinfo = (InterfaceInfo *)malloc(sizeof(InterfaceInfo));
323 if (ifinfo == nullptr) {
324 return HAL_OUT_OF_MEMORY;
325 }
326 if (memset_s(ifinfo, sizeof(InterfaceInfo), 0, sizeof(InterfaceInfo)) != EOK ||
327 GetInterface(de->d_name, ifinfo) != HAL_SUCCESS) {
328 free(ifinfo);
329 return HAL_OUT_OF_MEMORY;
330 }
331 ifinfo->isVirtual = false;
332 ifinfo->handle = handle;
333 info->interfaces[i] = ifinfo;
334 i++;
335 }
336 }
337 return HAL_SUCCESS;
338 }
339
WifiInitInterfaces(wifiHandle handle)340 static WifiError WifiInitInterfaces(wifiHandle handle)
341 {
342 HalInfo *info = (HalInfo *)handle;
343 int n = 0;
344 WifiError ret = GetInterfaceNum(&n);
345 if (ret == HAL_UNKNOWN) {
346 return HAL_UNKNOWN;
347 }
348 if (n == 0) {
349 return HAL_NOT_AVAILABLE;
350 }
351
352 DIR *d = opendir("/sys/class/net");
353 if (d == nullptr) {
354 return HAL_UNKNOWN;
355 }
356 n += MAX_VIRTUAL_IFACES;
357 if (n > CALLOC_MAX_VALUE) {
358 closedir(d);
359 return HAL_OUT_OF_MEMORY;
360 }
361 info->interfaces = (InterfaceInfo **)calloc(n, sizeof(InterfaceInfo *) * n);
362 if (!info->interfaces) {
363 RelaseHalInfoSpace(info);
364 closedir(d);
365 return HAL_OUT_OF_MEMORY;
366 }
367 int i = 0;
368 if (WifiInitInterfacesSplitting(handle, info, d, i, n) != HAL_SUCCESS) {
369 RelaseHalInfoSpace(info);
370 closedir(d);
371 return HAL_OUT_OF_MEMORY;
372 }
373 closedir(d);
374 info->numInterfaces = i;
375 info->maxNumInterfaces = n;
376 return HAL_SUCCESS;
377 }
378
379 class GetMulticastIdCommand : public WifiCommand {
380 public:
GetMulticastIdCommand(wifiHandle handle,const char * name,const char * group)381 GetMulticastIdCommand(wifiHandle handle, const char *name, const char *group)
382 : WifiCommand("GetMulticastIdCommand", handle, 0)
383 {
384 mName = name;
385 mGroup = group;
386 mId = -1;
387 }
388
GetId()389 int GetId()
390 {
391 return mId;
392 }
393
Create()394 int Create() override
395 {
396 int nlctrlFamily = genl_ctrl_resolve(mInfo->cmdSock, "nlctrl");
397 int ret = mMsg.Create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0);
398 if (ret < 0) {
399 return ret;
400 }
401 ret = mMsg.PutString(CTRL_ATTR_FAMILY_NAME, mName);
402 return ret;
403 }
404
HandleResponse(WifiEvent & reply)405 int HandleResponse(WifiEvent& reply) override
406 {
407 struct nlattr **tb = reply.Attributes();
408 struct nlattr *mcgrp = nullptr;
409 int i;
410
411 if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
412 HDF_LOGI("No multicast groups found");
413 return NL_SKIP;
414 }
415
416 FOR_EACH_ATTR(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
417 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
418 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, (nlattr *)nla_data(mcgrp),
419 nla_len(mcgrp), NULL);
420 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || !tb2[CTRL_ATTR_MCAST_GRP_ID]) {
421 continue;
422 }
423 char *grpName = (char *)nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
424 int grpNameLen = nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
425 if (strncmp(grpName, mGroup, grpNameLen) != 0) {
426 continue;
427 }
428 mId = static_cast<int32_t>(nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]));
429 break;
430 }
431 return NL_SKIP;
432 }
433
434 private:
435 const char *mName;
436 const char *mGroup;
437 int mId;
438 };
439
WifiGetMulticastId(wifiHandle handle,const char * name,const char * group)440 static int WifiGetMulticastId(wifiHandle handle, const char *name, const char *group)
441 {
442 GetMulticastIdCommand cmd(handle, name, group);
443 auto lock = ReadLockData();
444 int res = cmd.RequestResponse();
445 if (res < 0) {
446 return res;
447 } else {
448 return cmd.GetId();
449 }
450 }
451
IsWifiInterface(const char * name)452 static bool IsWifiInterface(const char *name)
453 {
454 constexpr int32_t NUM_3 = 3;
455 constexpr int32_t NUM_5 = 5;
456 if (strncmp(name, "wlan", NUM_4) != 0 && strncmp(name, "swlan", NUM_5) != 0 &&
457 strncmp(name, "p2p", NUM_3) != 0 && strncmp(name, "aware", NUM_5) != 0 &&
458 strncmp(name, "nan", NUM_3) != 0) {
459 /* not a wifi interface; ignore it */
460 return false;
461 } else {
462 return true;
463 }
464 }
465
GetInterface(const char * name,InterfaceInfo * info)466 static int GetInterface(const char *name, InterfaceInfo *info)
467 {
468 unsigned int size = 0;
469 size = strlcpy(info->name, name, sizeof(info->name));
470 if (size >= sizeof(info->name)) {
471 return HAL_OUT_OF_MEMORY;
472 }
473 info->id = static_cast<int>(if_nametoindex(name));
474 return HAL_SUCCESS;
475 }
476
WifiGetWlanInterface(wifiHandle info,wifiInterfaceHandle * ifaceHandles,int numIfaceHandles)477 wifiInterfaceHandle WifiGetWlanInterface(wifiHandle info, wifiInterfaceHandle *ifaceHandles, int numIfaceHandles)
478 {
479 constexpr int32_t NUM_5 = 5;
480 char buf[EVENT_BUF_SIZE];
481 wifiInterfaceHandle wlan0Handle;
482 WifiError res = VendorHalGetIfaces((wifiHandle)info, &numIfaceHandles, &ifaceHandles);
483 if (res < 0) {
484 return NULL;
485 }
486 for (int i = 0; i < numIfaceHandles; i++) {
487 if (VendorHalGetIfName(ifaceHandles[i], buf, sizeof(buf)) == HAL_SUCCESS) {
488 if (strncmp(buf, "wlan0", NUM_5) == 0) {
489 HDF_LOGI("found interface %{public}s\n", buf);
490 wlan0Handle = ifaceHandles[i];
491 return wlan0Handle;
492 }
493 }
494 }
495 return NULL;
496 }
497
PreInitFail(bool needCloseSock,struct nl_sock * eventSock,struct nl_sock * cmdSock,bool needClearLock,bool needClearcb)498 static void PreInitFail(bool needCloseSock, struct nl_sock *eventSock,
499 struct nl_sock *cmdSock, bool needClearLock, bool needClearcb)
500 {
501 if (needCloseSock) {
502 close(g_halInfo->cleanupSocks[0]);
503 close(g_halInfo->cleanupSocks[1]);
504 }
505 if (cmdSock != nullptr) {
506 nl_socket_free(cmdSock);
507 }
508 if (eventSock != nullptr) {
509 nl_socket_free(eventSock);
510 }
511 if (needClearLock) {
512 pthread_mutex_destroy(&g_halInfo->cbLock);
513 DestroyResponseLock();
514 }
515 if (needClearcb) {
516 if (g_halInfo->eventCb != nullptr) {
517 free(g_halInfo->eventCb);
518 g_halInfo->eventCb = nullptr;
519 }
520 if (g_halInfo->cmd != nullptr) {
521 free(g_halInfo->cmd);
522 g_halInfo->cmd = nullptr;
523 }
524 }
525 if (g_halInfo != nullptr) {
526 free(g_halInfo);
527 g_halInfo = nullptr;
528 }
529 }
530
SetHalInfo(struct nl_sock * eventSock,struct nl_sock * cmdSock)531 static bool SetHalInfo(struct nl_sock *eventSock, struct nl_sock *cmdSock)
532 {
533 struct nl_cb *cb = nl_socket_get_cb(eventSock);
534 if (cb == nullptr) {
535 HDF_LOGE("Could not create handle");
536 return false;
537 }
538 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, InternalNoSeqCheck, g_halInfo);
539 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, InternalValidMessageHandler, g_halInfo);
540 nl_cb_put(cb);
541 g_halInfo->cmdSock = cmdSock;
542 g_halInfo->eventSock = eventSock;
543 g_halInfo->cleanUp = false;
544 g_halInfo->inEventLoop = false;
545 g_halInfo->eventCb = reinterpret_cast<CbInfo *>(malloc(sizeof(CbInfo) * DEFAULT_EVENT_CB_SIZE));
546 if (g_halInfo->eventCb == nullptr) {
547 return false;
548 }
549 g_halInfo->allocEventCb = DEFAULT_EVENT_CB_SIZE;
550 g_halInfo->numEventCb = 0;
551 g_halInfo->cmd = reinterpret_cast<CmdInfo *>(malloc(sizeof(CmdInfo) * DEFAULT_CMD_SIZE));
552 if (g_halInfo->cmd == nullptr) {
553 free(g_halInfo->eventCb);
554 g_halInfo->eventCb = nullptr;
555 return false;
556 }
557 g_halInfo->allocCmd = DEFAULT_CMD_SIZE;
558 g_halInfo->numCmd = 0;
559 g_halInfo->nl80211FamilyId = genl_ctrl_resolve(cmdSock, "nl80211");
560 if (g_halInfo->nl80211FamilyId < 0) {
561 HDF_LOGE("Could not resolve nl80211 familty id");
562 free(g_halInfo->eventCb);
563 g_halInfo->eventCb = nullptr;
564 free(g_halInfo->cmd);
565 g_halInfo->cmd = nullptr;
566 return false;
567 }
568 return true;
569 }
570
InitCmdSock()571 static struct nl_sock *InitCmdSock()
572 {
573 struct nl_sock *cmdSock = WifiCreateNlSocket(WIFI_HAL_CMD_SOCK_PORT);
574 if (cmdSock == nullptr) {
575 HDF_LOGE("cmd sock create failed");
576 return nullptr;
577 }
578 if (nl_socket_set_buffer_size(cmdSock, (SIZE_BATE * SIZE_1K), 0) < 0) {
579 HDF_LOGE("Could not set size for cmdSock: %{public}s", strerror(errno));
580 }
581 return cmdSock;
582 }
583
InitEventSock()584 static struct nl_sock *InitEventSock()
585 {
586 struct nl_sock *eventSock = WifiCreateNlSocket(WIFI_HAL_EVENT_SOCK_PORT);
587 if (eventSock == nullptr) {
588 HDF_LOGE("event sock create failed");
589 return nullptr;
590 }
591 if (nl_socket_set_buffer_size(eventSock, (NUM_4 * SIZE_1K * SIZE_1K), 0) < 0) {
592 HDF_LOGE("Could not set size for eventSock: %{public}s", strerror(errno));
593 }
594 return eventSock;
595 }
596
InitHalInfo()597 static bool InitHalInfo()
598 {
599 g_halInfo = reinterpret_cast<HalInfo *>(malloc(sizeof(HalInfo)));
600 if (g_halInfo == nullptr) {
601 HDF_LOGE("Could not allocate HalInfo");
602 return false;
603 }
604 if (memset_s(g_halInfo, sizeof(*g_halInfo), 0, sizeof(*g_halInfo)) != EOK) {
605 HDF_LOGE("memset HalInfo failed");
606 free(g_halInfo);
607 g_halInfo = nullptr;
608 return false;
609 }
610 return true;
611 }
612
WifiPreInitialize(void)613 static WifiError WifiPreInitialize(void)
614 {
615 srand(getpid());
616 wifiHandle handle;
617
618 HDF_LOGI("WifiPreInitialize");
619 if (g_halInfo != nullptr) {
620 WifiPreDeinitialize();
621 }
622 if (!InitHalInfo()) {
623 return HAL_UNKNOWN;
624 }
625 HDF_LOGI("Creating socket");
626 if (socketpair(AF_UNIX, SOCK_STREAM, 0, g_halInfo->cleanupSocks) == -1) {
627 HDF_LOGE("Could not create cleanup sockets");
628 PreInitFail(false, nullptr, nullptr, false, false);
629 return HAL_UNKNOWN;
630 }
631 struct nl_sock *cmdSock = InitCmdSock();
632 if (cmdSock == nullptr) {
633 PreInitFail(true, nullptr, nullptr, false, false);
634 return HAL_UNKNOWN;
635 }
636 struct nl_sock *eventSock = InitEventSock();
637 if (eventSock == nullptr) {
638 PreInitFail(true, nullptr, cmdSock, false, false);
639 return HAL_UNKNOWN;
640 }
641 if (!SetHalInfo(eventSock, cmdSock)) {
642 PreInitFail(true, eventSock, cmdSock, false, false);
643 return HAL_UNKNOWN;
644 }
645 pthread_mutex_init(&g_halInfo->cbLock, nullptr);
646 InitResponseLock();
647 handle = (wifiHandle) g_halInfo;
648 if (WifiInitInterfaces(handle) != HAL_SUCCESS) {
649 HDF_LOGE("No wifi interface found");
650 PreInitFail(true, eventSock, cmdSock, true, true);
651 return HAL_NOT_AVAILABLE;
652 }
653 if ((wifiAddMemberShip(handle, "scan") < 0) || (wifiAddMemberShip(handle, "mlme") < 0) ||
654 (wifiAddMemberShip(handle, "regulatory") < 0) || (wifiAddMemberShip(handle, "vendor") < 0)) {
655 HDF_LOGE("Add membership failed");
656 PreInitFail(true, eventSock, cmdSock, true, true);
657 return HAL_NOT_AVAILABLE;
658 }
659 HDF_LOGI("Initialized Wifi HAL Successfully; vendor cmd = %{public}d", NL80211_CMD_VENDOR);
660 return HAL_SUCCESS;
661 }
662
VendorHalInit(wifiHandle * handle)663 WifiError VendorHalInit(wifiHandle *handle)
664 {
665 WifiError result = HAL_SUCCESS;
666
667 HDF_LOGI("WifiInitialize");
668 if (g_halInfo == nullptr) {
669 result = WifiPreInitialize();
670 if (result != HAL_SUCCESS) {
671 HDF_LOGE("WifiInitialize WifiPreInitialize failed");
672 return result;
673 } else {
674 HDF_LOGE("WifiInitialize WifiPreInitialize succeeded");
675 }
676 }
677 *handle = (wifiHandle) g_halInfo;
678 return HAL_SUCCESS;
679 }
680
681
WaitDriverStart(void)682 WifiError WaitDriverStart(void)
683 {
684 // This function will Wait to make sure basic client netdev is created
685 // Function times out after 10 seconds
686 #ifdef SUPPORT_EMULATOR
687 return HAL_SUCCESS;
688 #endif
689 int count = (POLL_DRIVER_MAX_TIME_MS * 1000) / POLL_DRIVER_DURATION_US;
690 FILE *fd;
691
692 do {
693 if ((fd = fopen(NET_FILE_PATH, "r")) != nullptr) {
694 fclose(fd);
695 WifiPreInitialize();
696 return HAL_SUCCESS;
697 }
698 usleep(POLL_DRIVER_DURATION_US);
699 } while (--count > 0);
700
701 HDF_LOGE("Timed out waiting on Driver ready ... ");
702 return HAL_TIMED_OUT;
703 }
704
705 static std::vector<std::string> added_ifaces;
706
WifiCleanupDynamicIfaces(wifiHandle handle)707 static void WifiCleanupDynamicIfaces(wifiHandle handle)
708 {
709 unsigned int len = added_ifaces.size();
710 HDF_LOGI("%{public}s: virtual iface size %{public}d\n", __FUNCTION__, len);
711 while (len--) {
712 VendorHalDeleteIface(handle, added_ifaces.front().c_str());
713 HDF_LOGI("%{public}s: deleted virtual iface %{public}s\n",
714 __FUNCTION__, added_ifaces.front().c_str());
715 }
716 added_ifaces.clear();
717 }
718
VendorHalExitSplitting(wifiHandle handle,HalInfo * info)719 static void VendorHalExitSplitting(wifiHandle handle, HalInfo *info)
720 {
721 /* calling internal modules or cleanup */
722 pthread_mutex_lock(&info->cbLock);
723 int badCommands = 0;
724 HDF_LOGI("eventCb callbacks left: %{public}d ", info->numEventCb);
725 for (int i = 0; i < info->numEventCb; i++) {
726 HDF_LOGI("eventCb cleanup. index:%{public}d", i);
727 CbInfo *cbi = &(info->eventCb[i]);
728 if (!cbi) {
729 HDF_LOGE("cbi null for index %{public}d", i);
730 continue;
731 }
732 HDF_LOGI("eventCb cleanup. vendor cmd:%{public}d sub_cmd:%{public}d", cbi->vendorId, cbi->vendorSubcmd);
733 WifiCommand *cmd = (WifiCommand *)cbi->cbArg;
734 if (cmd != nullptr) {
735 HDF_LOGI("Command left in eventCb");
736 }
737 }
738 HDF_LOGI("Check bad commands: numCmd:%{public}d badCommands:%{public}d", info->numCmd, badCommands);
739 while (info->numCmd > badCommands) {
740 int numCmd = info->numCmd;
741 CmdInfo *cmdi = &(info->cmd[badCommands]);
742 WifiCommand *cmd = cmdi->cmd;
743 if (cmd != nullptr) {
744 HDF_LOGI("Cancelling command:%{public}s", cmd->GetType());
745 pthread_mutex_unlock(&info->cbLock);
746 cmd->Cancel();
747 pthread_mutex_lock(&info->cbLock);
748 if (numCmd == info->numCmd) {
749 HDF_LOGI("Cancelling command:%{public}s did not work", (cmd ? cmd->GetType() : ""));
750 badCommands++;
751 }
752 /* release reference added when command is saved */
753 cmd->ReleaseRef();
754 }
755 }
756 for (int i = 0; i < info->numEventCb; i++) {
757 CbInfo *cbi = &(info->eventCb[i]);
758 if (!cbi) {
759 HDF_LOGE("cbi null for index %{public}d", i);
760 continue;
761 }
762 }
763 if (!GetGHalutilMode()) {
764 WifiCleanupDynamicIfaces(handle);
765 }
766 pthread_mutex_unlock(&info->cbLock);
767 }
768
VendorHalExit(wifiHandle handle,VendorHalExitHandler handler)769 void VendorHalExit(wifiHandle handle, VendorHalExitHandler handler)
770 {
771 if (!handle) {
772 HDF_LOGE("Handle is null");
773 return;
774 }
775
776 HalInfo *info = GetHalInfo(handle);
777 int numIfaceHandles = 0;
778 wifiInterfaceHandle *ifaceHandles = NULL;
779 wifiInterfaceHandle wlan0Handle;
780
781 info->CleanedUpHandler = handler;
782 auto lock = WriteLock();
783 wlan0Handle = WifiGetWlanInterface((wifiHandle) info, ifaceHandles, numIfaceHandles);
784 if (wlan0Handle != NULL) {
785 HDF_LOGE("Calling hal cleanup");
786 if (!GetGHalutilMode()) {
787 WifiCleanupDynamicIfaces(handle);
788 HDF_LOGI("Cleaned dynamic virtual ifaces\n");
789 HDF_LOGI("wifi_stop_hal success");
790 }
791 } else {
792 HDF_LOGE("Not cleaning up hal as global_iface is NULL");
793 }
794
795 VendorHalExitSplitting(handle, info);
796
797 info->cleanUp = true;
798
799 if (TEMP_FAILURE_RETRY(write(info->cleanupSocks[0], "Exit", NUM_4)) < 1) {
800 // As a fallback set the cleanup flag to TRUE
801 HDF_LOGE("could not write to the cleanup socket");
802 }
803 HDF_LOGE("wifi_cleanUp done");
804 }
805
InternalCleanedUpHandler(wifiHandle handle)806 static void InternalCleanedUpHandler(wifiHandle handle)
807 {
808 auto lock = WriteLock();
809 HalInfo *info = GetHalInfo(handle);
810 if (info == nullptr) {
811 HDF_LOGE("InternalCleanedUpHandler: info is null");
812 return;
813 }
814 VendorHalExitHandler cleanedUpHandler = info->CleanedUpHandler;
815 HDF_LOGI("internal clean up");
816 if (info->cmdSock != nullptr) {
817 HDF_LOGI("cmdSock non null. clean up");
818 close(info->cleanupSocks[0]);
819 close(info->cleanupSocks[1]);
820 nl_socket_free(info->cmdSock);
821 nl_socket_free(info->eventSock);
822 info->cmdSock = nullptr;
823 info->eventSock = nullptr;
824 }
825
826 if (cleanedUpHandler) {
827 HDF_LOGI("cleanup_handler cb");
828 (*cleanedUpHandler)(handle);
829 } else {
830 HDF_LOGE("!! clean up handler is null!!");
831 }
832 DestroyResponseLock();
833 pthread_mutex_destroy(&info->cbLock);
834 free(info);
835 g_halInfo = nullptr;
836 HDF_LOGI("Internal cleanup completed");
837 }
838
InternalPollinHandler(wifiHandle handle)839 static int InternalPollinHandler(wifiHandle handle)
840 {
841 HalInfo *info = GetHalInfo(handle);
842 if (info == nullptr) {
843 HDF_LOGE("InternalPollinHandler: info is nullptr");
844 return -1;
845 }
846 struct nl_cb *cb = nl_socket_get_cb(info->eventSock);
847 int res = nl_recvmsgs(info->eventSock, cb);
848 HDF_LOGD("nl_recvmsgs returned %{public}d", res);
849 nl_cb_put(cb);
850 return res;
851 }
852
StartHalLoop(wifiHandle handle)853 void StartHalLoop(wifiHandle handle)
854 {
855 constexpr int32_t NUM_2 = 2;
856 HalInfo *info = GetHalInfo(handle);
857 if (info == nullptr || info->eventSock == nullptr || info->inEventLoop) {
858 return;
859 } else {
860 info->inEventLoop = true;
861 }
862
863 pollfd pfd[2];
864 if (memset_s(&pfd[0], sizeof(pollfd) * NUM_2, 0, sizeof(pollfd) * NUM_2) != EOK) {
865 return;
866 }
867 pfd[0].fd = nl_socket_get_fd(info->eventSock);
868 pfd[0].events = POLLIN;
869 pfd[1].fd = info->cleanupSocks[1];
870 pfd[1].events = POLLIN;
871
872 char buf[2048];
873 do {
874 int timeout = -1; /* Infinite timeout */
875 pfd[0].revents = 0;
876 pfd[1].revents = 0;
877 int result = TEMP_FAILURE_RETRY(poll(pfd, NUM_2, timeout));
878 if (result < 0) {
879 HDF_LOGE("Error polling socket");
880 } else if (static_cast<uint32_t>(pfd[0].revents) & POLLERR) {
881 HDF_LOGE("POLL Error; error no = %{public}d (%{public}s)", errno, strerror(errno));
882 ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[0].fd, buf, sizeof(buf)));
883 HDF_LOGE("Read after POLL returned %zd, error no = %{public}d (%{public}s)", result2,
884 errno, strerror(errno));
885 if (errno == WIFI_HAL_EVENT_BUFFER_NOT_AVAILABLE) {
886 HDF_LOGE("Exit, No buffer space");
887 break;
888 }
889 } else if (static_cast<uint32_t>(pfd[0].revents) & POLLHUP) {
890 HDF_LOGE("Remote side hung up");
891 break;
892 } else if ((static_cast<uint32_t>(pfd[0].revents) & (POLLIN)) && (!info->cleanUp)) {
893 InternalPollinHandler(handle);
894 } else if (static_cast<uint32_t>(pfd[1].revents) & POLLIN) {
895 HDF_LOGI("Got a Signal to exit!!!");
896 } else {
897 HDF_LOGE("Unknown event - %{public}0x, %{public}0x", pfd[0].revents, pfd[1].revents);
898 }
899 } while (!info->cleanUp);
900
901 InternalCleanedUpHandler(handle);
902 HDF_LOGE("Exit %{public}s", __FUNCTION__);
903 }
904
905 class VirtualIfaceConfig : public WifiCommand {
906 const char *mIfname;
907 nl80211_iftype mType;
908 uint32_t mwlan0Id;
909
910 public:
VirtualIfaceConfig(wifiInterfaceHandle handle,const char * ifname,nl80211_iftype ifaceType,uint32_t wlan0Id)911 VirtualIfaceConfig(wifiInterfaceHandle handle, const char* ifname, nl80211_iftype ifaceType, uint32_t wlan0Id)
912 : WifiCommand("VirtualIfaceConfig", handle, 0), mIfname(ifname), mType(ifaceType), mwlan0Id(wlan0Id)
913 {
914 mIfname = ifname;
915 mType = ifaceType;
916 mwlan0Id = wlan0Id;
917 }
918
CreateRequest(WifiRequest & request,const char * ifname,nl80211_iftype ifaceType,uint32_t wlan0Id)919 int CreateRequest(WifiRequest& request, const char* ifname,
920 nl80211_iftype ifaceType, uint32_t wlan0Id)
921 {
922 HDF_LOGD("add ifname = %{public}s, ifaceType = %{public}d, wlan0Id = %{public}d",
923 ifname, ifaceType, wlan0Id);
924
925 int result = request.Create(NL80211_CMD_NEW_INTERFACE);
926 if (result < 0) {
927 HDF_LOGE("failed to create NL80211_CMD_NEW_INTERFACE; result = %{public}d", result);
928 return result;
929 }
930
931 result = request.PutU32(NL80211_ATTR_IFINDEX, wlan0Id);
932 if (result < 0) {
933 HDF_LOGE("failed to put NL80211_ATTR_IFINDEX; result = %{public}d", result);
934 return result;
935 }
936
937 result = request.PutString(NL80211_ATTR_IFNAME, ifname);
938 if (result < 0) {
939 HDF_LOGE("failed to put NL80211_ATTR_IFNAME = %{public}s; result = %{public}d", ifname, result);
940 return result;
941 }
942
943 result = request.PutU32(NL80211_ATTR_IFTYPE, ifaceType);
944 if (result < 0) {
945 HDF_LOGE("failed to put NL80211_ATTR_IFTYPE = %{public}d; result = %{public}d", ifaceType, result);
946 return result;
947 }
948 return HAL_SUCCESS;
949 }
950
DeleteRequest(WifiRequest & request,const char * ifname)951 int DeleteRequest(WifiRequest& request, const char* ifname)
952 {
953 HDF_LOGD("delete ifname = %{public}s\n", ifname);
954 int result = request.Create(NL80211_CMD_DEL_INTERFACE);
955 if (result < 0) {
956 HDF_LOGE("failed to create NL80211_CMD_DEL_INTERFACE; result = %{public}d", result);
957 return result;
958 }
959 result = request.PutU32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname));
960 if (result < 0) {
961 HDF_LOGE("failed to put NL80211_ATTR_IFINDEX = %{public}d; result = %{public}d",
962 if_nametoindex(ifname), result);
963 return result;
964 }
965 result = request.PutString(NL80211_ATTR_IFNAME, ifname);
966 if (result < 0) {
967 HDF_LOGE("failed to put NL80211_ATTR_IFNAME = %{public}s; result = %{public}d", ifname, result);
968 return result;
969 }
970 return HAL_SUCCESS;
971 }
972
CreateIface()973 int CreateIface()
974 {
975 HDF_LOGD("Creating virtual interface");
976 WifiRequest request(FamilyId(), IfaceId());
977 int result = CreateRequest(request, mIfname, mType, mwlan0Id);
978 if (result != HAL_SUCCESS) {
979 HDF_LOGE("failed to create virtual iface request; result = %{public}d\n", result);
980 return result;
981 }
982 auto lock = ReadLockData();
983 result = RequestResponse(request);
984 if (result != HAL_SUCCESS) {
985 HDF_LOGE("failed to Get the virtual iface create response; result = %{public}d\n", result);
986 return result;
987 }
988 HDF_LOGD("Created virtual interface");
989 return HAL_SUCCESS;
990 }
991
DeleteIface()992 int DeleteIface()
993 {
994 HDF_LOGD("Deleting virtual interface");
995 WifiRequest request(FamilyId(), IfaceId());
996 int result = DeleteRequest(request, mIfname);
997 if (result != HAL_SUCCESS) {
998 HDF_LOGE("failed to create virtual iface delete request; result = %{public}d\n", result);
999 return result;
1000 }
1001 auto lock = ReadLockData();
1002 result = RequestResponse(request);
1003 if (result != HAL_SUCCESS) {
1004 HDF_LOGE("failed to Get response of delete virtual interface; result = %{public}d\n", result);
1005 return result;
1006 }
1007 HDF_LOGD("Deleted virtual interface");
1008 return HAL_SUCCESS;
1009 }
1010 protected:
HandleResponse(WifiEvent & reply)1011 int HandleResponse(WifiEvent& reply) override
1012 {
1013 HDF_LOGD("Request complete!");
1014 /* Nothing to do on response! */
1015 return NL_SKIP;
1016 }
1017 };
1018
WifiAddIfaceHalInfo(wifiHandle handle,const char * ifname,bool isVirtual)1019 static WifiError WifiAddIfaceHalInfo(wifiHandle handle, const char* ifname, bool isVirtual)
1020 {
1021 HalInfo *info = nullptr;
1022 int i = 0;
1023
1024 info = (HalInfo *)handle;
1025 if (info == nullptr) {
1026 HDF_LOGE("Could not find info\n");
1027 return HAL_UNKNOWN;
1028 }
1029
1030 HDF_LOGI("%{public}s: add InterfaceInfo for iface: %{public}s\n", __FUNCTION__, ifname);
1031 if (info->numInterfaces == MAX_VIRTUAL_IFACES) {
1032 HDF_LOGE("No space. MAX limit reached for virtual interfaces %{public}d\n", info->numInterfaces);
1033 return HAL_OUT_OF_MEMORY;
1034 }
1035
1036 InterfaceInfo *ifinfo = (InterfaceInfo *)malloc(sizeof(InterfaceInfo));
1037 if (!ifinfo) {
1038 free(info->interfaces);
1039 info->numInterfaces = 0;
1040 return HAL_OUT_OF_MEMORY;
1041 }
1042
1043 ifinfo->handle = handle;
1044 while (i < info->maxNumInterfaces) {
1045 if (info->interfaces[i] == nullptr) {
1046 if (GetInterface(ifname, ifinfo) != HAL_SUCCESS) {
1047 continue;
1048 }
1049 ifinfo->isVirtual = isVirtual;
1050 info->interfaces[i] = ifinfo;
1051 info->numInterfaces++;
1052 HDF_LOGI("%{public}s: Added iface: %{public}s at the index %{public}d\n", __FUNCTION__, ifname, i);
1053 break;
1054 }
1055 i++;
1056 }
1057 return HAL_SUCCESS;
1058 }
1059
CheckWhetherAddIface(wifiHandle handle,const char * ifname)1060 static void CheckWhetherAddIface(wifiHandle handle, const char* ifname)
1061 {
1062 HalInfo *info = (HalInfo *)handle;
1063 int i = 0;
1064
1065 while (i < info->maxNumInterfaces) {
1066 if (info->interfaces[i] != nullptr &&
1067 strncmp(info->interfaces[i]->name,
1068 ifname, sizeof(info->interfaces[i]->name)) == 0) {
1069 HDF_LOGD("%{public}s is exists", ifname);
1070 return;
1071 }
1072 i++;
1073 }
1074 WifiAddIfaceHalInfo((wifiHandle)handle, ifname, false);
1075 }
1076
VendorHalCreateIface(wifiHandle handle,const char * ifname,HalIfaceType ifaceType)1077 static WifiError VendorHalCreateIface(wifiHandle handle, const char* ifname, HalIfaceType ifaceType)
1078 {
1079 int numIfaceHandles = 0;
1080 WifiError ret = HAL_SUCCESS;
1081 wifiInterfaceHandle *ifaceHandles = NULL;
1082 wifiInterfaceHandle wlan0Handle;
1083 nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
1084 uint32_t wlan0Id = if_nametoindex("wlan0");
1085 if (!handle || !wlan0Id) {
1086 HDF_LOGE("%{public}s: Error wifiHandle NULL or wlan0 not present\n", __FUNCTION__);
1087 return HAL_UNKNOWN;
1088 }
1089 /* Do not create interface if already exist. */
1090 if (if_nametoindex(ifname)) {
1091 HDF_LOGI("%{public}s: if_nametoindex(%{public}s) = %{public}d already exists, skip create \n",
1092 __FUNCTION__, ifname, if_nametoindex(ifname));
1093 CheckWhetherAddIface(handle, ifname);
1094 return HAL_SUCCESS;
1095 }
1096 HDF_LOGI("%{public}s: ifname name = %{public}s, type = %{public}u\n", __FUNCTION__, ifname,
1097 ifaceType);
1098 switch (ifaceType) {
1099 case HAL_TYPE_STA:
1100 type = NL80211_IFTYPE_STATION;
1101 break;
1102 case HAL_TYPE_AP:
1103 type = NL80211_IFTYPE_AP;
1104 break;
1105 case HAL_TYPE_P2P:
1106 type = NL80211_IFTYPE_P2P_DEVICE;
1107 break;
1108 case HAL_TYPE_NAN:
1109 type = NL80211_IFTYPE_NAN;
1110 break;
1111 default:
1112 HDF_LOGE("%{public}s: Wrong interface type %{public}u\n", __FUNCTION__, ifaceType);
1113 return HAL_UNKNOWN;
1114 }
1115 wlan0Handle = WifiGetWlanInterface((wifiHandle)handle, ifaceHandles, numIfaceHandles);
1116 VirtualIfaceConfig command(wlan0Handle, ifname, type, wlan0Id);
1117 ret = (WifiError)command.CreateIface();
1118 if (ret != HAL_SUCCESS) {
1119 HDF_LOGE("%{public}s: Iface add Error:%{public}d", __FUNCTION__, ret);
1120 return ret;
1121 }
1122 /* Update dynamic interface list*/
1123 added_ifaces.push_back(std::string(ifname));
1124 ret = WifiAddIfaceHalInfo((wifiHandle)handle, ifname, true);
1125 return ret;
1126 }
1127
WifiClearIfaceHalInfo(wifiHandle handle,const char * ifname)1128 static WifiError WifiClearIfaceHalInfo(wifiHandle handle, const char* ifname)
1129 {
1130 HalInfo *info = (HalInfo *)handle;
1131 int i = 0;
1132
1133 HDF_LOGI("%s: clear hal info for iface: %s\n", __FUNCTION__, ifname);
1134 while (i < info->maxNumInterfaces) {
1135 if ((info->interfaces[i] != nullptr) &&
1136 strncmp(info->interfaces[i]->name, ifname,
1137 sizeof(info->interfaces[i]->name)) == 0) {
1138 free(info->interfaces[i]);
1139 info->interfaces[i] = nullptr;
1140 info->numInterfaces--;
1141 HDF_LOGI("%s: Cleared the index = %d for iface: %s\n", __FUNCTION__, i, ifname);
1142 break;
1143 }
1144 i++;
1145 }
1146 if (i < info->numInterfaces) {
1147 for (int j = i; j < info->numInterfaces; j++) {
1148 info->interfaces[j] = info->interfaces[j + 1];
1149 }
1150 info->interfaces[info->numInterfaces] = nullptr;
1151 }
1152 return HAL_SUCCESS;
1153 }
1154
VendorHalDeleteIface(wifiHandle handle,const char * ifname)1155 static WifiError VendorHalDeleteIface(wifiHandle handle, const char* ifname)
1156 {
1157 int numIfaceHandles = 0;
1158 int i = 0;
1159 WifiError ret = HAL_SUCCESS;
1160 wifiInterfaceHandle *ifaceHandles = NULL;
1161 wifiInterfaceHandle wlan0Handle;
1162 HalInfo *info = (HalInfo *)handle;
1163 uint32_t wlan0Id = if_nametoindex("wlan0");
1164 if (!handle || !wlan0Id) {
1165 HDF_LOGE("%{public}s: Error wifiHandle NULL or wlan0 not present\n", __FUNCTION__);
1166 return HAL_UNKNOWN;
1167 }
1168
1169 while (i < info->maxNumInterfaces) {
1170 if (info->interfaces[i] != nullptr &&
1171 strncmp(info->interfaces[i]->name,
1172 ifname, sizeof(info->interfaces[i]->name)) == 0) {
1173 if (!info->interfaces[i]->isVirtual) {
1174 HDF_LOGI("%{public}s: %{public}s is static iface, skip delete\n",
1175 __FUNCTION__, ifname);
1176 return HAL_SUCCESS;
1177 }
1178 }
1179 i++;
1180 }
1181
1182 HDF_LOGD("%{public}s: iface name=%{public}s\n", __FUNCTION__, ifname);
1183 wlan0Handle = WifiGetWlanInterface((wifiHandle)handle, ifaceHandles, numIfaceHandles);
1184 VirtualIfaceConfig command(wlan0Handle, ifname, (nl80211_iftype)0, 0);
1185 ret = (WifiError)command.DeleteIface();
1186 if (ret != HAL_SUCCESS) {
1187 HDF_LOGE("%{public}s: Iface delete Error:%{public}d", __FUNCTION__, ret);
1188 return ret;
1189 }
1190 added_ifaces.erase(std::remove(added_ifaces.begin(), added_ifaces.end(), std::string(ifname)),
1191 added_ifaces.end());
1192 ret = WifiClearIfaceHalInfo((wifiHandle)handle, ifname);
1193 return ret;
1194 }
1195
VendorHalGetIfaces(wifiHandle handle,int * num,wifiInterfaceHandle ** interfaces)1196 WifiError VendorHalGetIfaces(wifiHandle handle, int *num, wifiInterfaceHandle **interfaces)
1197 {
1198 if (!handle) {
1199 HDF_LOGE("Handle is null");
1200 return HAL_UNKNOWN;
1201 }
1202
1203 HalInfo *info = (HalInfo *)handle;
1204 *interfaces = (wifiInterfaceHandle *)info->interfaces;
1205 *num = info->numInterfaces;
1206
1207 return HAL_SUCCESS;
1208 }
1209
VendorHalGetIfName(wifiInterfaceHandle handle,char * name,size_t size)1210 WifiError VendorHalGetIfName(wifiInterfaceHandle handle, char *name, size_t size)
1211 {
1212 if (!handle) {
1213 HDF_LOGE("Handle is null");
1214 return HAL_UNKNOWN;
1215 }
1216 InterfaceInfo *info = (InterfaceInfo *)handle;
1217 if (strncpy_s(name, IFNAMSIZ, info->name, IFNAMSIZ) != EOK) {
1218 return HAL_UNKNOWN;
1219 }
1220 name[IFNAMSIZ - 1] = '\0';
1221 return HAL_SUCCESS;
1222 }
1223
1224 class SetCountryCodeCommand : public WifiCommand {
1225 public:
SetCountryCodeCommand(wifiInterfaceHandle handle,const char * countryCode)1226 SetCountryCodeCommand(wifiInterfaceHandle handle, const char *countryCode)
1227 : WifiCommand("SetCountryCodeCommand", handle, 0)
1228 {
1229 mCountryCode = countryCode;
1230 }
Create()1231 int Create() override
1232 {
1233 int ret;
1234
1235 ret = mMsg.Create(HAL_OUI, WIFI_SUBCMD_SET_COUNTRY_CODE);
1236 if (ret < 0) {
1237 HDF_LOGE("Can't create message to send to driver - %{public}d", ret);
1238 return ret;
1239 }
1240 nlattr *data = mMsg.AttrStart(NL80211_ATTR_VENDOR_DATA);
1241 ret = mMsg.PutString(HAL_COUNTRY, mCountryCode);
1242 if (ret < 0) {
1243 return ret;
1244 }
1245 mMsg.AttrEnd(data);
1246 return HAL_SUCCESS;
1247 }
1248 private:
1249 const char *mCountryCode;
1250 };
1251
WifiSetCountryCode(wifiInterfaceHandle handle,const char * country_code)1252 static WifiError WifiSetCountryCode(wifiInterfaceHandle handle, const char *country_code)
1253 {
1254 if (!handle) {
1255 HDF_LOGE("Handle is null");
1256 return HAL_INVALID_ARGS;
1257 }
1258 auto lock = ReadLockData();
1259 SetCountryCodeCommand command(handle, country_code);
1260 return (WifiError) command.RequestResponse();
1261 }
1262
1263 class GetAssociatedInfoCommand : public WifiCommand {
1264 public:
GetAssociatedInfoCommand(wifiInterfaceHandle handle,AssociatedInfo * info)1265 GetAssociatedInfoCommand(wifiInterfaceHandle handle, AssociatedInfo *info)
1266 : WifiCommand("GetAssociatedInfoCommand", handle, 0)
1267 {
1268 mAssocInfo = info;
1269 }
Create()1270 int Create() override
1271 {
1272 int ret;
1273
1274 ret = mMsg.Create(FamilyId(), NL80211_CMD_GET_SCAN, NLM_F_DUMP, 0);
1275 if (ret < 0) {
1276 HDF_LOGE("Can't create message to send to driver - %{public}d", ret);
1277 return ret;
1278 }
1279 ret = mMsg.PutU32(NL80211_ATTR_IFINDEX, IfaceId());
1280 if (ret < 0) {
1281 return ret;
1282 }
1283 return HAL_SUCCESS;
1284 }
1285 protected:
HandleResponse(WifiEvent & reply)1286 int HandleResponse(WifiEvent& reply) override
1287 {
1288 uint32_t status;
1289 struct nlattr **attr = reply.Attributes();
1290 struct nlattr *bss[NL80211_BSS_MAX + 1];
1291 struct nla_policy bssPolicy[NL80211_BSS_MAX + 1];
1292 bssPolicy[NL80211_BSS_BSSID].type = NLA_UNSPEC;
1293 bssPolicy[NL80211_BSS_FREQUENCY].type = NLA_U32;
1294 bssPolicy[NL80211_BSS_STATUS].type = NLA_U32;
1295
1296 HDF_LOGD("In GetAssociatedInfoCommand::HandleResponse");
1297 if (!attr[NL80211_ATTR_BSS]) {
1298 HDF_LOGE("HandleResponse: BSS info missing!");
1299 return NL_SKIP;
1300 }
1301 if (nla_parse_nested(bss, NL80211_BSS_MAX, attr[NL80211_ATTR_BSS], bssPolicy) < 0 ||
1302 bss[NL80211_BSS_STATUS] == NULL) {
1303 HDF_LOGD("HandleResponse BSS attr or status missing!");
1304 return NL_SKIP;
1305 }
1306 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
1307 if (status == BSS_STATUS_ASSOCIATED && bss[NL80211_BSS_FREQUENCY]) {
1308 mAssocInfo->associatedFreq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
1309 }
1310 if (status == BSS_STATUS_ASSOCIATED && bss[NL80211_BSS_BSSID]) {
1311 if (memcpy_s(mAssocInfo->associatedBssid, ETH_ADDR_LEN,
1312 nla_data(bss[NL80211_BSS_BSSID]), ETH_ADDR_LEN) != EOK) {
1313 HDF_LOGE("HandleResponse: memcpy_s failed!");
1314 return NL_SKIP;
1315 }
1316 }
1317 return NL_SKIP;
1318 }
1319 private:
1320 AssociatedInfo *mAssocInfo;
1321 };
1322
WifiGetAssociateInfo(wifiInterfaceHandle handle,AssociatedInfo * info)1323 static int WifiGetAssociateInfo(wifiInterfaceHandle handle, AssociatedInfo *info)
1324 {
1325 GetAssociatedInfoCommand command(handle, info);
1326 auto lock = ReadLockData();
1327 return (WifiError) command.RequestResponse();
1328 }
1329
1330 class GetSignalInfoCommand : public WifiCommand {
1331 public:
GetSignalInfoCommand(wifiInterfaceHandle handle,AssociatedInfo assocInfo)1332 GetSignalInfoCommand(wifiInterfaceHandle handle, AssociatedInfo assocInfo)
1333 : WifiCommand("GetSignalInfoCommand", handle, 0)
1334 {
1335 mAssocInfo = assocInfo;
1336 if (memset_s(&mSignalInfo, sizeof(mSignalInfo), 0, sizeof(mSignalInfo)) != EOK) {
1337 HDF_LOGE("memset mSignalInfo failed");
1338 }
1339 }
Create()1340 int Create() override
1341 {
1342 int ret;
1343
1344 ret = mMsg.Create(FamilyId(), NL80211_CMD_GET_STATION, 0, 0);
1345 if (ret < 0) {
1346 HDF_LOGE("Can't create message to send to driver - %{public}d", ret);
1347 return ret;
1348 }
1349 ret = mMsg.PutU32(NL80211_ATTR_IFINDEX, IfaceId());
1350 if (ret < 0) {
1351 return ret;
1352 }
1353 ret = mMsg.Put(NL80211_ATTR_MAC, mAssocInfo.associatedBssid, ETH_ADDR_LEN);
1354 if (ret < 0) {
1355 return ret;
1356 }
1357 mSignalInfo.associatedFreq = static_cast<int32_t>(mAssocInfo.associatedFreq);
1358 return HAL_SUCCESS;
1359 }
GetScanResultsInfo()1360 OHOS::HDI::Wlan::Chip::V1_0::SignalPollResult &GetScanResultsInfo()
1361 {
1362 return mSignalInfo;
1363 }
1364 protected:
HandleResponse(WifiEvent & reply)1365 int HandleResponse(WifiEvent& reply) override
1366 {
1367 struct nlattr **attr = reply.Attributes();
1368 struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
1369 struct nla_policy statsPolicy[NL80211_STA_INFO_MAX + 1];
1370 statsPolicy[NL80211_STA_INFO_SIGNAL].type = NLA_S8;
1371 statsPolicy[NL80211_STA_INFO_RX_BYTES].type = NLA_U32;
1372 statsPolicy[NL80211_STA_INFO_TX_BYTES].type = NLA_U32;
1373 statsPolicy[NL80211_STA_INFO_RX_PACKETS].type = NLA_U32;
1374 statsPolicy[NL80211_STA_INFO_TX_PACKETS].type = NLA_U32;
1375 statsPolicy[NL80211_STA_INFO_TX_FAILED].type = NLA_U32;
1376 statsPolicy[NL80211_STA_INFO_NOISE].type = NLA_S32;
1377 statsPolicy[NL80211_STA_INFO_SNR].type = NLA_S32;
1378 statsPolicy[NL80211_STA_INFO_CNAHLOAD].type = NLA_S32;
1379 statsPolicy[NL80211_STA_INFO_UL_DELAY].type = NLA_S32;
1380 statsPolicy[NL80211_STA_INFO_UL_DELAY_ARRAY].type = NLA_U16;
1381 statsPolicy[NL80211_STA_INFO_TX_TIME].type = NLA_U16;
1382 statsPolicy[NL80211_STA_INFO_BEACON_RSSI].type = NLA_S8;
1383 statsPolicy[NL80211_STA_INFO_CHLOAD_SELF].type = NLA_U16;
1384 statsPolicy[NL80211_STA_INFO_SIGNAL_DUAL].type = NLA_S8;
1385 statsPolicy[NL80211_STA_INFO_TX_PPDU_CNT].type = NLA_U32;
1386 statsPolicy[NL80211_STA_INFO_TX_PPDU_RETRY_CNT].type = NLA_U32;
1387 statsPolicy[NL80211_STA_INFO_PPDU_PER].type = NLA_U8;
1388 statsPolicy[NL80211_STA_INFO_TX_MCS].type = NLA_U8;
1389 statsPolicy[NL80211_STA_INFO_CWMIN].type = NLA_U8;
1390 statsPolicy[NL80211_STA_INFO_CWMAX].type = NLA_S8;
1391 statsPolicy[NL80211_STA_INFO_ULDELAY_CDF].type = NLA_U16;
1392 statsPolicy[NL80211_STA_INFO_TX_TIME_CDF].type = NLA_U16;
1393
1394 if (!attr[NL80211_ATTR_STA_INFO]) {
1395 HDF_LOGE("HandleResponse: sta stats missing!");
1396 return NL_SKIP;
1397 }
1398 if (nla_parse_nested(stats, NL80211_STA_INFO_MAX, attr[NL80211_ATTR_STA_INFO], statsPolicy) < 0) {
1399 HDF_LOGE("HandleResponse: nla_parse_nested NL80211_ATTR_STA_INFO failed!");
1400 return NL_SKIP;
1401 }
1402 FillSignal(stats, NL80211_STA_INFO_MAX + 1);
1403 FillSignalExt(stats, NL80211_STA_INFO_MAX + 1);
1404 FillSignalAiWifi(stats, NL80211_STA_INFO_MAX + 1);
1405 FillSignalRate(stats, NL80211_STA_INFO_MAX + 1);
1406 return NL_SKIP;
1407 }
1408 private:
1409 OHOS::HDI::Wlan::Chip::V1_0::SignalPollResult mSignalInfo;
1410 AssociatedInfo mAssocInfo;
1411
FillSignal(struct nlattr ** stats,uint32_t size)1412 void FillSignal(struct nlattr **stats, uint32_t size)
1413 {
1414 if (size < NL80211_STA_INFO_MAX + 1) {
1415 HDF_LOGE("size of stats is not enough");
1416 return;
1417 }
1418
1419 if (stats[NL80211_STA_INFO_SIGNAL] != nullptr) {
1420 mSignalInfo.currentRssi = nla_get_s8(stats[NL80211_STA_INFO_SIGNAL]);
1421 }
1422 if (stats[NL80211_STA_INFO_TX_BYTES] != nullptr) {
1423 mSignalInfo.currentTxBytes = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
1424 }
1425 if (stats[NL80211_STA_INFO_RX_BYTES] != nullptr) {
1426 mSignalInfo.currentRxBytes = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
1427 }
1428 if (stats[NL80211_STA_INFO_TX_PACKETS] != nullptr) {
1429 mSignalInfo.currentTxPackets = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
1430 }
1431 if (stats[NL80211_STA_INFO_RX_PACKETS] != nullptr) {
1432 mSignalInfo.currentRxPackets = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
1433 }
1434 if (stats[NL80211_STA_INFO_TX_FAILED] != nullptr) {
1435 mSignalInfo.currentTxFailed = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
1436 }
1437 }
1438
FillSignalExt(struct nlattr ** stats,uint32_t size)1439 void FillSignalExt(struct nlattr **stats, uint32_t size)
1440 {
1441 if (size < NL80211_STA_INFO_MAX + 1) {
1442 HDF_LOGE("size of stats is not enough");
1443 return;
1444 }
1445
1446 if (stats[NL80211_STA_INFO_NOISE] != NULL) {
1447 mSignalInfo.currentNoise = nla_get_s32(stats[NL80211_STA_INFO_NOISE]);
1448 }
1449 if (stats[NL80211_STA_INFO_SNR] != NULL) {
1450 mSignalInfo.currentSnr = nla_get_s32(stats[NL80211_STA_INFO_SNR]);
1451 }
1452 if (stats[NL80211_STA_INFO_CNAHLOAD] != NULL) {
1453 mSignalInfo.currentChload = nla_get_s32(stats[NL80211_STA_INFO_CNAHLOAD]);
1454 }
1455 if (stats[NL80211_STA_INFO_UL_DELAY] != NULL) {
1456 mSignalInfo.currentUlDelay = nla_get_s32(stats[NL80211_STA_INFO_UL_DELAY]);
1457 }
1458 if (stats[NL80211_STA_INFO_UL_DELAY_ARRAY] != NULL) {
1459 uint16_t *ulDelayArray = (uint16_t *)nla_data(stats[NL80211_STA_INFO_UL_DELAY_ARRAY]);
1460 HDF_LOGD("mSignalInfo.ulDelayArray[0]=%{public}d ", ulDelayArray[0]);
1461 }
1462 if (stats[NL80211_STA_INFO_TX_TIME] != NULL) {
1463 uint16_t *txTime = (uint16_t *)nla_data(stats[NL80211_STA_INFO_TX_TIME]);
1464 HDF_LOGD("mSignalInfo.txTime[0]=%{public}d ", txTime[0]);
1465 }
1466 if (stats[NL80211_STA_INFO_CHLOAD_SELF] != NULL) {
1467 mSignalInfo.chloadSelf = nla_get_u16(stats[NL80211_STA_INFO_CHLOAD_SELF]);
1468 }
1469 if (stats[NL80211_STA_INFO_SIGNAL_DUAL] != NULL) {
1470 int8_t *rptRssi = (int8_t *)nla_data(stats[NL80211_STA_INFO_SIGNAL_DUAL]);
1471 mSignalInfo.c0Rssi = rptRssi[0];
1472 mSignalInfo.c1Rssi = rptRssi[1];
1473 }
1474 FillSignalAiWifi(stats, NL80211_STA_INFO_MAX + 1);
1475 }
1476
FillSignalAiWifi(struct nlattr ** stats,uint32_t size)1477 void FillSignalAiWifi(struct nlattr **stats, uint32_t size)
1478 {
1479 const int beaconRssiMaxLen = 10;
1480 if (size < NL80211_STA_INFO_MAX + 1) {
1481 HDF_LOGE("size of stats is not enough");
1482 return;
1483 }
1484 if (stats[NL80211_STA_INFO_BEACON_RSSI] != NULL) {
1485 int8_t *beaconRssi = (int8_t *)nla_data(stats[NL80211_STA_INFO_BEACON_RSSI]);
1486 int beaconRssiLen = (int32_t)(nla_len(stats[NL80211_STA_INFO_BEACON_RSSI]));
1487 std::vector<uint8_t> beaconRssiVec(beaconRssi, beaconRssi + beaconRssiLen);
1488 if (beaconRssiLen > 0 && beaconRssiLen <= beaconRssiMaxLen) {
1489 mSignalInfo.ext.insert(mSignalInfo.ext.end(), beaconRssiVec.begin(), beaconRssiVec.end());
1490 }
1491 }
1492 if (stats[NL80211_STA_INFO_TX_PPDU_CNT] != NULL) {
1493 uint32_t txPpduCnt = nla_get_u32(stats[NL80211_STA_INFO_TX_PPDU_CNT]);
1494 mSignalInfo.ext.push_back(static_cast<uint8_t>(txPpduCnt & MASK_CSMA));
1495 mSignalInfo.ext.push_back(static_cast<uint8_t>((txPpduCnt >> OFFSET_8) & MASK_CSMA));
1496 mSignalInfo.ext.push_back(static_cast<uint8_t>((txPpduCnt >> OFFSET_16) & MASK_CSMA));
1497 mSignalInfo.ext.push_back(static_cast<uint8_t>((txPpduCnt >> OFFSET_24) & MASK_CSMA));
1498 }
1499 if (stats[NL80211_STA_INFO_TX_PPDU_RETRY_CNT] != NULL) {
1500 uint32_t txPpduRetryCnt = nla_get_u32(stats[NL80211_STA_INFO_TX_PPDU_RETRY_CNT]);
1501 mSignalInfo.ext.push_back(static_cast<uint8_t>(txPpduRetryCnt & MASK_CSMA));
1502 mSignalInfo.ext.push_back(static_cast<uint8_t>((txPpduRetryCnt >> OFFSET_8) & MASK_CSMA));
1503 mSignalInfo.ext.push_back(static_cast<uint8_t>((txPpduRetryCnt >> OFFSET_16) & MASK_CSMA));
1504 mSignalInfo.ext.push_back(static_cast<uint8_t>((txPpduRetryCnt >> OFFSET_24) & MASK_CSMA));
1505 }
1506 if (stats[NL80211_STA_INFO_PPDU_PER] != NULL) {
1507 uint8_t ppduPer = nla_get_u8(stats[NL80211_STA_INFO_PPDU_PER]);
1508 mSignalInfo.ext.push_back(ppduPer);
1509 }
1510 if (stats[NL80211_STA_INFO_TX_MCS] != NULL) {
1511 uint8_t txMcs = nla_get_u8(stats[NL80211_STA_INFO_TX_MCS]);
1512 mSignalInfo.ext.push_back(txMcs);
1513 }
1514 FillSignalAiWifiEx(stats, size);
1515 }
FillSignalAiWifiEx(struct nlattr ** stats,uint32_t size)1516 void FillSignalAiWifiEx(struct nlattr **stats, uint32_t size)
1517 {
1518 if (size < NL80211_STA_INFO_MAX + 1) {
1519 HDF_LOGE("size of stats is not enough");
1520 return;
1521 }
1522 if (stats[NL80211_STA_INFO_CWMIN] != NULL) {
1523 uint8_t cwMin = nla_get_u8(stats[NL80211_STA_INFO_CWMIN]);
1524 mSignalInfo.ext.push_back(cwMin);
1525 }
1526 if (stats[NL80211_STA_INFO_CWMAX] != NULL) {
1527 uint8_t cwMax = nla_get_u8(stats[NL80211_STA_INFO_CWMAX]);
1528 mSignalInfo.ext.push_back(cwMax);
1529 }
1530 if (stats[NL80211_STA_INFO_ULDELAY_CDF] != NULL) {
1531 uint8_t *uldelayCdf = (uint8_t *)nla_data(stats[NL80211_STA_INFO_ULDELAY_CDF]);
1532 int uldelayCdfLen = (int32_t)(nla_len(stats[NL80211_STA_INFO_ULDELAY_CDF]));
1533 for (int i = 0; i < uldelayCdfLen; ++i) {
1534 mSignalInfo.ext.push_back(static_cast<uint8_t>(uldelayCdf[i]));
1535 }
1536 }
1537 if (stats[NL80211_STA_INFO_TX_TIME_CDF] != NULL) {
1538 uint8_t *txtimeCdf = (uint8_t *)nla_data(stats[NL80211_STA_INFO_TX_TIME_CDF]);
1539 int txtimeCdfLen = (int32_t)(nla_len(stats[NL80211_STA_INFO_TX_TIME_CDF]));
1540 for (int i = 0; i < txtimeCdfLen; ++i) {
1541 mSignalInfo.ext.push_back(static_cast<uint8_t>(txtimeCdf[i]));
1542 }
1543 }
1544 }
1545
FillSignalRate(struct nlattr ** stats,uint32_t size)1546 void FillSignalRate(struct nlattr **stats, uint32_t size)
1547 {
1548 struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
1549 struct nla_policy ratePolicy[NL80211_RATE_INFO_MAX + 1];
1550 ratePolicy[NL80211_RATE_INFO_BITRATE].type = NLA_U16;
1551 ratePolicy[NL80211_RATE_INFO_BITRATE32].type = NLA_U32;
1552
1553 if (size < NL80211_STA_INFO_MAX + 1) {
1554 HDF_LOGE("FillSignalRate: size of stats is not enough");
1555 return;
1556 }
1557 if (stats[NL80211_STA_INFO_RX_BITRATE] != NULL &&
1558 nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_RX_BITRATE], ratePolicy) == 0) {
1559 if (rate[NL80211_RATE_INFO_BITRATE32] != nullptr) {
1560 mSignalInfo.rxBitrate = (int32_t)nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
1561 } else if (rate[NL80211_RATE_INFO_BITRATE] != nullptr) {
1562 mSignalInfo.rxBitrate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
1563 }
1564 }
1565 if (stats[NL80211_STA_INFO_TX_BITRATE] != NULL &&
1566 nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_TX_BITRATE], ratePolicy) == 0) {
1567 if (rate[NL80211_RATE_INFO_BITRATE32] != nullptr) {
1568 mSignalInfo.txBitrate = (int32_t)nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
1569 } else if (rate[NL80211_RATE_INFO_BITRATE] != nullptr) {
1570 mSignalInfo.txBitrate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
1571 }
1572 }
1573 }
1574 };
1575
1576
WifiGetSignalInfo(wifiInterfaceHandle handle,OHOS::HDI::Wlan::Chip::V1_0::SignalPollResult & signalPollresult)1577 static WifiError WifiGetSignalInfo(wifiInterfaceHandle handle,
1578 OHOS::HDI::Wlan::Chip::V1_0::SignalPollResult& signalPollresult)
1579 {
1580 AssociatedInfo associatedInfo;
1581
1582 if (!handle) {
1583 HDF_LOGE("Handle is null");
1584 return HAL_INVALID_ARGS;
1585 }
1586 (void)memset_s(&associatedInfo, sizeof(associatedInfo), 0, sizeof(associatedInfo));
1587 if (WifiGetAssociateInfo(handle, &associatedInfo) < 0) {
1588 return HAL_NONE;
1589 }
1590 GetSignalInfoCommand command(handle, associatedInfo);
1591 auto lock = ReadLockData();
1592 command.RequestResponse();
1593 signalPollresult = command.GetScanResultsInfo();
1594 return HAL_SUCCESS;
1595 }
1596
RegisterIfaceCallBack(const char * ifaceName,WifiCallbackHandler OnCallbackEvent)1597 static WifiError RegisterIfaceCallBack(const char *ifaceName, WifiCallbackHandler OnCallbackEvent)
1598 {
1599 std::unique_lock<std::mutex> lock(g_callbackMutex);
1600 if (ifaceName == nullptr) {
1601 HDF_LOGE(" ifaceName is null!");
1602 return HAL_NONE;
1603 }
1604
1605 g_halInfo->ifaceCallBack = OnCallbackEvent;
1606
1607 return HAL_SUCCESS;
1608 }
1609
IsSupportCoex(bool & isCoex)1610 WifiError IsSupportCoex(bool& isCoex)
1611 {
1612 isCoex = false;
1613 return HAL_SUCCESS;
1614 }
1615
SendCmdToDriver(const char * ifaceName,int32_t commandId,const std::vector<int8_t> & paramData)1616 static WifiError SendCmdToDriver(const char *ifaceName, int32_t commandId, const std::vector<int8_t>& paramData)
1617 {
1618 return HAL_SUCCESS;
1619 }
1620