• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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