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