• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <net/if.h>
17 #include <arpa/inet.h>
18 #include <dirent.h>
19 #include <netlink-private/types.h>
20 #include <netlink/genl/ctrl.h>
21 #include <netlink/genl/genl.h>
22 #include <netlink/handlers.h>
23 #include <securec.h>
24 #include <stdbool.h>
25 #include <stdio.h>
26 #include <sys/ioctl.h>
27 #include <sys/socket.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31 #include <linux/ethtool.h>
32 #include <linux/if_arp.h>
33 #include <linux/netlink.h>
34 #include <linux/nl80211.h>
35 #include <linux/sockios.h>
36 #include <linux/wireless.h>
37 #include <linux/version.h>
38 
39 #include "../wifi_common_cmd.h"
40 #include "hilog/log.h"
41 #include "netlink_adapter.h"
42 #include "hdf_dlist.h"
43 #include "parameter.h"
44 
45 #define VENDOR_ID 0x001A11
46 
47 // vendor subcmd
48 #define WIFI_SUBCMD_SET_COUNTRY_CODE   0x100E
49 #define WIFI_SUBCMD_SET_RANDOM_MAC_OUI 0x100C
50 
51 #define WAITFORMUTEX  100000
52 #define WAITFORTHREAD 100000
53 #define RETRIES       30
54 
55 #define STR_WLAN0     "wlan0"
56 #define STR_WLAN1     "wlan1"
57 #define STR_P2P0      "p2p0"
58 #define STR_P2P0_X    "p2p0-"
59 #define NET_DEVICE_INFO_PATH "/sys/class/net"
60 
61 #define PRIMARY_ID_POWER_MODE   0x8bfd
62 #define SECONDARY_ID_POWER_MODE 0x101
63 #define SET_POWER_MODE_SLEEP     "pow_mode sleep"
64 #define SET_POWER_MODE_INIT      "pow_mode init"
65 #define SET_POWER_MODE_THIRD     "pow_mode third"
66 #define GET_POWER_MODE           "get_pow_mode"
67 
68 #define CMD_SET_CLOSE_GO_CAC      "SET_CLOSE_GO_CAC"
69 #define CMD_SET_CHANGE_GO_CHANNEL "CMD_SET_CHANGE_GO_CHANNEL"
70 #define CMD_SET_GO_DETECT_RADAR   "CMD_SET_GO_DETECT_RADAR"
71 #define CMD_SET_DYNAMIC_DBAC_MODE "SET_DYNAMIC_DBAC_MODE"
72 #define CMD_SET_P2P_SCENES        "CMD_SET_P2P_SCENES"
73 #define CMD_GET_AP_BANDWIDTH      "GET_AP_BANDWIDTH"
74 #define CMD_SET_RX_MGMT_REMAIN_ON_CHANNEL "RX_MGMT_REMAIN_ON_CHANNEL"
75 
76 #define P2P_BUF_SIZE              64
77 #define MAX_PRIV_CMD_SIZE         4096
78 #define LOW_LITMIT_FREQ_2_4G      2400
79 #define HIGH_LIMIT_FREQ_2_4G      2500
80 #define LOW_LIMIT_FREQ_5G         5100
81 #define HIGH_LIMIT_FREQ_5G        5900
82 #define INTERFACE_UP              0x1 /* interface is up */
83 #define MAX_INTERFACE_NAME_SIZE   16
84 
BIT(uint8_t x)85 static inline uint32_t BIT(uint8_t x)
86 {
87     return 1U << x;
88 }
89 #define STA_DRV_DATA_TX_MCS BIT(0)
90 #define STA_DRV_DATA_RX_MCS BIT(1)
91 #define STA_DRV_DATA_TX_VHT_MCS BIT(2)
92 #define STA_DRV_DATA_RX_VHT_MCS BIT(3)
93 #define STA_DRV_DATA_TX_VHT_NSS BIT(4)
94 #define STA_DRV_DATA_RX_VHT_NSS BIT(5)
95 #define STA_DRV_DATA_TX_SHORT_GI BIT(6)
96 #define STA_DRV_DATA_RX_SHORT_GI BIT(7)
97 #define STA_DRV_DATA_LAST_ACK_RSSI BIT(8)
98 
99 #define WLAN_IFACE_LENGTH 4
100 #define P2P_IFACE_LENGTH 3
101 #ifndef KERNEL_VERSION
102 #define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
103 #endif
104 
105 #define SUBCHIP_WIFI_PROP "ohos.boot.odm.conn.schiptype"
106 #define SUPPORT_COEXCHIP "bisheng"
107 #define SUBCHIP_WIFI_PROP_LEN 10
108 #define SUPPORT_COEXCHIP_LEN 7
109 
110 #define NETLINK_CAP_ACK 10
111 #define NETLINK_EXT_ACK 11
112 #define SOL_NETLINK 270
113 #define RECV_MAX_COUNT 100
114 
115 // vendor attr
116 enum AndrWifiAttr {
117 #if (defined(LINUX_VERSION_CODE) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
118     WIFI_ATTRIBUTE_INVALID,
119 #endif
120     WIFI_ATTRIBUTE_NUM_FEATURE_SET,
121     WIFI_ATTRIBUTE_FEATURE_SET,
122     WIFI_ATTRIBUTE_RANDOM_MAC_OUI,
123     WIFI_ATTRIBUTE_NODFS_SET,
124     WIFI_ATTRIBUTE_COUNTRY
125 };
126 
127 struct FamilyData {
128     const char *group;
129     int32_t id;
130 };
131 
132 struct WifiHalInfo {
133     struct nl_sock *cmdSock;
134     struct nl_sock *eventSock;
135     struct nl_sock *ctrlSock;
136     int32_t familyId;
137 
138     // thread controller info
139     pthread_t thread;
140     enum ThreadStatus status;
141     pthread_mutex_t mutex;
142 };
143 
144 typedef struct {
145     void *buf;
146     uint16_t length;
147     uint16_t flags;
148 } DataPoint;
149 
150 union HwprivReqData {
151     char name[IFNAMSIZ];
152     int32_t mode;
153     DataPoint point;
154 };
155 
156 typedef struct {
157     char interfaceName[IFNAMSIZ];
158     union HwprivReqData data;
159 } HwprivIoctlData;
160 
161 typedef struct {
162 #if (defined(LINUX_VERSION_CODE) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
163     uint8_t *buf;
164     uint32_t size;
165     uint32_t len;
166 #else
167     uint32_t size;
168     uint32_t len;
169     uint8_t *buf;
170 #endif
171 } WifiPrivCmd;
172 
173 #define SLOW_SCAN_INTERVAL_MULTIPLIER 3
174 #define FAST_SCAN_ITERATIONS 3
175 #define BITNUMS_OF_ONE_BYTE 8
176 #define SCHED_SCAN_PLANS_ATTR_INDEX1 1
177 #define SCHED_SCAN_PLANS_ATTR_INDEX2 2
178 #define MS_PER_SECOND 1000
179 
180 typedef struct {
181     uint8_t maxNumScanSsids;
182     uint8_t maxNumSchedScanSsids;
183     uint8_t maxMatchSets;
184     uint32_t maxNumScanPlans;
185     uint32_t maxScanPlanInterval;
186     uint32_t maxScanPlanIterations;
187 } ScanCapabilities;
188 
189 typedef struct {
190     bool supportsRandomMacSchedScan;
191     bool supportsLowPowerOneshotScan;
192     bool supportsExtSchedScanRelativeRssi;
193 } WiphyFeatures;
194 
195 typedef struct {
196     ScanCapabilities scanCapabilities;
197     WiphyFeatures wiphyFeatures;
198 } WiphyInfo;
199 
200 struct SsidListNode {
201     WifiDriverScanSsid ssidInfo;
202     struct DListHead entry;
203 };
204 
205 struct FreqListNode {
206     int32_t freq;
207     struct DListHead entry;
208 };
209 
210 static struct WifiHalInfo g_wifiHalInfo = {0};
211 
212 static int32_t GetWiphyInfo(const uint32_t wiphyIndex, WiphyInfo *wiphyInfo);
213 static int32_t GetWiphyIndex(const char *ifName, uint32_t *wiphyIndex);
214 
OpenNetlinkSocket(void)215 static struct nl_sock *OpenNetlinkSocket(void)
216 {
217     struct nl_sock *sock = NULL;
218 
219     sock = nl_socket_alloc();
220     if (sock == NULL) {
221         HILOG_ERROR(LOG_CORE, "%s: fail to alloc socket", __FUNCTION__);
222         return NULL;
223     }
224 
225     if (nl_connect(sock, NETLINK_GENERIC) != 0) {
226         HILOG_ERROR(LOG_CORE, "%s: fail to connect socket", __FUNCTION__);
227         nl_socket_free(sock);
228         return NULL;
229     }
230 
231     return sock;
232 }
233 
CloseNetlinkSocket(struct nl_sock * sock)234 static void CloseNetlinkSocket(struct nl_sock *sock)
235 {
236     if (sock != NULL) {
237         nl_socket_free(sock);
238     }
239 }
240 
ConnectCmdSocket(void)241 static int32_t ConnectCmdSocket(void)
242 {
243     g_wifiHalInfo.cmdSock = OpenNetlinkSocket();
244     if (g_wifiHalInfo.cmdSock == NULL) {
245         HILOG_ERROR(LOG_CORE, "%s: fail to open cmd socket", __FUNCTION__);
246         return RET_CODE_FAILURE;
247     }
248 
249     nl_socket_disable_seq_check(g_wifiHalInfo.cmdSock);
250     // send find familyId result to Controller
251     g_wifiHalInfo.familyId = genl_ctrl_resolve(g_wifiHalInfo.cmdSock, NL80211_GENL_NAME);
252     if (g_wifiHalInfo.familyId < 0) {
253         HILOG_ERROR(LOG_CORE, "%s: fail to resolve family", __FUNCTION__);
254         CloseNetlinkSocket(g_wifiHalInfo.cmdSock);
255         g_wifiHalInfo.cmdSock = NULL;
256         return RET_CODE_FAILURE;
257     }
258     HILOG_INFO(LOG_CORE, "%s: family id: %d", __FUNCTION__, g_wifiHalInfo.familyId);
259     return RET_CODE_SUCCESS;
260 }
261 
DisconnectCmdSocket(void)262 static void DisconnectCmdSocket(void)
263 {
264     CloseNetlinkSocket(g_wifiHalInfo.cmdSock);
265     g_wifiHalInfo.cmdSock = NULL;
266 }
267 
ConnectCtrlSocket(void)268 static int32_t ConnectCtrlSocket(void)
269 {
270     g_wifiHalInfo.ctrlSock = OpenNetlinkSocket();
271     if (g_wifiHalInfo.ctrlSock == NULL) {
272         HILOG_ERROR(LOG_CORE, "%s: fail to open ctrl socket", __FUNCTION__);
273         return RET_CODE_FAILURE;
274     }
275 
276     if (nl_socket_set_nonblocking(g_wifiHalInfo.ctrlSock) != 0) {
277         HILOG_ERROR(LOG_CORE, "%s: fail to set nonblocking socket", __FUNCTION__);
278         CloseNetlinkSocket(g_wifiHalInfo.ctrlSock);
279         g_wifiHalInfo.ctrlSock = NULL;
280         return RET_CODE_FAILURE;
281     }
282 
283     // send find familyId result to Controller
284     g_wifiHalInfo.familyId = genl_ctrl_resolve(g_wifiHalInfo.ctrlSock, NL80211_GENL_NAME);
285     if (g_wifiHalInfo.familyId < 0) {
286         HILOG_ERROR(LOG_CORE, "%s: fail to resolve family", __FUNCTION__);
287         CloseNetlinkSocket(g_wifiHalInfo.ctrlSock);
288         g_wifiHalInfo.ctrlSock = NULL;
289         return RET_CODE_FAILURE;
290     }
291     HILOG_INFO(LOG_CORE, "%s: family id: %d", __FUNCTION__, g_wifiHalInfo.familyId);
292     return RET_CODE_SUCCESS;
293 }
294 
DisconnectCtrlSocket(void)295 static void DisconnectCtrlSocket(void)
296 {
297     CloseNetlinkSocket(g_wifiHalInfo.ctrlSock);
298     g_wifiHalInfo.ctrlSock = NULL;
299 }
300 
CmdSocketErrorHandler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)301 static int32_t CmdSocketErrorHandler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
302 {
303     int32_t *ret = (int32_t *)arg;
304 
305     *ret = err->error;
306     return NL_SKIP;
307 }
308 
CmdSocketFinishHandler(struct nl_msg * msg,void * arg)309 static int32_t CmdSocketFinishHandler(struct nl_msg *msg, void *arg)
310 {
311     int32_t *ret = (int32_t *)arg;
312 
313     *ret = 0;
314     return NL_SKIP;
315 }
316 
CmdSocketAckHandler(struct nl_msg * msg,void * arg)317 static int32_t CmdSocketAckHandler(struct nl_msg *msg, void *arg)
318 {
319     int32_t *err = (int32_t *)arg;
320 
321     *err = 0;
322     return NL_STOP;
323 }
324 
NetlinkSetCallback(const RespHandler handler,int32_t * error,void * data)325 static struct nl_cb *NetlinkSetCallback(const RespHandler handler, int32_t *error, void *data)
326 {
327     struct nl_cb *cb = NULL;
328 
329     cb = nl_cb_alloc(NL_CB_DEFAULT);
330     if (cb == NULL) {
331         HILOG_ERROR(LOG_CORE, "%s: nl_cb_alloc failed", __FUNCTION__);
332         return NULL;
333     }
334     nl_cb_err(cb, NL_CB_CUSTOM, CmdSocketErrorHandler, error);
335     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, CmdSocketFinishHandler, error);
336     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, CmdSocketAckHandler, error);
337     if (handler != NULL) {
338         nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handler, data);
339     }
340     return cb;
341 }
342 
PthreadMutexLock(void)343 static int32_t PthreadMutexLock(void)
344 {
345     int32_t rc;
346     int32_t count = 0;
347 
348     while ((rc = pthread_mutex_trylock(&g_wifiHalInfo.mutex)) == EBUSY) {
349         if (count < RETRIES) {
350             HILOG_ERROR(LOG_CORE, "%s: pthread b trylock", __FUNCTION__);
351             count++;
352             usleep(WAITFORMUTEX);
353         } else {
354             HILOG_ERROR(LOG_CORE, "%s: pthread trylock timeout", __FUNCTION__);
355             return RET_CODE_SUCCESS;
356         }
357     }
358     return rc;
359 }
360 
NetlinkSendCmdSync(struct nl_msg * msg,const RespHandler handler,void * data)361 int32_t NetlinkSendCmdSync(struct nl_msg *msg, const RespHandler handler, void *data)
362 {
363     HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
364     int32_t rc = RET_CODE_FAILURE;
365     struct nl_cb *cb = NULL;
366 
367     if (g_wifiHalInfo.cmdSock == NULL) {
368         HILOG_ERROR(LOG_CORE, "%s: sock is null", __FUNCTION__);
369         return RET_CODE_INVALID_PARAM;
370     }
371 
372     if (PthreadMutexLock() != RET_CODE_SUCCESS) {
373         HILOG_ERROR(LOG_CORE, "%s: pthread trylock failed", __FUNCTION__);
374         return RET_CODE_FAILURE;
375     }
376 
377     /* try to set NETLINK_EXT_ACK to 1, ignoring errors */
378     int32_t opt = 1;
379     setsockopt(nl_socket_get_fd(g_wifiHalInfo.cmdSock), SOL_NETLINK, NETLINK_EXT_ACK, &opt, sizeof(opt));
380 
381     /* try to set NETLINK_CAP_ACK to 1, ignoring errors */
382     opt = 1;
383     setsockopt(nl_socket_get_fd(g_wifiHalInfo.cmdSock), SOL_NETLINK, NETLINK_CAP_ACK, &opt, sizeof(opt));
384 
385     do {
386         rc = nl_send_auto(g_wifiHalInfo.cmdSock, msg);
387         HILOG_INFO(LOG_CORE, "nl_send_auto cmdSock, rc=%{public}d", rc);
388         if (rc < 0) {
389             HILOG_ERROR(LOG_CORE, "%s: nl_send_auto failed", __FUNCTION__);
390             break;
391         }
392 
393         int32_t error = 1;
394         cb = NetlinkSetCallback(handler, &error, data);
395         if (cb == NULL) {
396             HILOG_ERROR(LOG_CORE, "%s: nl_cb_alloc failed", __FUNCTION__);
397             rc = RET_CODE_FAILURE;
398             break;
399         }
400 
401         /* wait for reply */
402         int32_t recv_count = 0;
403         while (error > 0) {
404             rc = nl_recvmsgs(g_wifiHalInfo.cmdSock, cb);
405             if (rc == -NLE_DUMP_INTR) {
406                 HILOG_ERROR(LOG_CORE, "nl_recvmsgs failed: rc=%{public}d, errno=%{public}d, (%{public}s)", rc, errno,
407                     strerror(errno));
408                 error = -NLE_AGAIN;
409                 rc = RET_CODE_NOT_AVAILABLE;
410             } else if (rc < 0) {
411                 HILOG_ERROR(LOG_CORE, "nl_recvmsgs failed: rc=%{public}d, errno=%{public}d, (%{public}s)", rc, errno,
412                     strerror(errno));
413             }
414 
415             if (rc == -NLE_NOMEM || recv_count != 0) {
416                 recv_count++;
417             }
418 
419             if (recv_count >= RECV_MAX_COUNT) {
420                 HILOG_ERROR(LOG_CORE, "nl_recvmsgs failed times overs max count!");
421                 error = -NLE_NOMEM;
422                 rc = RET_CODE_NOMEM;
423             }
424             HILOG_INFO(LOG_CORE, "nl_recvmsgs cmdSock, rc=%{public}d error=%{public}d", rc, error);
425         }
426 
427         if (error == -NLE_MSGTYPE_NOSUPPORT) {
428             HILOG_ERROR(LOG_CORE, "%s: Netlink message type is not supported", __FUNCTION__);
429             rc = RET_CODE_NOT_SUPPORT;
430         }
431         if (error == -EBUSY) {
432             HILOG_ERROR(LOG_CORE, "%s: Device is busy.", __FUNCTION__);
433             rc = RET_CODE_DEVICE_BUSY;
434         }
435         nl_cb_put(cb);
436     } while (0);
437 
438     pthread_mutex_unlock(&g_wifiHalInfo.mutex);
439     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
440     return rc;
441 }
442 
ParseFamilyId(struct nlattr * attr,struct FamilyData * familyData)443 static void ParseFamilyId(struct nlattr *attr, struct FamilyData *familyData)
444 {
445     struct nlattr *tmp = NULL;
446     void *data = NULL;
447     int32_t len;
448     int32_t i;
449 
450     nla_for_each_nested(tmp, attr, i) {
451         struct nlattr *attrMcastGrp[CTRL_ATTR_MCAST_GRP_MAX + 1];
452         data = nla_data(tmp);
453         len = nla_len(tmp);
454         nla_parse(attrMcastGrp, CTRL_ATTR_MCAST_GRP_MAX, data, len, NULL);
455         data = nla_data(attrMcastGrp[CTRL_ATTR_MCAST_GRP_NAME]);
456         len = nla_len(attrMcastGrp[CTRL_ATTR_MCAST_GRP_NAME]);
457         if (attrMcastGrp[CTRL_ATTR_MCAST_GRP_NAME] && attrMcastGrp[CTRL_ATTR_MCAST_GRP_ID] &&
458             strncmp((char *)data, familyData->group, len) == 0) {
459             familyData->id = (int32_t)nla_get_u32(attrMcastGrp[CTRL_ATTR_MCAST_GRP_ID]);
460         }
461     }
462 }
463 
FamilyIdHandler(struct nl_msg * msg,void * arg)464 static int32_t FamilyIdHandler(struct nl_msg *msg, void *arg)
465 {
466     struct FamilyData *familyData = (struct FamilyData *)arg;
467     struct genlmsghdr *hdr = NULL;
468     struct nlattr *attr[CTRL_ATTR_MAX + 1];
469     void *data = NULL;
470     int32_t len;
471 
472     hdr = nlmsg_data(nlmsg_hdr(msg));
473     if (hdr == NULL) {
474         HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
475         return NL_SKIP;
476     }
477 
478     data = genlmsg_attrdata(hdr, 0);
479     len = genlmsg_attrlen(hdr, 0);
480     nla_parse(attr, CTRL_ATTR_MAX, data, len, NULL);
481     if (!attr[CTRL_ATTR_MCAST_GROUPS]) {
482         return NL_SKIP;
483     }
484 
485     ParseFamilyId(attr[CTRL_ATTR_MCAST_GROUPS], familyData);
486 
487     return NL_SKIP;
488 }
489 
GetMulticastId(const char * family,const char * group)490 static int32_t GetMulticastId(const char *family, const char *group)
491 {
492     struct nl_msg *msg = NULL;
493     int32_t ret;
494     static struct FamilyData familyData;
495     int32_t familyId = genl_ctrl_resolve(g_wifiHalInfo.cmdSock, "nlctrl");
496 
497     familyData.group = group;
498     familyData.id = -ENOENT;
499 
500     msg = nlmsg_alloc();
501     if (msg == NULL) {
502         HILOG_ERROR(LOG_CORE, "%s: nlmsg_alloc failed", __FUNCTION__);
503         return RET_CODE_NOMEM;
504     }
505 
506     if (!genlmsg_put(msg, 0, 0, familyId, 0, 0, CTRL_CMD_GETFAMILY, 0) ||
507         nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, family)) {
508         HILOG_ERROR(LOG_CORE, "%s: put msg failed", __FUNCTION__);
509         nlmsg_free(msg);
510         return RET_CODE_FAILURE;
511     }
512 
513     ret = NetlinkSendCmdSync(msg, FamilyIdHandler, &familyData);
514     if (ret == 0) {
515         ret = familyData.id;
516     }
517     nlmsg_free(msg);
518     return ret;
519 }
520 
NlsockAddMembership(struct nl_sock * sock,const char * group)521 static int32_t NlsockAddMembership(struct nl_sock *sock, const char *group)
522 {
523     int32_t id;
524     int32_t ret;
525 
526     id = GetMulticastId(NL80211_GENL_NAME, group);
527     if (id < 0) {
528         HILOG_ERROR(LOG_CORE, "%s: get multicast id failed", __FUNCTION__);
529         return id;
530     }
531 
532     ret = nl_socket_add_membership(sock, id);
533     if (ret < 0) {
534         HILOG_ERROR(LOG_CORE, "%s: Could not add multicast membership for %d: %d (%s)", __FUNCTION__, id, ret,
535             strerror(-ret));
536         return RET_CODE_FAILURE;
537     }
538 
539     return RET_CODE_SUCCESS;
540 }
541 
ConnectEventSocket(void)542 static int32_t ConnectEventSocket(void)
543 {
544     int32_t ret;
545 
546     g_wifiHalInfo.eventSock = OpenNetlinkSocket();
547     if (g_wifiHalInfo.eventSock == NULL) {
548         HILOG_ERROR(LOG_CORE, "%s: fail to open event socket", __FUNCTION__);
549         return RET_CODE_FAILURE;
550     }
551 
552     if (nl_socket_set_nonblocking(g_wifiHalInfo.eventSock) != 0) {
553         HILOG_ERROR(LOG_CORE, "%s: fail to set nonblocking socket", __FUNCTION__);
554         CloseNetlinkSocket(g_wifiHalInfo.eventSock);
555         g_wifiHalInfo.eventSock = NULL;
556         return RET_CODE_FAILURE;
557     }
558 
559     do {
560         ret = NlsockAddMembership(g_wifiHalInfo.eventSock, NL80211_MULTICAST_GROUP_SCAN);
561         if (ret != RET_CODE_SUCCESS) {
562             HILOG_ERROR(LOG_CORE, "%s: nlsock add membership for scan event failed.", __FUNCTION__);
563             break;
564         }
565         ret = NlsockAddMembership(g_wifiHalInfo.eventSock, NL80211_MULTICAST_GROUP_MLME);
566         if (ret != RET_CODE_SUCCESS) {
567             HILOG_ERROR(LOG_CORE, "%s: nlsock add membership for mlme failed.", __FUNCTION__);
568             break;
569         }
570         ret = NlsockAddMembership(g_wifiHalInfo.eventSock, NL80211_MULTICAST_GROUP_REG);
571         if (ret != RET_CODE_SUCCESS) {
572             HILOG_ERROR(LOG_CORE, "%s: nlsock add membership for regulatory failed.", __FUNCTION__);
573             break;
574         }
575         ret = NlsockAddMembership(g_wifiHalInfo.eventSock, NL80211_MULTICAST_GROUP_VENDOR);
576         if (ret != RET_CODE_SUCCESS) {
577             HILOG_ERROR(LOG_CORE, "%s: nlsock add membership for vendor failed.", __FUNCTION__);
578             break;
579         }
580         return RET_CODE_SUCCESS;
581     } while (0);
582     CloseNetlinkSocket(g_wifiHalInfo.eventSock);
583     g_wifiHalInfo.eventSock = NULL;
584     return ret;
585 }
586 
DisconnectEventSocket(void)587 void DisconnectEventSocket(void)
588 {
589     CloseNetlinkSocket(g_wifiHalInfo.eventSock);
590     g_wifiHalInfo.eventSock = NULL;
591 }
592 
WifiMsgRegisterEventListener(void)593 static int32_t WifiMsgRegisterEventListener(void)
594 {
595     HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
596     int32_t rc;
597     int32_t count = 0;
598     struct WifiThreadParam threadParam;
599 
600     threadParam.eventSock = g_wifiHalInfo.eventSock;
601     threadParam.ctrlSock = g_wifiHalInfo.ctrlSock;
602     threadParam.familyId = g_wifiHalInfo.familyId;
603     threadParam.status = &g_wifiHalInfo.status;
604 
605     g_wifiHalInfo.status = THREAD_STARTING;
606     rc = pthread_create(&(g_wifiHalInfo.thread), NULL, EventThread, &threadParam);
607     if (rc != 0) {
608         HILOG_ERROR(LOG_CORE, "%s: failed create event thread", __FUNCTION__);
609         g_wifiHalInfo.status = THREAD_STOP;
610         return RET_CODE_FAILURE;
611     }
612 
613     // waiting for thread start running
614     while (g_wifiHalInfo.status != THREAD_RUN) {
615         HILOG_INFO(LOG_CORE, "%s: waiting for thread start running.", __FUNCTION__);
616         if (count < RETRIES) {
617             count++;
618             usleep(WAITFORTHREAD);
619         } else {
620             HILOG_ERROR(LOG_CORE, "%s: warit for thread running timeout", __FUNCTION__);
621             if (g_wifiHalInfo.status != THREAD_STOP) {
622                 g_wifiHalInfo.status = THREAD_STOP;
623                 pthread_join(g_wifiHalInfo.thread, NULL);
624             }
625             return RET_CODE_FAILURE;
626         }
627     }
628     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
629     return RET_CODE_SUCCESS;
630 }
631 
WifiMsgUnregisterEventListener(void)632 static void WifiMsgUnregisterEventListener(void)
633 {
634     HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
635     g_wifiHalInfo.status = THREAD_STOPPING;
636     pthread_join(g_wifiHalInfo.thread, NULL);
637     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
638 }
639 
WifiDriverClientInit(void)640 int32_t WifiDriverClientInit(void)
641 {
642     HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
643     if (g_wifiHalInfo.cmdSock != NULL) {
644         HILOG_ERROR(LOG_CORE, "%s: already create cmd socket", __FUNCTION__);
645         return RET_CODE_FAILURE;
646     }
647 
648     if (InitEventcallbackMutex() != RET_CODE_SUCCESS) {
649         HILOG_ERROR(LOG_CORE, "%s: init callbackmutex failed.", __FUNCTION__);
650         return RET_CODE_FAILURE;
651     }
652 
653     if (pthread_mutex_init(&g_wifiHalInfo.mutex, NULL) != RET_CODE_SUCCESS) {
654         HILOG_ERROR(LOG_CORE, "%s: init mutex failed.", __FUNCTION__);
655         goto err_mutex;
656     }
657 
658     if (ConnectCmdSocket() != RET_CODE_SUCCESS) {
659         HILOG_ERROR(LOG_CORE, "%s: connect cmd socket failed.", __FUNCTION__);
660         goto err_cmd;
661     }
662 
663     if (ConnectCtrlSocket() != RET_CODE_SUCCESS) {
664         HILOG_ERROR(LOG_CORE, "%s: connect ctrl socket failed", __FUNCTION__);
665         goto err_ctrl;
666     }
667 
668     if (ConnectEventSocket() != RET_CODE_SUCCESS) {
669         HILOG_ERROR(LOG_CORE, "%s: connect event socket failed", __FUNCTION__);
670         goto err_event;
671     }
672 
673     if (WifiMsgRegisterEventListener() != RET_CODE_SUCCESS) {
674         HILOG_ERROR(LOG_CORE, "%s: WifiMsgRegisterEventListener failed", __FUNCTION__);
675         goto err_reg;
676     }
677     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
678     return RET_CODE_SUCCESS;
679 err_reg:
680     DisconnectEventSocket();
681 err_event:
682     DisconnectCtrlSocket();
683 err_ctrl:
684     DisconnectCmdSocket();
685 err_cmd:
686     pthread_mutex_destroy(&g_wifiHalInfo.mutex);
687 err_mutex:
688     DeinitEventcallbackMutex();
689     return RET_CODE_FAILURE;
690 }
691 
WifiDriverClientDeinit(void)692 void WifiDriverClientDeinit(void)
693 {
694     HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
695     WifiMsgUnregisterEventListener();
696 
697     if (g_wifiHalInfo.cmdSock == NULL) {
698         HILOG_ERROR(LOG_CORE, "%s: cmd socket not inited", __FUNCTION__);
699     } else {
700         DisconnectCmdSocket();
701     }
702 
703     if (g_wifiHalInfo.ctrlSock == NULL) {
704         HILOG_ERROR(LOG_CORE, "%s: ctrl socket not inited", __FUNCTION__);
705     } else {
706         DisconnectCtrlSocket();
707     }
708 
709     if (g_wifiHalInfo.eventSock == NULL) {
710         HILOG_ERROR(LOG_CORE, "%s: event socket not inited", __FUNCTION__);
711     } else {
712         DisconnectEventSocket();
713     }
714 
715     pthread_mutex_destroy(&g_wifiHalInfo.mutex);
716     DeinitEventcallbackMutex();
717     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
718 }
719 
ParserIsSupportCombo(struct nl_msg * msg,void * arg)720 static int32_t ParserIsSupportCombo(struct nl_msg *msg, void *arg)
721 {
722     struct nlattr *attr[NL80211_ATTR_MAX + 1];
723     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
724     struct nlattr *nlComb = NULL;
725     struct nlattr *attrComb[NUM_NL80211_IFACE_COMB];
726     uint8_t *isSupportCombo = (uint8_t *)arg;
727     int32_t ret, i;
728     static struct nla_policy ifaceCombPolicy[NUM_NL80211_IFACE_COMB];
729     ifaceCombPolicy[NL80211_IFACE_COMB_LIMITS].type = NLA_NESTED;
730     ifaceCombPolicy[NL80211_IFACE_COMB_MAXNUM].type = NLA_U32;
731     ifaceCombPolicy[NL80211_IFACE_COMB_NUM_CHANNELS].type = NLA_U32;
732 
733     // parse all enum nl80211_attrs type
734     ret = nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
735     if (ret != 0) {
736         HILOG_ERROR(LOG_CORE, "%s: nla_parse tb failed", __FUNCTION__);
737         return NL_SKIP;
738     }
739 
740     if (attr[NL80211_ATTR_INTERFACE_COMBINATIONS] != NULL) {
741         nla_for_each_nested(nlComb, attr[NL80211_ATTR_INTERFACE_COMBINATIONS], i) {
742             // parse all enum nl80211_if_combination_attrs type
743             ret = nla_parse_nested(attrComb, MAX_NL80211_IFACE_COMB, nlComb, ifaceCombPolicy);
744             if (ret != 0) {
745                 HILOG_ERROR(LOG_CORE, "%s: nla_parse_nested nlComb failed", __FUNCTION__);
746                 return NL_SKIP;
747             }
748             if (!attrComb[NL80211_IFACE_COMB_LIMITS] || !attrComb[NL80211_IFACE_COMB_MAXNUM] ||
749                 !attrComb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
750                 *isSupportCombo = 0;
751             } else {
752                 *isSupportCombo = 1;
753             }
754         }
755     }
756     HILOG_INFO(LOG_CORE, "%s: isSupportCombo is %hhu", __FUNCTION__, *isSupportCombo);
757     return NL_SKIP;
758 }
759 
ParserSupportComboInfo(struct nl_msg * msg,void * arg)760 static int32_t ParserSupportComboInfo(struct nl_msg *msg, void *arg)
761 {
762     (void)arg;
763     struct nlattr *attr[NL80211_ATTR_MAX + 1];
764     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
765     struct nlattr *nlComb = NULL, *nlLimit = NULL, *nlMode = NULL;
766     struct nlattr *attrComb[NUM_NL80211_IFACE_COMB];
767     struct nlattr *attrLimit[NUM_NL80211_IFACE_LIMIT];
768     int32_t ret, i, j, k, type;
769     static struct nla_policy ifaceCombPolicy[NUM_NL80211_IFACE_COMB];
770     ifaceCombPolicy[NL80211_IFACE_COMB_LIMITS].type = NLA_NESTED;
771     ifaceCombPolicy[NL80211_IFACE_COMB_MAXNUM].type = NLA_U32;
772     ifaceCombPolicy[NL80211_IFACE_COMB_NUM_CHANNELS].type = NLA_U32;
773 
774     static struct nla_policy ifaceLimitPolicy[NUM_NL80211_IFACE_LIMIT];
775     ifaceLimitPolicy[NL80211_IFACE_LIMIT_MAX].type = NLA_U32;
776     ifaceLimitPolicy[NL80211_IFACE_LIMIT_TYPES].type = NLA_NESTED;
777 
778     ret = nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
779     if (ret != 0) {
780         HILOG_ERROR(LOG_CORE, "%s: nla_parse tb failed", __FUNCTION__);
781         return NL_SKIP;
782     }
783 
784     if (attr[NL80211_ATTR_INTERFACE_COMBINATIONS] != NULL) {
785         // get each ieee80211_iface_combination
786         nla_for_each_nested(nlComb, attr[NL80211_ATTR_INTERFACE_COMBINATIONS], i) {
787             ret = nla_parse_nested(attrComb, MAX_NL80211_IFACE_COMB, nlComb, ifaceCombPolicy);
788             if (ret != 0) {
789                 HILOG_ERROR(LOG_CORE, "%s: nla_parse_nested nlComb failed", __FUNCTION__);
790                 return NL_SKIP;
791             }
792             if (!attrComb[NL80211_IFACE_COMB_LIMITS] || !attrComb[NL80211_IFACE_COMB_MAXNUM] ||
793                 !attrComb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
794                 return RET_CODE_NOT_SUPPORT;
795             }
796             // parse each ieee80211_iface_limit
797             nla_for_each_nested(nlLimit, attrComb[NL80211_IFACE_COMB_LIMITS], j) {
798                 ret = nla_parse_nested(attrLimit, MAX_NL80211_IFACE_LIMIT, nlLimit, ifaceLimitPolicy);
799                 if (ret || !attrLimit[NL80211_IFACE_LIMIT_TYPES]) {
800                     HILOG_ERROR(LOG_CORE, "%s: iface limit types not supported", __FUNCTION__);
801                     return RET_CODE_NOT_SUPPORT; /* broken combination */
802                 }
803                 // parse each ieee80211_iface_limit's types
804                 nla_for_each_nested(nlMode, attrLimit[NL80211_IFACE_LIMIT_TYPES], k) {
805                     type = nla_type(nlMode);
806                     if (type > WIFI_IFTYPE_UNSPECIFIED && type < WIFI_IFTYPE_MAX) {
807                         HILOG_INFO(LOG_CORE, "%s: mode: %d", __FUNCTION__, type);
808                     }
809                 }
810                 HILOG_INFO(LOG_CORE, "%s: has parse a attrLimit", __FUNCTION__);
811             }
812         }
813     }
814     return NL_SKIP;
815 }
816 
GetWiphyBands(struct genlmsghdr * hdr)817 static struct nlattr *GetWiphyBands(struct genlmsghdr *hdr)
818 {
819     struct nlattr *attrMsg[NL80211_ATTR_MAX + 1];
820     void *data = genlmsg_attrdata(hdr, 0);
821     int32_t len = genlmsg_attrlen(hdr, 0);
822     nla_parse(attrMsg, NL80211_ATTR_MAX, data, len, NULL);
823     if (!attrMsg[NL80211_ATTR_WIPHY_BANDS]) {
824         HILOG_ERROR(LOG_CORE, "%s: no wiphy bands", __FUNCTION__);
825     }
826     return attrMsg[NL80211_ATTR_WIPHY_BANDS];
827 }
828 
GetCenterFreq(struct nlattr * bands,struct FreqInfoResult * result)829 static void GetCenterFreq(struct nlattr *bands, struct FreqInfoResult *result)
830 {
831     struct nlattr *attrFreq[NL80211_FREQUENCY_ATTR_MAX + 1];
832     struct nlattr *nlFreq = NULL;
833     void *data = NULL;
834     int32_t len;
835     int32_t i;
836     uint32_t freq;
837     static struct nla_policy freqPolicy[NL80211_FREQUENCY_ATTR_MAX + 1];
838     freqPolicy[NL80211_FREQUENCY_ATTR_FREQ].type = NLA_U32;
839     freqPolicy[NL80211_FREQUENCY_ATTR_MAX_TX_POWER].type = NLA_U32;
840 
841     // get each ieee80211_channel
842     nla_for_each_nested(nlFreq, bands, i) {
843         data = nla_data(nlFreq);
844         len = nla_len(nlFreq);
845         nla_parse(attrFreq, NL80211_FREQUENCY_ATTR_MAX, data, len, freqPolicy);
846         // get center freq
847         if (attrFreq[NL80211_FREQUENCY_ATTR_FREQ] == NULL) {
848             continue;
849         }
850         freq = nla_get_u32(attrFreq[NL80211_FREQUENCY_ATTR_FREQ]);
851         switch (result->band) {
852             case NL80211_BAND_2GHZ:
853                 if (attrFreq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) {
854                     if (freq > LOW_LITMIT_FREQ_2_4G && freq < HIGH_LIMIT_FREQ_2_4G) {
855                         result->freqs[result->nums] = freq;
856                         result->txPower[result->nums] = nla_get_u32(attrFreq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]);
857                         result->nums++;
858                     }
859                 }
860                 break;
861             case NL80211_BAND_5GHZ:
862                 if (freq > LOW_LIMIT_FREQ_5G && freq < HIGH_LIMIT_FREQ_5G) {
863                     result->freqs[result->nums] = freq;
864                     result->nums++;
865                 }
866                 break;
867             default:
868                 break;
869         }
870     }
871 }
872 
ParserValidFreq(struct nl_msg * msg,void * arg)873 static int32_t ParserValidFreq(struct nl_msg *msg, void *arg)
874 {
875     struct FreqInfoResult *result = (struct FreqInfoResult *)arg;
876     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
877     struct nlattr *attrWiphyBands = NULL;
878     struct nlattr *attrBand[NL80211_BAND_ATTR_MAX + 1];
879     struct nlattr *nlBand = NULL;
880     int32_t i;
881     void *data = NULL;
882     int32_t len;
883 
884     attrWiphyBands = GetWiphyBands(hdr);
885     if (attrWiphyBands == NULL) {
886         return NL_SKIP;
887     }
888 
889     // get each ieee80211_supported_band
890     nla_for_each_nested(nlBand, attrWiphyBands, i) {
891         data = nla_data(nlBand);
892         len = nla_len(nlBand);
893         nla_parse(attrBand, NL80211_BAND_ATTR_MAX, data, len, NULL);
894         if (attrBand[NL80211_BAND_ATTR_FREQS] == NULL) {
895             continue;
896         }
897         GetCenterFreq(attrBand[NL80211_BAND_ATTR_FREQS], result);
898     }
899     return NL_SKIP;
900 }
901 
IsWifiIface(const char * name)902 static bool IsWifiIface(const char *name)
903 {
904     if (strncmp(name, "wlan", WLAN_IFACE_LENGTH) != 0 && strncmp(name, "p2p", P2P_IFACE_LENGTH) != 0) {
905         /* not a wifi interface; ignore it */
906         return false;
907     } else {
908         return true;
909     }
910 }
911 
GetAllIfaceInfo(struct NetworkInfoResult * infoResult)912 static int32_t GetAllIfaceInfo(struct NetworkInfoResult *infoResult)
913 {
914     struct dirent **namelist = NULL;
915     char *ifName = NULL;
916     int32_t num;
917     int32_t i;
918     int32_t ret = RET_CODE_SUCCESS;
919 
920     num = scandir(NET_DEVICE_INFO_PATH, &namelist, NULL, alphasort);
921     if (num < 0) {
922         HILOG_ERROR(LOG_CORE, "%s: scandir failed, errno = %d, %s", __FUNCTION__, errno, strerror(errno));
923         return RET_CODE_FAILURE;
924     }
925     infoResult->nums = 0;
926     for (i = 0; i < num; i++) {
927         if (infoResult->nums < MAX_IFACE_NUM && IsWifiIface(namelist[i]->d_name)) {
928             ifName = infoResult->infos[infoResult->nums].name;
929             if (strncpy_s(ifName, IFNAMSIZ, namelist[i]->d_name, strlen(namelist[i]->d_name)) != EOK) {
930                 HILOG_ERROR(LOG_CORE, "%s: strncpy_s infoResult->infos failed", __FUNCTION__);
931                 ret = RET_CODE_FAILURE;
932             }
933             HILOG_INFO(LOG_CORE, "%{public}s: ifName = %{public}s", __FUNCTION__, ifName);
934             infoResult->nums++;
935         }
936         free(namelist[i]);
937     }
938     free(namelist);
939     return ret;
940 }
941 
NetLinkGetChipProp(void)942 static bool NetLinkGetChipProp(void)
943 {
944     char preValue[SUBCHIP_WIFI_PROP_LEN] = { 0 };
945     int errCode = GetParameter(SUBCHIP_WIFI_PROP, 0, preValue, SUBCHIP_WIFI_PROP_LEN);
946     if (errCode > 0) {
947         if (strncmp(preValue, SUPPORT_COEXCHIP, SUPPORT_COEXCHIP_LEN) == 0) {
948             return true;
949         }
950     }
951 
952     return false;
953 }
954 
GetUsableNetworkInfo(struct NetworkInfoResult * result)955 int32_t GetUsableNetworkInfo(struct NetworkInfoResult *result)
956 {
957     int32_t ret;
958     uint32_t i;
959 
960     ret = GetAllIfaceInfo(result);
961     if (ret != RET_CODE_SUCCESS) {
962         HILOG_ERROR(LOG_CORE, "%s: GetAllIfaceInfo failed", __FUNCTION__);
963         return ret;
964     }
965 
966     HILOG_INFO(LOG_CORE, "%{public}s: wifi iface num %{public}d", __FUNCTION__, result->nums);
967     for (i = 0; i < result->nums; ++i) {
968         ret = memset_s(result->infos[i].supportMode, sizeof(result->infos[i].supportMode), 0,
969             sizeof(result->infos[i].supportMode));
970         if (ret != EOK) {
971             HILOG_ERROR(LOG_CORE, "%s: memset_s esult->infos failed", __FUNCTION__);
972             return RET_CODE_FAILURE;
973         }
974         if (strncmp(result->infos[i].name, STR_WLAN0, strlen(STR_WLAN0)) == 0) {
975             result->infos[i].supportMode[WIFI_IFTYPE_STATION] = 1;
976             result->infos[i].supportMode[WIFI_IFTYPE_AP] = NetLinkGetChipProp() ? 0 : 1;
977         } else if (strncmp(result->infos[i].name, STR_WLAN1, strlen(STR_WLAN1)) == 0) {
978             result->infos[i].supportMode[WIFI_IFTYPE_STATION] = 1;
979             result->infos[i].supportMode[WIFI_IFTYPE_AP] = NetLinkGetChipProp() ? 1 : 0;
980         } else if (strncmp(result->infos[i].name, STR_P2P0, strlen(STR_P2P0)) == 0) {
981             result->infos[i].supportMode[WIFI_IFTYPE_P2P_DEVICE] = 1;
982         } else if (strncmp(result->infos[i].name, STR_P2P0_X, strlen(STR_P2P0_X)) == 0) {
983             result->infos[i].supportMode[WIFI_IFTYPE_P2P_CLIENT] = 1;
984             result->infos[i].supportMode[WIFI_IFTYPE_P2P_GO] = 1;
985         }
986     }
987     return RET_CODE_SUCCESS;
988 }
989 
IsSupportCombo(uint8_t * isSupportCombo)990 int32_t IsSupportCombo(uint8_t *isSupportCombo)
991 {
992     uint32_t ifaceId;
993     struct nl_msg *msg = NULL;
994     struct NetworkInfoResult networkInfo;
995     int32_t ret;
996 
997     ret = GetUsableNetworkInfo(&networkInfo);
998     if (ret != RET_CODE_SUCCESS) {
999         HILOG_ERROR(LOG_CORE, "%s: get network info failed", __FUNCTION__);
1000         return ret;
1001     }
1002 
1003     ifaceId = if_nametoindex(networkInfo.infos[0].name);
1004     if (ifaceId == 0) {
1005         HILOG_ERROR(LOG_CORE, "%s: get iface id(%u) failed", __FUNCTION__, ifaceId);
1006         return RET_CODE_FAILURE;
1007     }
1008 
1009     msg = nlmsg_alloc();
1010     if (msg == NULL) {
1011         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1012         return RET_CODE_NOMEM;
1013     }
1014 
1015     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1016     nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1017     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1018     ret = NetlinkSendCmdSync(msg, ParserIsSupportCombo, isSupportCombo);
1019     if (ret != RET_CODE_SUCCESS) {
1020         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1021     }
1022     nlmsg_free(msg);
1023     return ret;
1024 }
1025 
GetComboInfo(uint64_t * comboInfo,uint32_t size)1026 int32_t GetComboInfo(uint64_t *comboInfo, uint32_t size)
1027 {
1028     (void)size;
1029     uint32_t ifaceId;
1030     struct nl_msg *msg = NULL;
1031     struct NetworkInfoResult networkInfo;
1032     int32_t ret;
1033 
1034     ret = GetUsableNetworkInfo(&networkInfo);
1035     if (ret != RET_CODE_SUCCESS) {
1036         HILOG_ERROR(LOG_CORE, "%s: get network info failed", __FUNCTION__);
1037         return ret;
1038     }
1039 
1040     ifaceId = if_nametoindex(networkInfo.infos[0].name);
1041     if (ifaceId == 0) {
1042         HILOG_ERROR(LOG_CORE, "%s: get iface id(%d) failed", __FUNCTION__, ifaceId);
1043         return RET_CODE_FAILURE;
1044     }
1045 
1046     msg = nlmsg_alloc();
1047     if (msg == NULL) {
1048         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1049         return RET_CODE_NOMEM;
1050     }
1051     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1052     nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1053     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1054     ret = NetlinkSendCmdSync(msg, ParserSupportComboInfo, comboInfo);
1055     if (ret != RET_CODE_SUCCESS) {
1056         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1057     }
1058     nlmsg_free(msg);
1059     return ret;
1060 }
1061 
SetMacAddr(const char * ifName,unsigned char * mac,uint8_t len)1062 int32_t SetMacAddr(const char *ifName, unsigned char *mac, uint8_t len)
1063 {
1064     int32_t fd;
1065     int32_t ret;
1066     struct ifreq req;
1067 
1068     if (memset_s(&req, sizeof(req), 0, sizeof(req)) != EOK) {
1069         HILOG_ERROR(LOG_CORE, "%s: memset_s req failed", __FUNCTION__);
1070         return RET_CODE_FAILURE;
1071     }
1072     fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1073     if (fd < 0) {
1074         HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1075         return RET_CODE_FAILURE;
1076     }
1077     if (strncpy_s(req.ifr_name, IFNAMSIZ, ifName, strlen(ifName)) != EOK) {
1078         HILOG_ERROR(LOG_CORE, "%s: strncpy_s fail", __FUNCTION__);
1079         close(fd);
1080         return RET_CODE_FAILURE;
1081     }
1082     req.ifr_addr.sa_family = ARPHRD_ETHER;
1083     if (memcpy_s(req.ifr_hwaddr.sa_data, len, mac, len) != EOK) {
1084         HILOG_ERROR(LOG_CORE, "%s: memcpy_s req.ifr_hwaddr.sa_data failed", __FUNCTION__);
1085         close(fd);
1086         return RET_CODE_FAILURE;
1087     }
1088     ret = ioctl(fd, SIOCSIFHWADDR, &req);
1089     if (ret != RET_CODE_SUCCESS) {
1090         HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1091         if (errno == EPERM) {
1092             ret = RET_CODE_NOT_SUPPORT;
1093         } else if (errno == EBUSY) {
1094             ret = RET_CODE_DEVICE_BUSY;
1095         } else {
1096             ret = RET_CODE_FAILURE;
1097         }
1098     }
1099     close(fd);
1100     return ret;
1101 }
1102 
ParserChipId(struct nl_msg * msg,void * arg)1103 static int32_t ParserChipId(struct nl_msg *msg, void *arg)
1104 {
1105     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
1106     struct nlattr *attr[NL80211_ATTR_MAX + 1];
1107     uint8_t *chipId = (uint8_t *)arg;
1108     uint8_t *getChipId = NULL;
1109     int32_t ret;
1110 
1111     ret = nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
1112     if (ret != 0) {
1113         HILOG_ERROR(LOG_CORE, "%s: nla_parse failed", __FUNCTION__);
1114         return NL_SKIP;
1115     }
1116 
1117     if (attr[NL80211_ATTR_MAX]) {
1118         getChipId = nla_data(attr[NL80211_ATTR_MAX]);
1119         *chipId = *getChipId;
1120     }
1121 
1122     return NL_SKIP;
1123 }
1124 
GetDevMacAddr(const char * ifName,int32_t type,uint8_t * mac,uint8_t len)1125 int32_t GetDevMacAddr(const char *ifName, int32_t type, uint8_t *mac, uint8_t len)
1126 {
1127     (void)type;
1128     int32_t fd;
1129     int32_t ret;
1130     struct ifreq req;
1131 
1132     if (memset_s(&req, sizeof(req), 0, sizeof(req)) != EOK) {
1133         HILOG_ERROR(LOG_CORE, "%s: memset_s req failed", __FUNCTION__);
1134         return RET_CODE_FAILURE;
1135     }
1136     fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1137     if (fd < 0) {
1138         HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1139         return RET_CODE_FAILURE;
1140     }
1141 
1142     if (strncpy_s(req.ifr_name, IFNAMSIZ, ifName, strlen(ifName)) != EOK) {
1143         HILOG_ERROR(LOG_CORE, "%s: strncpy_s failed", __FUNCTION__);
1144         close(fd);
1145         return RET_CODE_FAILURE;
1146     }
1147     struct ethtool_perm_addr *epaddr =
1148         (struct ethtool_perm_addr *)malloc(sizeof(struct ethtool_perm_addr) + ETH_ADDR_LEN);
1149     if (epaddr == NULL) {
1150         HILOG_ERROR(LOG_CORE, "%s: malloc failed", __FUNCTION__);
1151         close(fd);
1152         return RET_CODE_FAILURE;
1153     }
1154     epaddr->cmd = ETHTOOL_GPERMADDR;
1155     epaddr->size = ETH_ADDR_LEN;
1156     req.ifr_data = (char*)epaddr;
1157     ret = ioctl(fd, SIOCETHTOOL, &req);
1158     if (ret != 0) {
1159         HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1160         free(epaddr);
1161         close(fd);
1162         return RET_CODE_FAILURE;
1163     }
1164 
1165     if (memcpy_s(mac, len, (unsigned char *)epaddr->data, ETH_ADDR_LEN) != EOK) {
1166         HILOG_ERROR(LOG_CORE, "%s: memcpy_s mac failed", __FUNCTION__);
1167         ret = RET_CODE_FAILURE;
1168     }
1169     free(epaddr);
1170     close(fd);
1171     return ret;
1172 }
1173 
GetValidFreqByBand(const char * ifName,int32_t band,struct FreqInfoResult * result,uint32_t size)1174 int32_t GetValidFreqByBand(const char *ifName, int32_t band, struct FreqInfoResult *result, uint32_t size)
1175 {
1176     uint32_t ifaceId;
1177     struct nl_msg *msg = NULL;
1178     int32_t ret;
1179 
1180     if (result == NULL || result->freqs == NULL || result->txPower == NULL) {
1181         HILOG_ERROR(LOG_CORE, "%s:  Invalid input parameter", __FUNCTION__);
1182         return RET_CODE_INVALID_PARAM;
1183     }
1184 
1185     if (band >= IEEE80211_NUM_BANDS) {
1186         HILOG_ERROR(LOG_CORE, "%s:  Invalid input parameter, band = %d", __FUNCTION__, band);
1187         return RET_CODE_INVALID_PARAM;
1188     }
1189 
1190     ifaceId = if_nametoindex(ifName);
1191     if (ifaceId == 0) {
1192         HILOG_ERROR(LOG_CORE, "%s: get iface id(%d) failed", __FUNCTION__, ifaceId);
1193         return RET_CODE_INVALID_PARAM;
1194     }
1195 
1196     msg = nlmsg_alloc();
1197     if (msg == NULL) {
1198         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1199         return RET_CODE_NOMEM;
1200     }
1201 
1202     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1203     nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1204     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1205     ret = memset_s(result->freqs, size * sizeof(uint32_t), 0, size * sizeof(uint32_t));
1206     if (ret != EOK) {
1207         HILOG_ERROR(LOG_CORE, "%s: memset_s result->freqs  failed", __FUNCTION__);
1208         nlmsg_free(msg);
1209         return RET_CODE_FAILURE;
1210     }
1211     result->nums = 0;
1212     result->band = band;
1213     ret = NetlinkSendCmdSync(msg, ParserValidFreq, result);
1214     if (ret != RET_CODE_SUCCESS) {
1215         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1216     }
1217     nlmsg_free(msg);
1218     return ret;
1219 }
1220 
SetTxPower(const char * ifName,int32_t power)1221 int32_t SetTxPower(const char *ifName, int32_t power)
1222 {
1223     uint32_t ifaceId;
1224     struct nl_msg *msg = NULL;
1225     int32_t ret;
1226 
1227     ifaceId = if_nametoindex(ifName);
1228     if (ifaceId == 0) {
1229         HILOG_ERROR(LOG_CORE, "%s: get iface id(%d) failed", __FUNCTION__, ifaceId);
1230         return RET_CODE_INVALID_PARAM;
1231     }
1232 
1233     msg = nlmsg_alloc();
1234     if (msg == NULL) {
1235         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1236         return RET_CODE_NOMEM;
1237     }
1238 
1239     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_SET_WIPHY, 0);
1240     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1241     nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_SETTING, NL80211_TX_POWER_LIMITED);
1242     nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, 100 * power);
1243     ret = NetlinkSendCmdSync(msg, NULL, NULL);
1244     if (ret != RET_CODE_SUCCESS) {
1245         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1246     } else {
1247         HILOG_INFO(LOG_CORE, "%s: send end success", __FUNCTION__);
1248     }
1249     nlmsg_free(msg);
1250     return ret;
1251 }
1252 
GetAssociatedStas(const char * ifName,struct AssocStaInfoResult * result)1253 int32_t GetAssociatedStas(const char *ifName, struct AssocStaInfoResult *result)
1254 {
1255     (void)ifName;
1256     if (memset_s(result, sizeof(struct AssocStaInfoResult), 0, sizeof(struct AssocStaInfoResult)) != EOK) {
1257         HILOG_ERROR(LOG_CORE, "%s: memset_s result failed", __FUNCTION__);
1258         return RET_CODE_FAILURE;
1259     }
1260     return RET_CODE_SUCCESS;
1261 }
1262 
WifiSetCountryCode(const char * ifName,const char * code,uint32_t len)1263 int32_t WifiSetCountryCode(const char *ifName, const char *code, uint32_t len)
1264 {
1265     uint32_t ifaceId = if_nametoindex(ifName);
1266     struct nl_msg *msg = NULL;
1267     struct nlattr *data = NULL;
1268     int32_t ret;
1269 
1270     if (ifaceId == 0) {
1271         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1272         return RET_CODE_FAILURE;
1273     }
1274 
1275     msg = nlmsg_alloc();
1276     if (msg == NULL) {
1277         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1278         return RET_CODE_NOMEM;
1279     }
1280 
1281     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_VENDOR, 0);
1282     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1283     nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, VENDOR_ID);
1284     nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, WIFI_SUBCMD_SET_COUNTRY_CODE);
1285     data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1286     if (data == NULL) {
1287         HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1288         nlmsg_free(msg);
1289         return RET_CODE_FAILURE;
1290     }
1291     nla_put(msg, WIFI_ATTRIBUTE_COUNTRY, len, code);
1292     nla_nest_end(msg, data);
1293 
1294     ret = NetlinkSendCmdSync(msg, NULL, NULL);
1295     if (ret != RET_CODE_SUCCESS) {
1296         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1297     }
1298     nlmsg_free(msg);
1299     return ret;
1300 }
1301 
SetScanMacAddr(const char * ifName,uint8_t * scanMac,uint8_t len)1302 int32_t SetScanMacAddr(const char *ifName, uint8_t *scanMac, uint8_t len)
1303 {
1304     int32_t ret;
1305     uint32_t ifaceId = if_nametoindex(ifName);
1306     struct nl_msg *msg = nlmsg_alloc();
1307     struct nlattr *data = NULL;
1308 
1309     if (msg == NULL) {
1310         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1311         return RET_CODE_NOMEM;
1312     }
1313     if (ifaceId == 0) {
1314         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1315         nlmsg_free(msg);
1316         return RET_CODE_FAILURE;
1317     }
1318     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_VENDOR, 0);
1319     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1320     nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, VENDOR_ID);
1321     nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, WIFI_SUBCMD_SET_RANDOM_MAC_OUI);
1322     data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1323     if (data == NULL) {
1324         HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1325         nlmsg_free(msg);
1326         return RET_CODE_FAILURE;
1327     }
1328     nla_put(msg, WIFI_ATTRIBUTE_RANDOM_MAC_OUI, len, scanMac);
1329     nla_nest_end(msg, data);
1330     ret = NetlinkSendCmdSync(msg, NULL, NULL);
1331     if (ret != RET_CODE_SUCCESS) {
1332         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1333     }
1334     nlmsg_free(msg);
1335     return ret;
1336 }
1337 
AcquireChipId(const char * ifName,uint8_t * chipId)1338 int32_t AcquireChipId(const char *ifName, uint8_t *chipId)
1339 {
1340     struct nl_msg *msg = NULL;
1341     uint32_t ifaceId;
1342     int32_t ret;
1343 
1344     if (ifName == NULL || chipId == NULL) {
1345         HILOG_ERROR(LOG_CORE, "%s params is NULL", __FUNCTION__);
1346         return RET_CODE_INVALID_PARAM;
1347     }
1348 
1349     ifaceId = if_nametoindex(ifName);
1350     if (ifaceId == 0) {
1351         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1352         return RET_CODE_FAILURE;
1353     }
1354 
1355     msg = nlmsg_alloc();
1356     if (msg == NULL) {
1357         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1358         return RET_CODE_NOMEM;
1359     }
1360 
1361     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1362     nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1363     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1364 
1365     ret = NetlinkSendCmdSync(msg, ParserChipId, chipId);
1366     if (ret != RET_CODE_SUCCESS) {
1367         HILOG_ERROR(LOG_CORE, "%s: NetlinkSendCmdSync failed.", __FUNCTION__);
1368     }
1369     nlmsg_free(msg);
1370     return ret;
1371 }
1372 
GetIfNamesByChipId(const uint8_t chipId,char ** ifNames,uint32_t * num)1373 int32_t GetIfNamesByChipId(const uint8_t chipId, char **ifNames, uint32_t *num)
1374 {
1375     if (ifNames == NULL || num == NULL) {
1376         HILOG_ERROR(LOG_CORE, "%s params is NULL", __FUNCTION__);
1377         return RET_CODE_INVALID_PARAM;
1378     }
1379 
1380     if (chipId >= MAX_WLAN_DEVICE) {
1381         HILOG_ERROR(LOG_CORE, "%s: chipId = %d", __FUNCTION__, chipId);
1382         return RET_CODE_INVALID_PARAM;
1383     }
1384     *num = 1;
1385     *ifNames = (char *)calloc(*num, IFNAMSIZ);
1386     if (*ifNames == NULL) {
1387         HILOG_ERROR(LOG_CORE, "%s: calloc failed", __FUNCTION__);
1388         return RET_CODE_FAILURE;
1389     }
1390     if (memcpy_s(*ifNames, IFNAMSIZ, "wlan0", IFNAMSIZ) != EOK) {
1391         HILOG_ERROR(LOG_CORE, "%s: memcpy failed", __FUNCTION__);
1392         free(*ifNames);
1393         *ifNames = NULL;
1394         return RET_CODE_FAILURE;
1395     }
1396     return RET_CODE_SUCCESS;
1397 }
1398 
SetResetDriver(const uint8_t chipId,const char * ifName)1399 int32_t SetResetDriver(const uint8_t chipId, const char *ifName)
1400 {
1401     (void)chipId;
1402     (void)ifName;
1403     return RET_CODE_SUCCESS;
1404 }
1405 
NetDeviceInfoHandler(struct nl_msg * msg,void * arg)1406 static int32_t NetDeviceInfoHandler(struct nl_msg *msg, void *arg)
1407 {
1408     struct NetDeviceInfo *info = (struct NetDeviceInfo *)arg;
1409     struct nlattr *attr[NL80211_ATTR_MAX + 1];
1410     struct genlmsghdr *hdr = NULL;
1411     void *data = NULL;
1412     int32_t len;
1413 
1414     hdr = nlmsg_data(nlmsg_hdr(msg));
1415     if (hdr == NULL) {
1416         HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
1417         return NL_SKIP;
1418     }
1419     data = genlmsg_attrdata(hdr, 0);
1420     len = genlmsg_attrlen(hdr, 0);
1421     nla_parse(attr, NL80211_ATTR_MAX, data, len, NULL);
1422     if (attr[NL80211_ATTR_IFTYPE]) {
1423         info->iftype = nla_get_u32(attr[NL80211_ATTR_IFTYPE]);
1424         HILOG_ERROR(LOG_CORE, "%s: %s iftype is %hhu", __FUNCTION__, info->ifName, info->iftype);
1425     }
1426     if (attr[NL80211_ATTR_MAC]) {
1427         if (memcpy_s(info->mac, ETH_ADDR_LEN, nla_data(attr[NL80211_ATTR_MAC]), ETH_ADDR_LEN) != EOK) {
1428             HILOG_ERROR(LOG_CORE, "%s: memcpy_s mac address fail", __FUNCTION__);
1429         }
1430     }
1431 
1432     return NL_SKIP;
1433 }
1434 
GetIftypeAndMac(struct NetDeviceInfo * info)1435 static int32_t GetIftypeAndMac(struct NetDeviceInfo *info)
1436 {
1437     struct nl_msg *msg = nlmsg_alloc();
1438     int32_t ret;
1439 
1440     if (msg == NULL) {
1441         HILOG_ERROR(LOG_CORE, "%s: nlmsg_alloc failed.", __FUNCTION__);
1442         return RET_CODE_FAILURE;
1443     }
1444 
1445     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_INTERFACE, 0);
1446     nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(info->ifName));
1447 
1448     ret = NetlinkSendCmdSync(msg, NetDeviceInfoHandler, info);
1449     if (ret != RET_CODE_SUCCESS) {
1450         HILOG_ERROR(LOG_CORE, "%s: NetlinkSendCmdSync failed.", __FUNCTION__);
1451     }
1452     nlmsg_free(msg);
1453     return ret;
1454 }
1455 
GetNetDeviceInfo(struct NetDeviceInfoResult * netDeviceInfoResult)1456 int32_t GetNetDeviceInfo(struct NetDeviceInfoResult *netDeviceInfoResult)
1457 {
1458     struct NetworkInfoResult networkInfo;
1459     uint32_t i;
1460     int32_t ret;
1461 
1462     ret = GetUsableNetworkInfo(&networkInfo);
1463     if (ret != RET_CODE_SUCCESS) {
1464         HILOG_ERROR(LOG_CORE, "%s: get network info failed", __FUNCTION__);
1465         return ret;
1466     }
1467 
1468     for (i = 0; i < networkInfo.nums && i < MAX_NETDEVICE_COUNT; i++) {
1469         if (memset_s(&netDeviceInfoResult->deviceInfos[i], sizeof(struct NetDeviceInfo), 0,
1470             sizeof(struct NetDeviceInfo)) != EOK) {
1471             HILOG_ERROR(LOG_CORE, "%s: memset_s fail", __FUNCTION__);
1472             return RET_CODE_FAILURE;
1473         }
1474         netDeviceInfoResult->deviceInfos[i].index = i + 1;
1475         if (strncpy_s(netDeviceInfoResult->deviceInfos[i].ifName, IFNAMSIZ,
1476             networkInfo.infos[i].name, IFNAMSIZ) != EOK) {
1477             HILOG_ERROR(LOG_CORE, "%s: strncpy_s fail", __FUNCTION__);
1478             return RET_CODE_FAILURE;
1479         }
1480         ret = GetIftypeAndMac(&netDeviceInfoResult->deviceInfos[i]);
1481         if (ret != RET_CODE_SUCCESS) {
1482             HILOG_ERROR(LOG_CORE, "%s: get iftype and mac failed", __FUNCTION__);
1483             return ret;
1484         }
1485     }
1486 
1487     return RET_CODE_SUCCESS;
1488 }
1489 
CmdScanPutSsidsMsg(struct nl_msg * msg,const WifiScan * scan,const WiphyInfo * wiphyInfo)1490 static int32_t CmdScanPutSsidsMsg(struct nl_msg *msg, const WifiScan *scan, const WiphyInfo *wiphyInfo)
1491 {
1492     struct nlattr *nest = NULL;
1493     int32_t i;
1494 
1495     if (scan->ssids) {
1496         nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
1497         if (nest == NULL) {
1498             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1499             return RET_CODE_FAILURE;
1500         }
1501         for (i = 0; i < scan->numSsids; i++) {
1502             if (i >= wiphyInfo->scanCapabilities.maxNumScanSsids) {
1503                 HILOG_INFO(LOG_CORE, "%s: Skip the excess hidden ssids for scan", __FUNCTION__);
1504                 break;
1505             }
1506             nla_put(msg, i + 1, scan->ssids[i].ssidLen, scan->ssids[i].ssid);
1507         }
1508         nla_nest_end(msg, nest);
1509     }
1510     return RET_CODE_SUCCESS;
1511 }
1512 
CmdScanPutFreqsMsg(struct nl_msg * msg,const WifiScan * scan)1513 static int32_t CmdScanPutFreqsMsg(struct nl_msg *msg, const WifiScan *scan)
1514 {
1515     struct nlattr *nest = NULL;
1516     int32_t i;
1517 
1518     if (scan->freqs) {
1519         nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
1520         if (nest == NULL) {
1521             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1522             return RET_CODE_FAILURE;
1523         }
1524         for (i = 0; i < scan->numFreqs; i++) {
1525             nla_put_u32(msg, i + 1, scan->freqs[i]);
1526         }
1527         nla_nest_end(msg, nest);
1528     }
1529     return RET_CODE_SUCCESS;
1530 }
1531 
CmdScanPutMsg(const char * ifName,struct nl_msg * msg,const WifiScan * scan)1532 static int32_t CmdScanPutMsg(const char *ifName, struct nl_msg *msg, const WifiScan *scan)
1533 {
1534     uint32_t wiphyIndex;
1535     WiphyInfo wiphyInfo;
1536 
1537     if (memset_s(&wiphyInfo, sizeof(wiphyInfo), 0, sizeof(wiphyInfo)) != EOK) {
1538         HILOG_ERROR(LOG_CORE, "%s: memset_s wiphyInfo failed", __FUNCTION__);
1539         return RET_CODE_FAILURE;
1540     }
1541     if (GetWiphyIndex(ifName, &wiphyIndex) != RET_CODE_SUCCESS) {
1542         HILOG_ERROR(LOG_CORE, "%s: GetWiphyIndex failed", __FUNCTION__);
1543         return RET_CODE_FAILURE;
1544     }
1545     if (GetWiphyInfo(wiphyIndex, &wiphyInfo) != RET_CODE_SUCCESS) {
1546         HILOG_ERROR(LOG_CORE, "%s: GetWiphyInfo failed", __FUNCTION__);
1547         return RET_CODE_FAILURE;
1548     }
1549 
1550     if (CmdScanPutSsidsMsg(msg, scan, &wiphyInfo) != RET_CODE_SUCCESS) {
1551         return RET_CODE_FAILURE;
1552     }
1553 
1554     if (CmdScanPutFreqsMsg(msg, scan) != RET_CODE_SUCCESS) {
1555         return RET_CODE_FAILURE;
1556     }
1557 
1558     if (scan->extraIes) {
1559         nla_put(msg, NL80211_ATTR_IE, scan->extraIesLen, scan->extraIes);
1560     }
1561 
1562     if (scan->bssid) {
1563         nla_put(msg, NL80211_ATTR_MAC, ETH_ADDR_LEN, scan->bssid);
1564     }
1565 
1566     return RET_CODE_SUCCESS;
1567 }
1568 
WifiCmdScan(const char * ifName,WifiScan * scan)1569 int32_t WifiCmdScan(const char *ifName, WifiScan *scan)
1570 {
1571     uint32_t ifaceId = if_nametoindex(ifName);
1572     struct nl_msg *msg = NULL;
1573     int32_t ret;
1574 
1575     if (ifaceId == 0) {
1576         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1577         return RET_CODE_FAILURE;
1578     }
1579 
1580     msg = nlmsg_alloc();
1581     if (msg == NULL) {
1582         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1583         return RET_CODE_NOMEM;
1584     }
1585 
1586     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_TRIGGER_SCAN, 0);
1587     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1588     do {
1589         ret = CmdScanPutMsg(ifName, msg, scan);
1590         if (ret != RET_CODE_SUCCESS) {
1591             HILOG_ERROR(LOG_CORE, "%s: put msg failed", __FUNCTION__);
1592             break;
1593         }
1594         ret = NetlinkSendCmdSync(msg, NULL, NULL);
1595         if (ret != RET_CODE_SUCCESS) {
1596             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1597         }
1598     } while (0);
1599     nlmsg_free(msg);
1600     return ret;
1601 }
1602 
ParsePowerMode(const char * buf,uint16_t len,uint8_t * mode)1603 static int32_t ParsePowerMode(const char *buf, uint16_t len, uint8_t *mode)
1604 {
1605     char *key[WIFI_POWER_MODE_NUM] = {"sleep\n", "third\n", "init\n"};
1606     char *str = "pow_mode = ";
1607     if (buf == NULL || mode == NULL) {
1608         return RET_CODE_INVALID_PARAM;
1609     }
1610     char *pos = strstr(buf, str);
1611     if (pos == NULL) {
1612         HILOG_ERROR(LOG_CORE, "%s: no power mode", __FUNCTION__);
1613         return RET_CODE_FAILURE;
1614     }
1615     pos += strlen(str);
1616     if (!strncmp(pos, key[WIFI_POWER_MODE_SLEEPING], strlen(key[WIFI_POWER_MODE_SLEEPING]))) {
1617         *mode = WIFI_POWER_MODE_SLEEPING;
1618     } else if (!strncmp(pos, key[WIFI_POWER_MODE_GENERAL], strlen(key[WIFI_POWER_MODE_GENERAL]))) {
1619         *mode = WIFI_POWER_MODE_GENERAL;
1620     } else if (!strncmp(pos, key[WIFI_POWER_MODE_THROUGH_WALL], strlen(key[WIFI_POWER_MODE_THROUGH_WALL]))) {
1621         *mode = WIFI_POWER_MODE_THROUGH_WALL;
1622     } else {
1623         HILOG_ERROR(LOG_CORE, "%s: no invalid power mode", __FUNCTION__);
1624         return RET_CODE_FAILURE;
1625     }
1626     return RET_CODE_SUCCESS;
1627 }
1628 
GetCurrentPowerMode(const char * ifName,uint8_t * mode)1629 int32_t GetCurrentPowerMode(const char *ifName, uint8_t *mode)
1630 {
1631     int32_t fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1632     int32_t ret;
1633     HwprivIoctlData ioctlData;
1634 
1635     (void)memset_s(&ioctlData, sizeof(ioctlData), 0, sizeof(ioctlData));
1636     if (fd < 0) {
1637         HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1638         return RET_CODE_FAILURE;
1639     }
1640     do {
1641         if (strcpy_s(ioctlData.interfaceName, IFNAMSIZ, ifName) != EOK) {
1642             HILOG_ERROR(LOG_CORE, "%s: strcpy_s failed", __FUNCTION__);
1643             ret = RET_CODE_FAILURE;
1644             break;
1645         }
1646         ioctlData.data.point.flags = SECONDARY_ID_POWER_MODE;
1647         ioctlData.data.point.length = strlen(GET_POWER_MODE) + 1;
1648         ioctlData.data.point.buf = calloc(ioctlData.data.point.length, sizeof(char));
1649         if (ioctlData.data.point.buf == NULL) {
1650             HILOG_ERROR(LOG_CORE, "%s: calloc failed", __FUNCTION__);
1651             ret = RET_CODE_NOMEM;
1652             break;
1653         }
1654         if (memcpy_s(ioctlData.data.point.buf, ioctlData.data.point.length,
1655             GET_POWER_MODE, strlen(GET_POWER_MODE)) != EOK) {
1656             HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed", __FUNCTION__);
1657             ret = RET_CODE_FAILURE;
1658             break;
1659         }
1660         ret = ioctl(fd, PRIMARY_ID_POWER_MODE, &ioctlData);
1661         if (ret != RET_CODE_SUCCESS) {
1662             HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1663             if (errno == EOPNOTSUPP) {
1664                 ret = RET_CODE_NOT_SUPPORT;
1665             } else {
1666                 ret = RET_CODE_FAILURE;
1667             }
1668             break;
1669         }
1670         ret = ParsePowerMode(ioctlData.data.point.buf, ioctlData.data.point.length, mode);
1671         if (ret != RET_CODE_SUCCESS) {
1672             HILOG_ERROR(LOG_CORE, "%s: ParsePowerMode failed", __FUNCTION__);
1673             break;
1674         }
1675     } while (0);
1676     if (ioctlData.data.point.buf != NULL) {
1677         free(ioctlData.data.point.buf);
1678         ioctlData.data.point.buf = NULL;
1679     }
1680     close(fd);
1681     return ret;
1682 }
1683 
FillHwprivIoctlData(HwprivIoctlData * ioctlData,uint8_t mode)1684 static int32_t FillHwprivIoctlData(HwprivIoctlData *ioctlData, uint8_t mode)
1685 {
1686     const char *strTable[WIFI_POWER_MODE_NUM] = {SET_POWER_MODE_SLEEP, SET_POWER_MODE_THIRD, SET_POWER_MODE_INIT};
1687     const char *modeStr = strTable[mode];
1688 
1689     ioctlData->data.point.length = strlen(strTable[mode]) + 1;
1690     ioctlData->data.point.buf = calloc(ioctlData->data.point.length, sizeof(char));
1691     if (ioctlData->data.point.buf == NULL) {
1692         HILOG_ERROR(LOG_CORE, "%s: calloc failed", __FUNCTION__);
1693         return RET_CODE_NOMEM;
1694     }
1695     ioctlData->data.point.flags = SECONDARY_ID_POWER_MODE;
1696     if (strncpy_s(ioctlData->data.point.buf, ioctlData->data.point.length, modeStr, strlen(modeStr)) != EOK) {
1697         HILOG_ERROR(LOG_CORE, "%s: strncpy_s failed", __FUNCTION__);
1698         free(ioctlData->data.point.buf);
1699         ioctlData->data.point.buf = NULL;
1700         return RET_CODE_FAILURE;
1701     }
1702 
1703     return RET_CODE_SUCCESS;
1704 }
1705 
SetPowerMode(const char * ifName,uint8_t mode)1706 int32_t SetPowerMode(const char *ifName, uint8_t mode)
1707 {
1708     int32_t fd;
1709     int32_t ret;
1710     HwprivIoctlData ioctlData;
1711 
1712     if (ifName == NULL || mode >= WIFI_POWER_MODE_NUM) {
1713         HILOG_ERROR(LOG_CORE, "%s: Invalid parameter", __FUNCTION__);
1714         return RET_CODE_FAILURE;
1715     }
1716     (void)memset_s(&ioctlData, sizeof(ioctlData), 0, sizeof(ioctlData));
1717     fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1718     if (fd < 0) {
1719         HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1720         return RET_CODE_FAILURE;
1721     }
1722 
1723     do {
1724         if (strcpy_s(ioctlData.interfaceName, IFNAMSIZ, ifName) != EOK) {
1725             HILOG_ERROR(LOG_CORE, "%s: strcpy_s failed", __FUNCTION__);
1726             ret = RET_CODE_FAILURE;
1727             break;
1728         }
1729         ret = FillHwprivIoctlData(&ioctlData, mode);
1730         if (ret != RET_CODE_SUCCESS) {
1731             break;
1732         }
1733         ret = ioctl(fd, PRIMARY_ID_POWER_MODE, &ioctlData);
1734         if (ret != RET_CODE_SUCCESS) {
1735             HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1736             if (errno == EOPNOTSUPP) {
1737                 ret = RET_CODE_NOT_SUPPORT;
1738             } else {
1739                 ret = RET_CODE_FAILURE;
1740             }
1741         }
1742     } while (0);
1743 
1744     if (ioctlData.data.point.buf != NULL) {
1745         free(ioctlData.data.point.buf);
1746         ioctlData.data.point.buf = NULL;
1747     }
1748     close(fd);
1749     return ret;
1750 }
1751 
StartChannelMeas(const char * ifName,const struct MeasParam * measParam)1752 int32_t StartChannelMeas(const char *ifName, const struct MeasParam *measParam)
1753 {
1754     (void)ifName;
1755     (void)measParam;
1756     return RET_CODE_NOT_SUPPORT;
1757 }
1758 
GetChannelMeasResult(const char * ifName,struct MeasResult * measResult)1759 int32_t GetChannelMeasResult(const char *ifName, struct MeasResult *measResult)
1760 {
1761     (void)ifName;
1762     (void)measResult;
1763     return RET_CODE_NOT_SUPPORT;
1764 }
1765 
SendCommandToDriver(const char * cmd,uint32_t len,const char * ifName,WifiPrivCmd * out)1766 static int32_t SendCommandToDriver(const char *cmd, uint32_t len, const char *ifName, WifiPrivCmd *out)
1767 {
1768     struct ifreq ifr;
1769     int32_t ret = RET_CODE_FAILURE;
1770 
1771     if (cmd == NULL || out == NULL) {
1772         HILOG_ERROR(LOG_CORE, "%{public}s: cmd or out is null", __FUNCTION__);
1773         return RET_CODE_INVALID_PARAM;
1774     }
1775     if (len > out->size) {
1776         HILOG_ERROR(LOG_CORE, "%{public}s: Size of command is too large", __FUNCTION__);
1777         return RET_CODE_INVALID_PARAM;
1778     }
1779     if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
1780         HILOG_ERROR(LOG_CORE, "%s: memset_s ifr failed", __FUNCTION__);
1781         return RET_CODE_FAILURE;
1782     }
1783     if (memcpy_s(out->buf, out->size, cmd, len) != EOK) {
1784         HILOG_ERROR(LOG_CORE, "%{public}s: memcpy_s error", __FUNCTION__);
1785         return RET_CODE_FAILURE;
1786     }
1787     out->len = len;
1788     ifr.ifr_data = (void *)out;
1789     if (strcpy_s(ifr.ifr_name, IFNAMSIZ, ifName) != EOK) {
1790         HILOG_ERROR(LOG_CORE, "%s: strcpy_s error", __FUNCTION__);
1791         return RET_CODE_FAILURE;
1792     }
1793     int32_t sock = socket(AF_INET, SOCK_DGRAM, 0);
1794     if (sock < 0) {
1795         HILOG_ERROR(LOG_CORE, "%{public}s: socket failed, errno = %{public}d, (%{public}s)", __FUNCTION__, errno,
1796             strerror(errno));
1797         return ret;
1798     }
1799     do {
1800         ret = ioctl(sock, SIOCDEVPRIVATE + 1, &ifr);
1801         if (ret < 0) {
1802             HILOG_ERROR(LOG_CORE, "%{public}s: ioctl failed, errno = %{public}d, (%{public}s)", __FUNCTION__, errno,
1803                 strerror(errno));
1804             ret = (errno == EOPNOTSUPP) ? RET_CODE_NOT_SUPPORT : RET_CODE_FAILURE;
1805             break;
1806         }
1807     } while (0);
1808 
1809     close(sock);
1810     return ret;
1811 }
1812 
GetInterfaceState(const char * interfaceName,uint16_t * state)1813 static int32_t GetInterfaceState(const char *interfaceName, uint16_t *state)
1814 {
1815     int32_t ret = RET_CODE_FAILURE;
1816     struct ifreq ifr;
1817     int32_t fd;
1818 
1819     if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
1820         HILOG_ERROR(LOG_CORE, "%s: memset_s req failed", __FUNCTION__);
1821         return RET_CODE_FAILURE;
1822     }
1823 
1824     fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1825     if (fd < 0) {
1826         HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1827         return RET_CODE_FAILURE;
1828     }
1829     do {
1830         if (strncpy_s(ifr.ifr_name, MAX_INTERFACE_NAME_SIZE, interfaceName, strlen(interfaceName)) != EOK) {
1831             HILOG_ERROR(LOG_CORE, "%s: strncpy_s failed", __FUNCTION__);
1832             break;
1833         }
1834         ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
1835         if (ret < 0) {
1836             HILOG_ERROR(LOG_CORE, "%s:could not read interface state for %s, errno = %d, (%s)", __FUNCTION__,
1837                 interfaceName, errno, strerror(errno));
1838             ret = RET_CODE_FAILURE;
1839             break;
1840         }
1841         *state = ifr.ifr_flags;
1842     } while (0);
1843 
1844     close(fd);
1845     return ret;
1846 }
1847 
DisableNextCacOnce(const char * ifName)1848 static int32_t DisableNextCacOnce(const char *ifName)
1849 {
1850     char cmdBuf[P2P_BUF_SIZE] = {CMD_SET_CLOSE_GO_CAC};
1851 
1852     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
1853     WifiPrivCmd out = {0};
1854     out.buf = buf;
1855     out.size = MAX_PRIV_CMD_SIZE;
1856     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
1857 }
1858 
SetGoChannel(const char * ifName,const int8_t * data,uint32_t len)1859 static int32_t SetGoChannel(const char *ifName, const int8_t *data, uint32_t len)
1860 {
1861     int32_t ret = RET_CODE_FAILURE;
1862     char cmdBuf[P2P_BUF_SIZE] = {0};
1863     uint32_t cmdLen;
1864     uint16_t state;
1865 
1866     cmdLen = strlen(CMD_SET_CHANGE_GO_CHANNEL);
1867     if ((cmdLen + len) >= P2P_BUF_SIZE) {
1868         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
1869         return ret;
1870     }
1871     ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_CHANGE_GO_CHANNEL, *data);
1872     if (ret < RET_CODE_SUCCESS) {
1873         HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
1874         return RET_CODE_FAILURE;
1875     }
1876     if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
1877         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
1878         return RET_CODE_NETDOWN;
1879     }
1880 
1881     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
1882     WifiPrivCmd out = {0};
1883     out.buf = buf;
1884     out.size = MAX_PRIV_CMD_SIZE;
1885     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
1886 }
1887 
SetGoDetectRadar(const char * ifName,const int8_t * data,uint32_t len)1888 static int32_t SetGoDetectRadar(const char *ifName, const int8_t *data, uint32_t len)
1889 {
1890     int32_t ret = RET_CODE_FAILURE;
1891     char cmdBuf[P2P_BUF_SIZE] = {0};
1892     uint32_t cmdLen;
1893     uint16_t state;
1894 
1895     cmdLen = strlen(CMD_SET_GO_DETECT_RADAR);
1896     if ((cmdLen + len) >= P2P_BUF_SIZE) {
1897         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
1898         return ret;
1899     }
1900     ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_GO_DETECT_RADAR, *data);
1901     if (ret < RET_CODE_SUCCESS) {
1902         HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
1903         return RET_CODE_FAILURE;
1904     }
1905     if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
1906         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
1907         return RET_CODE_NETDOWN;
1908     }
1909 
1910     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
1911     WifiPrivCmd out = {0};
1912     out.buf = buf;
1913     out.size = MAX_PRIV_CMD_SIZE;
1914     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
1915 }
1916 
SetP2pScenes(const char * ifName,const int8_t * data,uint32_t len)1917 static int32_t SetP2pScenes(const char *ifName, const int8_t *data, uint32_t len)
1918 {
1919     int32_t ret = RET_CODE_FAILURE;
1920     char cmdBuf[P2P_BUF_SIZE] = {0};
1921     uint32_t cmdLen;
1922     uint16_t state;
1923 
1924     cmdLen = strlen(CMD_SET_P2P_SCENES);
1925     if ((cmdLen + len) >= P2P_BUF_SIZE) {
1926         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
1927         return ret;
1928     }
1929     ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_P2P_SCENES, *data);
1930     if (ret < RET_CODE_SUCCESS) {
1931         HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
1932         return RET_CODE_FAILURE;
1933     }
1934     if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
1935         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
1936         return RET_CODE_NETDOWN;
1937     }
1938 
1939     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
1940     WifiPrivCmd out = {0};
1941     out.buf = buf;
1942     out.size = MAX_PRIV_CMD_SIZE;
1943     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
1944 }
1945 
SetDynamicDbacMode(const char * ifName,const int8_t * data,uint32_t len)1946 static int32_t SetDynamicDbacMode(const char *ifName, const int8_t *data, uint32_t len)
1947 {
1948     int32_t ret = RET_CODE_FAILURE;
1949     char cmdBuf[P2P_BUF_SIZE] = {0};
1950     uint32_t cmdLen;
1951     uint16_t state;
1952 
1953     cmdLen = strlen(CMD_SET_DYNAMIC_DBAC_MODE);
1954     if ((cmdLen + len) >= P2P_BUF_SIZE) {
1955         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
1956         return ret;
1957     }
1958     ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_DYNAMIC_DBAC_MODE, *data);
1959     if (ret < RET_CODE_SUCCESS) {
1960         HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
1961         return RET_CODE_FAILURE;
1962     }
1963     if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
1964         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
1965         return RET_CODE_NETDOWN;
1966     }
1967 
1968     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
1969     WifiPrivCmd out = {0};
1970     out.buf = buf;
1971     out.size = MAX_PRIV_CMD_SIZE;
1972     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
1973 }
1974 
SetRxRemainOnChannel(const char * ifName,const int8_t * data,uint32_t len)1975 static int32_t SetRxRemainOnChannel(const char *ifName, const int8_t *data, uint32_t len)
1976 {
1977     int32_t ret = RET_CODE_FAILURE;
1978     char cmdBuf[P2P_BUF_SIZE] = {0};
1979     uint32_t cmdLen;
1980     uint16_t state;
1981 
1982     cmdLen = strlen(CMD_SET_RX_MGMT_REMAIN_ON_CHANNEL);
1983     if ((cmdLen + len) >= P2P_BUF_SIZE) {
1984         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
1985         return ret;
1986     }
1987     ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s", CMD_SET_RX_MGMT_REMAIN_ON_CHANNEL);
1988     if (ret < RET_CODE_SUCCESS) {
1989         HILOG_ERROR(LOG_CORE, "%{public}s: snprintf failed!, ret = %{public}d", __FUNCTION__, ret);
1990         return RET_CODE_FAILURE;
1991     }
1992     cmdLen = (uint32_t)ret;
1993     ret = memcpy_s(cmdBuf + cmdLen + 1, P2P_BUF_SIZE - cmdLen - 1, data, len);
1994     if (ret < RET_CODE_SUCCESS) {
1995         HILOG_ERROR(LOG_CORE, "%{public}s: memcpy failed!, ret = %{public}d", __FUNCTION__, ret);
1996         return RET_CODE_FAILURE;
1997     }
1998     if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
1999         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2000         return RET_CODE_NETDOWN;
2001     }
2002 
2003     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2004     WifiPrivCmd out = {0};
2005     out.buf = buf;
2006     out.size = MAX_PRIV_CMD_SIZE;
2007     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2008 }
2009 
SetProjectionScreenParam(const char * ifName,const ProjectionScreenParam * param)2010 int32_t SetProjectionScreenParam(const char *ifName, const ProjectionScreenParam *param)
2011 {
2012     int32_t ret;
2013     switch (param->cmdId) {
2014         case CMD_CLOSE_GO_CAC:
2015             ret = DisableNextCacOnce(ifName);
2016             break;
2017         case CMD_SET_GO_CSA_CHANNEL:
2018             ret = SetGoChannel(ifName, param->buf, param->bufLen);
2019             break;
2020         case CMD_SET_GO_RADAR_DETECT:
2021             ret = SetGoDetectRadar(ifName, param->buf, param->bufLen);
2022             break;
2023         case CMD_ID_MCC_STA_P2P_QUOTA_TIME:
2024             ret = SetDynamicDbacMode(ifName, param->buf, param->bufLen);
2025             break;
2026         case CMD_ID_CTRL_ROAM_CHANNEL:
2027             ret = SetP2pScenes(ifName, param->buf, param->bufLen);
2028             break;
2029         case CMD_ID_RX_REMAIN_ON_CHANNEL:
2030             ret = SetRxRemainOnChannel(ifName, param->buf, param->bufLen);
2031             break;
2032         default:
2033             HILOG_ERROR(LOG_CORE, "%{public}s: Invalid command id", __FUNCTION__);
2034             return RET_CODE_NOT_SUPPORT;
2035     }
2036     if (ret != RET_CODE_SUCCESS) {
2037         HILOG_ERROR(LOG_CORE, "%{public}s: Config projection screen fail, ret = %{public}d", __FUNCTION__, ret);
2038     }
2039     return ret;
2040 }
2041 
SendCmdIoctl(const char * ifName,int32_t cmdId,const int8_t * paramBuf,uint32_t paramBufLen)2042 int32_t SendCmdIoctl(const char *ifName, int32_t cmdId, const int8_t *paramBuf, uint32_t paramBufLen)
2043 {
2044     (void)ifName;
2045     (void)cmdId;
2046     (void)paramBuf;
2047     (void)paramBufLen;
2048     return RET_CODE_NOT_SUPPORT;
2049 }
2050 
ParseStaTxRate(struct nlattr ** stats,uint32_t size,StationInfo * info)2051 static void ParseStaTxRate(struct nlattr **stats, uint32_t size, StationInfo *info)
2052 {
2053     struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
2054     static struct nla_policy ratePolicy[NL80211_RATE_INFO_MAX + 1];
2055 
2056     if (size < NL80211_STA_INFO_MAX + 1) {
2057         HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
2058         return;
2059     }
2060     ratePolicy[NL80211_RATE_INFO_BITRATE].type = NLA_U16;
2061     ratePolicy[NL80211_RATE_INFO_BITRATE32].type = NLA_U32;
2062     ratePolicy[NL80211_RATE_INFO_MCS].type = NLA_U8;
2063     ratePolicy[NL80211_RATE_INFO_VHT_MCS].type = NLA_U8;
2064     ratePolicy[NL80211_RATE_INFO_SHORT_GI].type = NLA_FLAG;
2065     ratePolicy[NL80211_RATE_INFO_VHT_NSS].type = NLA_U8;
2066     if (stats[NL80211_STA_INFO_TX_BITRATE] != NULL &&
2067         nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_TX_BITRATE], ratePolicy) == 0) {
2068         if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
2069             info->txRate = nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
2070         } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
2071             info->txRate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
2072         }
2073         if (rate[NL80211_RATE_INFO_MCS] != NULL) {
2074             info->txMcs = nla_get_u8(rate[NL80211_RATE_INFO_MCS]);
2075             info->flags |= STA_DRV_DATA_TX_MCS;
2076         }
2077         if (rate[NL80211_RATE_INFO_VHT_MCS] != NULL) {
2078             info->txVhtmcs = nla_get_u8(rate[NL80211_RATE_INFO_VHT_MCS]);
2079             info->flags |= STA_DRV_DATA_TX_VHT_MCS;
2080         }
2081         if (rate[NL80211_RATE_INFO_SHORT_GI] != NULL) {
2082             info->flags |= STA_DRV_DATA_TX_SHORT_GI;
2083         }
2084         if (rate[NL80211_RATE_INFO_VHT_NSS] != NULL) {
2085             info->txVhtNss = nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]);
2086             info->flags |= STA_DRV_DATA_TX_VHT_NSS;
2087         }
2088     }
2089 }
2090 
ParseStaRxRate(struct nlattr ** stats,uint32_t size,StationInfo * info)2091 static void ParseStaRxRate(struct nlattr **stats, uint32_t size, StationInfo *info)
2092 {
2093     struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
2094     static struct nla_policy ratePolicy[NL80211_RATE_INFO_MAX + 1];
2095 
2096     if (size < NL80211_STA_INFO_MAX + 1) {
2097         HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
2098         return;
2099     }
2100     ratePolicy[NL80211_RATE_INFO_BITRATE].type = NLA_U16;
2101     ratePolicy[NL80211_RATE_INFO_BITRATE32].type = NLA_U32;
2102     ratePolicy[NL80211_RATE_INFO_MCS].type = NLA_U8;
2103     ratePolicy[NL80211_RATE_INFO_VHT_MCS].type = NLA_U8;
2104     ratePolicy[NL80211_RATE_INFO_SHORT_GI].type = NLA_FLAG;
2105     ratePolicy[NL80211_RATE_INFO_VHT_NSS].type = NLA_U8;
2106     if (stats[NL80211_STA_INFO_RX_BITRATE] != NULL &&
2107         nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_RX_BITRATE], ratePolicy) == 0) {
2108         if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
2109             info->rxRate = nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
2110         } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
2111             info->rxRate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
2112         }
2113         if (rate[NL80211_RATE_INFO_MCS] != NULL) {
2114             info->rxMcs = nla_get_u8(rate[NL80211_RATE_INFO_MCS]);
2115             info->flags |= STA_DRV_DATA_RX_MCS;
2116         }
2117         if (rate[NL80211_RATE_INFO_VHT_MCS] != NULL) {
2118             info->rxVhtmcs = nla_get_u8(rate[NL80211_RATE_INFO_VHT_MCS]);
2119             info->flags |= STA_DRV_DATA_RX_VHT_MCS;
2120         }
2121         if (rate[NL80211_RATE_INFO_SHORT_GI] != NULL) {
2122             info->flags |= STA_DRV_DATA_RX_SHORT_GI;
2123         }
2124         if (rate[NL80211_RATE_INFO_VHT_NSS] != NULL) {
2125             info->rxVhtNss = nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]);
2126             info->flags |= STA_DRV_DATA_RX_VHT_NSS;
2127         }
2128     }
2129 }
2130 
ParseStaInfo(struct nlattr ** stats,uint32_t size,StationInfo * info)2131 static void ParseStaInfo(struct nlattr **stats, uint32_t size, StationInfo *info)
2132 {
2133     ParseStaTxRate(stats, size, info);
2134     ParseStaRxRate(stats, size, info);
2135 }
2136 
StationInfoHandler(struct nl_msg * msg,void * arg)2137 static int32_t StationInfoHandler(struct nl_msg *msg, void *arg)
2138 {
2139     StationInfo *info = (StationInfo *)arg;
2140     struct genlmsghdr *hdr = NULL;
2141     struct nlattr *attr[NL80211_ATTR_MAX + 1];
2142     struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
2143     static struct nla_policy statsPolicy[NL80211_STA_INFO_MAX + 1];
2144 
2145     statsPolicy[NL80211_STA_INFO_INACTIVE_TIME].type = NLA_U32;
2146     statsPolicy[NL80211_STA_INFO_RX_BYTES].type = NLA_U32;
2147     statsPolicy[NL80211_STA_INFO_TX_BYTES].type = NLA_U32;
2148     statsPolicy[NL80211_STA_INFO_RX_PACKETS].type = NLA_U32;
2149     statsPolicy[NL80211_STA_INFO_TX_PACKETS].type = NLA_U32;
2150     statsPolicy[NL80211_STA_INFO_TX_FAILED].type = NLA_U32;
2151     statsPolicy[NL80211_STA_INFO_RX_BYTES64].type = NLA_U64;
2152     statsPolicy[NL80211_STA_INFO_TX_BYTES64].type = NLA_U64;
2153     statsPolicy[NL80211_STA_INFO_SIGNAL].type = NLA_U8;
2154     statsPolicy[NL80211_STA_INFO_ACK_SIGNAL].type = NLA_U8;
2155     statsPolicy[NL80211_STA_INFO_RX_DURATION].type = NLA_U64;
2156 
2157     hdr = nlmsg_data(nlmsg_hdr(msg));
2158     if (hdr == NULL) {
2159         HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
2160         return NL_SKIP;
2161     }
2162 
2163     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
2164     if (!attr[NL80211_ATTR_STA_INFO]) {
2165         HILOG_ERROR(LOG_CORE, "%s: sta stats missing!", __FUNCTION__);
2166         return NL_SKIP;
2167     }
2168 
2169     if (nla_parse_nested(stats, NL80211_STA_INFO_MAX, attr[NL80211_ATTR_STA_INFO], statsPolicy)) {
2170         HILOG_ERROR(LOG_CORE, "%s: failed to parse nested attributes!", __FUNCTION__);
2171         return NL_SKIP;
2172     }
2173 
2174     ParseStaInfo(stats, NL80211_STA_INFO_MAX + 1, info);
2175     return NL_SKIP;
2176 }
2177 
GetStationInfo(const char * ifName,StationInfo * info,const uint8_t * mac,uint32_t macLen)2178 int32_t GetStationInfo(const char *ifName, StationInfo *info, const uint8_t *mac, uint32_t macLen)
2179 {
2180     uint32_t ifaceId = if_nametoindex(ifName);
2181     struct nl_msg *msg = NULL;
2182     int32_t ret = RET_CODE_FAILURE;
2183 
2184     if (ifaceId == 0) {
2185         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2186         return RET_CODE_FAILURE;
2187     }
2188 
2189     msg = nlmsg_alloc();
2190     if (msg == NULL) {
2191         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2192         return RET_CODE_NOMEM;
2193     }
2194     do {
2195         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_STATION, 0)) {
2196             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2197             break;
2198         }
2199         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId) != RET_CODE_SUCCESS) {
2200             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 ifaceId faile", __FUNCTION__);
2201             break;
2202         }
2203         if (nla_put(msg, NL80211_ATTR_MAC, ETH_ADDR_LEN, mac) != RET_CODE_SUCCESS) {
2204             HILOG_ERROR(LOG_CORE, "%s: nla_put mac address faile", __FUNCTION__);
2205             break;
2206         }
2207 
2208         ret = NetlinkSendCmdSync(msg, StationInfoHandler, info);
2209         if (ret != RET_CODE_SUCCESS) {
2210             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2211         }
2212     } while (0);
2213     nlmsg_free(msg);
2214     return ret;
2215 }
2216 
SetExtFeatureFlag(const uint8_t * extFeatureFlagsBytes,uint32_t extFeatureFlagsLen,uint32_t extFeatureFlag)2217 static bool SetExtFeatureFlag(const uint8_t *extFeatureFlagsBytes, uint32_t extFeatureFlagsLen, uint32_t extFeatureFlag)
2218 {
2219     uint32_t extFeatureFlagBytePos;
2220     uint32_t extFeatureFlagBitPos;
2221 
2222     if (extFeatureFlagsBytes == NULL || extFeatureFlagsLen == 0) {
2223         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2224         return false;
2225     }
2226     extFeatureFlagBytePos = extFeatureFlag / BITNUMS_OF_ONE_BYTE;
2227     extFeatureFlagBitPos = extFeatureFlag % BITNUMS_OF_ONE_BYTE;
2228     if (extFeatureFlagBytePos >= extFeatureFlagsLen) {
2229         return false;
2230     }
2231     return extFeatureFlagsBytes[extFeatureFlagBytePos] & (1U << extFeatureFlagBitPos);
2232 }
2233 
GetWiphyInfoHandler(struct nl_msg * msg,void * arg)2234 static int32_t GetWiphyInfoHandler(struct nl_msg *msg, void *arg)
2235 {
2236     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
2237     struct nlattr *attr[NL80211_ATTR_MAX + 1];
2238     WiphyInfo *wiphyInfo = (WiphyInfo *)arg;
2239     uint32_t featureFlags = 0;
2240     uint8_t *extFeatureFlagsBytes = NULL;
2241     uint32_t extFeatureFlagsLen = 0;
2242 
2243     if (hdr == NULL) {
2244         HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
2245         return NL_SKIP;
2246     }
2247     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
2248     if (attr[NL80211_ATTR_MAX_NUM_SCAN_SSIDS] != NULL) {
2249         wiphyInfo->scanCapabilities.maxNumScanSsids = nla_get_u8(attr[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
2250     }
2251     if (attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS] != NULL) {
2252         wiphyInfo->scanCapabilities.maxNumSchedScanSsids = nla_get_u8(attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
2253     }
2254     if (attr[NL80211_ATTR_MAX_MATCH_SETS] != NULL) {
2255         wiphyInfo->scanCapabilities.maxMatchSets = nla_get_u8(attr[NL80211_ATTR_MAX_MATCH_SETS]);
2256     }
2257     if (attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS] != NULL) {
2258         wiphyInfo->scanCapabilities.maxNumScanPlans = nla_get_u32(attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS]);
2259     }
2260     if (attr[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL] != NULL) {
2261         wiphyInfo->scanCapabilities.maxScanPlanInterval = nla_get_u32(attr[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL]);
2262     }
2263     if (attr[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS] != NULL) {
2264         wiphyInfo->scanCapabilities.maxScanPlanIterations = nla_get_u32(attr[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]);
2265     }
2266     if (attr[NL80211_ATTR_FEATURE_FLAGS] != NULL) {
2267         featureFlags = nla_get_u32(attr[NL80211_ATTR_FEATURE_FLAGS]);
2268     }
2269     wiphyInfo->wiphyFeatures.supportsRandomMacSchedScan = featureFlags & NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
2270     if (attr[NL80211_ATTR_EXT_FEATURES] != NULL) {
2271         extFeatureFlagsBytes = nla_data(attr[NL80211_ATTR_EXT_FEATURES]);
2272         extFeatureFlagsLen = (uint32_t)nla_len(attr[NL80211_ATTR_EXT_FEATURES]);
2273         wiphyInfo->wiphyFeatures.supportsLowPowerOneshotScan =
2274             SetExtFeatureFlag(extFeatureFlagsBytes, extFeatureFlagsLen, NL80211_EXT_FEATURE_LOW_POWER_SCAN);
2275         wiphyInfo->wiphyFeatures.supportsExtSchedScanRelativeRssi =
2276             SetExtFeatureFlag(extFeatureFlagsBytes, extFeatureFlagsLen, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI);
2277     }
2278     return NL_SKIP;
2279 }
2280 
GetWiphyInfo(const uint32_t wiphyIndex,WiphyInfo * wiphyInfo)2281 static int32_t GetWiphyInfo(const uint32_t wiphyIndex, WiphyInfo *wiphyInfo)
2282 {
2283     struct nl_msg *msg = NULL;
2284     int32_t ret = RET_CODE_FAILURE;
2285 
2286     if (wiphyInfo == NULL) {
2287         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2288         return RET_CODE_INVALID_PARAM;
2289     }
2290     msg = nlmsg_alloc();
2291     if (msg == NULL) {
2292         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2293         return RET_CODE_NOMEM;
2294     }
2295     do {
2296         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_WIPHY, 0)) {
2297             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2298             break;
2299         }
2300         if (nla_put_u32(msg, NL80211_ATTR_WIPHY, wiphyIndex) != RET_CODE_SUCCESS) {
2301             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 wiphyIndex failed.", __FUNCTION__);
2302             break;
2303         }
2304         ret = NetlinkSendCmdSync(msg, GetWiphyInfoHandler, wiphyInfo);
2305         if (ret != RET_CODE_SUCCESS) {
2306             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2307         }
2308     } while (0);
2309     nlmsg_free(msg);
2310     return ret;
2311 }
2312 
GetWiphyIndexHandler(struct nl_msg * msg,void * arg)2313 static int32_t GetWiphyIndexHandler(struct nl_msg *msg, void *arg)
2314 {
2315     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
2316     struct nlattr *attr[NL80211_ATTR_MAX + 1];
2317     uint32_t *wiphyIndex = (uint32_t *)arg;
2318 
2319     if (hdr == NULL) {
2320         HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
2321         return NL_SKIP;
2322     }
2323     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
2324     if (!attr[NL80211_ATTR_WIPHY]) {
2325         HILOG_ERROR(LOG_CORE, "%s: wiphy info missing!", __FUNCTION__);
2326         return NL_SKIP;
2327     }
2328     *wiphyIndex = nla_get_u32(attr[NL80211_ATTR_WIPHY]);
2329     return NL_SKIP;
2330 }
2331 
GetWiphyIndex(const char * ifName,uint32_t * wiphyIndex)2332 static int32_t GetWiphyIndex(const char *ifName, uint32_t *wiphyIndex)
2333 {
2334     struct nl_msg *msg = NULL;
2335     uint32_t interfaceId;
2336     int32_t ret = RET_CODE_FAILURE;
2337 
2338     if (ifName == NULL || wiphyIndex == NULL) {
2339         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2340         return RET_CODE_INVALID_PARAM;
2341     }
2342     interfaceId = if_nametoindex(ifName);
2343     if (interfaceId == 0) {
2344         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2345         return RET_CODE_FAILURE;
2346     }
2347     msg = nlmsg_alloc();
2348     if (msg == NULL) {
2349         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2350         return RET_CODE_NOMEM;
2351     }
2352     do {
2353         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0)) {
2354             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2355             break;
2356         }
2357         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2358             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed.", __FUNCTION__);
2359             break;
2360         }
2361         ret = NetlinkSendCmdSync(msg, GetWiphyIndexHandler, wiphyIndex);
2362         if (ret != RET_CODE_SUCCESS) {
2363             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2364         }
2365     } while (0);
2366     nlmsg_free(msg);
2367     return ret;
2368 }
2369 
ProcessMatchSsidToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2370 static int32_t ProcessMatchSsidToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2371 {
2372     struct nlattr *nestedMatchSsid = NULL;
2373     struct nlattr *nest = NULL;
2374     uint8_t matchSsidsCount = 0;
2375 
2376     nestedMatchSsid = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
2377     if (nestedMatchSsid == NULL) {
2378         HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2379         return RET_CODE_FAILURE;
2380     }
2381     for (uint32_t i = 0; i < pnoSettings->pnoNetworksLen; i++) {
2382         if (matchSsidsCount + 1 > wiphyInfo->scanCapabilities.maxMatchSets) {
2383             break;
2384         }
2385         nest = nla_nest_start(msg, i);
2386         if (nest == NULL) {
2387             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2388             return RET_CODE_FAILURE;
2389         }
2390         nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID, pnoSettings->pnoNetworks[i].ssid.ssidLen,
2391             pnoSettings->pnoNetworks[i].ssid.ssid);
2392         nla_put_u32(msg, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI, pnoSettings->min5gRssi);
2393         nla_nest_end(msg, nest);
2394         matchSsidsCount++;
2395     }
2396     nla_nest_end(msg, nestedMatchSsid);
2397     return RET_CODE_SUCCESS;
2398 }
2399 
ClearSsidsList(struct DListHead * ssidsList)2400 static void ClearSsidsList(struct DListHead *ssidsList)
2401 {
2402     struct SsidListNode *ssidListNode = NULL;
2403     struct SsidListNode *tmp = NULL;
2404 
2405     DLIST_FOR_EACH_ENTRY_SAFE(ssidListNode, tmp, ssidsList, struct SsidListNode, entry) {
2406         DListRemove(&ssidListNode->entry);
2407         free(ssidListNode);
2408         ssidListNode = NULL;
2409     }
2410     DListHeadInit(ssidsList);
2411 }
2412 
ProcessSsidToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2413 static int32_t ProcessSsidToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2414 {
2415     uint8_t scanSsidsCount = 0;
2416     struct SsidListNode *ssidListNode = NULL;
2417     struct nlattr *nestedSsid = NULL;
2418     uint32_t index = 0;
2419     struct DListHead scanSsids = {0};
2420 
2421     DListHeadInit(&scanSsids);
2422     for (uint32_t i = 0; i < pnoSettings->pnoNetworksLen; i++) {
2423         if (!(pnoSettings->pnoNetworks[i].isHidden)) {
2424             continue;
2425         }
2426         if (scanSsidsCount + 1 > wiphyInfo->scanCapabilities.maxNumSchedScanSsids) {
2427             break;
2428         }
2429         struct SsidListNode *ssidNode = (struct SsidListNode *)malloc(sizeof(struct SsidListNode));
2430         if (ssidNode == NULL) {
2431             HILOG_ERROR(LOG_CORE, "%s: malloc failed.", __FUNCTION__);
2432             ClearSsidsList(&scanSsids);
2433             return RET_CODE_FAILURE;
2434         }
2435         (void)memset_s(ssidNode, sizeof(struct SsidListNode), 0, sizeof(struct SsidListNode));
2436         ssidNode->ssidInfo.ssidLen = pnoSettings->pnoNetworks[i].ssid.ssidLen;
2437         if (memcpy_s(ssidNode->ssidInfo.ssid, MAX_SSID_LEN, pnoSettings->pnoNetworks[i].ssid.ssid,
2438                 pnoSettings->pnoNetworks[i].ssid.ssidLen) != EOK) {
2439             HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed.", __FUNCTION__);
2440             ClearSsidsList(&scanSsids);
2441             return RET_CODE_FAILURE;
2442         }
2443         DListInsertTail(&ssidNode->entry, &scanSsids);
2444         scanSsidsCount++;
2445     }
2446     if (!DListIsEmpty(&scanSsids)) {
2447         nestedSsid = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
2448         if (nestedSsid == NULL) {
2449             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2450             ClearSsidsList(&scanSsids);
2451             return RET_CODE_FAILURE;
2452         }
2453         DLIST_FOR_EACH_ENTRY(ssidListNode, &scanSsids, struct SsidListNode, entry) {
2454             nla_put(msg, index, ssidListNode->ssidInfo.ssidLen, ssidListNode->ssidInfo.ssid);
2455             index++;
2456         }
2457         nla_nest_end(msg, nestedSsid);
2458     }
2459     ClearSsidsList(&scanSsids);
2460     return RET_CODE_SUCCESS;
2461 }
2462 
ProcessScanPlanToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2463 static int32_t ProcessScanPlanToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2464 {
2465     struct nlattr *nestedPlan = NULL;
2466     struct nlattr *plan = NULL;
2467 
2468     bool supportNumScanPlans = (wiphyInfo->scanCapabilities.maxNumScanPlans >= 2);
2469     bool supportScanPlanInterval = (wiphyInfo->scanCapabilities.maxScanPlanInterval * MS_PER_SECOND >=
2470         (uint32_t)pnoSettings->scanIntervalMs * SLOW_SCAN_INTERVAL_MULTIPLIER);
2471     bool supportScanPlanIterations = (wiphyInfo->scanCapabilities.maxScanPlanIterations >= FAST_SCAN_ITERATIONS);
2472 
2473     if (supportNumScanPlans && supportScanPlanInterval && supportScanPlanIterations) {
2474         nestedPlan = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
2475         if (nestedPlan == NULL) {
2476             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2477             return RET_CODE_FAILURE;
2478         }
2479         plan = nla_nest_start(msg, SCHED_SCAN_PLANS_ATTR_INDEX1);
2480         nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL, pnoSettings->scanIntervalMs);
2481         nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS, pnoSettings->scanIterations);
2482         nla_nest_end(msg, plan);
2483         plan = nla_nest_start(msg, SCHED_SCAN_PLANS_ATTR_INDEX2);
2484         nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL, pnoSettings->scanIntervalMs * SLOW_SCAN_INTERVAL_MULTIPLIER);
2485         nla_nest_end(msg, plan);
2486         nla_nest_end(msg, nestedPlan);
2487     } else {
2488         nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, pnoSettings->scanIntervalMs * MS_PER_SECOND);
2489     }
2490     return RET_CODE_SUCCESS;
2491 }
2492 
ClearFreqsList(struct DListHead * freqsList)2493 static void ClearFreqsList(struct DListHead *freqsList)
2494 {
2495     struct FreqListNode *freqListNode = NULL;
2496     struct FreqListNode *tmp = NULL;
2497 
2498     DLIST_FOR_EACH_ENTRY_SAFE(freqListNode, tmp, freqsList, struct FreqListNode, entry) {
2499         DListRemove(&freqListNode->entry);
2500         free(freqListNode);
2501         freqListNode = NULL;
2502     }
2503     DListHeadInit(freqsList);
2504 }
2505 
InsertFreqToList(int32_t freq,struct DListHead * scanFreqs)2506 static int32_t InsertFreqToList(int32_t freq, struct DListHead *scanFreqs)
2507 {
2508     bool isFreqExist = false;
2509     struct FreqListNode *freqListNode = NULL;
2510 
2511     DLIST_FOR_EACH_ENTRY(freqListNode, scanFreqs, struct FreqListNode, entry) {
2512         if (freqListNode == NULL) {
2513             HILOG_ERROR(LOG_CORE, "%s: freqListNode is NULL.", __FUNCTION__);
2514             return RET_CODE_FAILURE;
2515         }
2516         if (freqListNode->freq == freq) {
2517             isFreqExist = true;
2518             break;
2519         }
2520     }
2521     if (!isFreqExist) {
2522         struct FreqListNode *freqNode = (struct FreqListNode *)malloc(sizeof(struct FreqListNode));
2523         if (freqNode == NULL) {
2524             HILOG_ERROR(LOG_CORE, "%s: malloc failed.", __FUNCTION__);
2525             return RET_CODE_FAILURE;
2526         }
2527         (void)memset_s(freqNode, sizeof(struct FreqListNode), 0, sizeof(struct FreqListNode));
2528         freqNode->freq = freq;
2529         DListInsertTail(&freqNode->entry, scanFreqs);
2530     }
2531     return RET_CODE_SUCCESS;
2532 }
2533 
ProcessFreqToMsg(struct nl_msg * msg,const WifiPnoSettings * pnoSettings)2534 static int32_t ProcessFreqToMsg(struct nl_msg *msg, const WifiPnoSettings *pnoSettings)
2535 {
2536     struct FreqListNode *freqListNode = NULL;
2537     struct DListHead scanFreqs = {0};
2538     struct nlattr *nestedFreq = NULL;
2539     uint32_t index = 0;
2540 
2541     DListHeadInit(&scanFreqs);
2542     for (uint32_t i = 0; i < pnoSettings->pnoNetworksLen; i++) {
2543         for (uint32_t j = 0; j < pnoSettings->pnoNetworks[i].freqsLen; j++) {
2544             if (InsertFreqToList(pnoSettings->pnoNetworks[i].freqs[j], &scanFreqs) != RET_CODE_SUCCESS) {
2545                 HILOG_ERROR(LOG_CORE, "%s: InsertFreqToList failed.", __FUNCTION__);
2546                 ClearFreqsList(&scanFreqs);
2547                 return RET_CODE_FAILURE;
2548             }
2549         }
2550     }
2551     if (!DListIsEmpty(&scanFreqs)) {
2552         nestedFreq = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
2553         if (nestedFreq == NULL) {
2554             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2555             ClearFreqsList(&scanFreqs);
2556             return RET_CODE_FAILURE;
2557         }
2558         DLIST_FOR_EACH_ENTRY(freqListNode, &scanFreqs, struct FreqListNode, entry) {
2559             nla_put_s32(msg, index, freqListNode->freq);
2560             index++;
2561         }
2562         nla_nest_end(msg, nestedFreq);
2563     }
2564     ClearFreqsList(&scanFreqs);
2565     return RET_CODE_SUCCESS;
2566 }
2567 
ProcessReqflagsToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2568 static int32_t ProcessReqflagsToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2569 {
2570     uint32_t scanFlag = 0;
2571 
2572     if (wiphyInfo->wiphyFeatures.supportsExtSchedScanRelativeRssi) {
2573         struct nl80211_bss_select_rssi_adjust rssiAdjust;
2574         (void)memset_s(&rssiAdjust, sizeof(rssiAdjust), 0, sizeof(rssiAdjust));
2575         rssiAdjust.band = NL80211_BAND_2GHZ;
2576         rssiAdjust.delta = pnoSettings->min2gRssi - pnoSettings->min5gRssi;
2577         nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST, sizeof(rssiAdjust), &rssiAdjust);
2578     }
2579     if (wiphyInfo->wiphyFeatures.supportsRandomMacSchedScan) {
2580         scanFlag |= NL80211_SCAN_FLAG_RANDOM_ADDR;
2581     }
2582     if (wiphyInfo->wiphyFeatures.supportsLowPowerOneshotScan) {
2583         scanFlag |= NL80211_SCAN_FLAG_LOW_POWER;
2584     }
2585     if (scanFlag != 0) {
2586         nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, scanFlag);
2587     }
2588     return RET_CODE_SUCCESS;
2589 }
2590 
ConvertSetsToNetlinkmsg(struct nl_msg * msg,const char * ifName,const WifiPnoSettings * pnoSettings)2591 static int32_t ConvertSetsToNetlinkmsg(struct nl_msg *msg, const char *ifName, const WifiPnoSettings *pnoSettings)
2592 {
2593     int32_t ret;
2594     uint32_t wiphyIndex;
2595     WiphyInfo wiphyInfo;
2596 
2597     (void)memset_s(&wiphyInfo, sizeof(wiphyInfo), 0, sizeof(wiphyInfo));
2598     ret = GetWiphyIndex(ifName, &wiphyIndex);
2599     if (ret != RET_CODE_SUCCESS) {
2600         HILOG_ERROR(LOG_CORE, "%s: GetWiphyIndex failed", __FUNCTION__);
2601         return RET_CODE_FAILURE;
2602     }
2603     ret = GetWiphyInfo(wiphyIndex, &wiphyInfo);
2604     if (ret != RET_CODE_SUCCESS) {
2605         HILOG_ERROR(LOG_CORE, "%s: GetWiphyInfo failed", __FUNCTION__);
2606         return RET_CODE_FAILURE;
2607     }
2608     if (ProcessMatchSsidToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2609         ProcessSsidToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2610         ProcessScanPlanToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2611         ProcessReqflagsToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2612         ProcessFreqToMsg(msg, pnoSettings) != RET_CODE_SUCCESS) {
2613         HILOG_ERROR(LOG_CORE, "%s: Fill parameters to netlink failed.", __FUNCTION__);
2614         return RET_CODE_FAILURE;
2615     }
2616     return RET_CODE_SUCCESS;
2617 }
2618 
WifiStartPnoScan(const char * ifName,const WifiPnoSettings * pnoSettings)2619 int32_t WifiStartPnoScan(const char *ifName, const WifiPnoSettings *pnoSettings)
2620 {
2621     HILOG_INFO(LOG_CORE, "hal enter %{public}s ifName:%{public}s", __FUNCTION__, ifName);
2622     uint32_t interfaceId;
2623     struct nl_msg *msg = NULL;
2624     int32_t ret = RET_CODE_FAILURE;
2625 
2626     interfaceId = if_nametoindex(ifName);
2627     if (interfaceId == 0) {
2628         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2629         return RET_CODE_FAILURE;
2630     }
2631     msg = nlmsg_alloc();
2632     if (msg == NULL) {
2633         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2634         return RET_CODE_NOMEM;
2635     }
2636     do {
2637         HILOG_INFO(LOG_CORE, "genlmsg_put NL80211_CMD_START_SCHED_SCAN");
2638         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_ACK, NL80211_CMD_START_SCHED_SCAN, 0)) {
2639             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2640             break;
2641         }
2642         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2643             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed.", __FUNCTION__);
2644             break;
2645         }
2646         if (ConvertSetsToNetlinkmsg(msg, ifName, pnoSettings) != RET_CODE_SUCCESS) {
2647             HILOG_ERROR(LOG_CORE, "%s: ConvertSetsToNetlinkmsg failed.", __FUNCTION__);
2648             break;
2649         }
2650         ret = NetlinkSendCmdSync(msg, NULL, NULL);
2651         if (ret != RET_CODE_SUCCESS) {
2652             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2653         }
2654     } while (0);
2655     nlmsg_free(msg);
2656     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
2657     return ret;
2658 }
2659 
WifiStopPnoScan(const char * ifName)2660 int32_t WifiStopPnoScan(const char *ifName)
2661 {
2662     HILOG_INFO(LOG_CORE, "hal enter %{public}s ifName:%{public}s", __FUNCTION__, ifName);
2663     uint32_t interfaceId;
2664     struct nl_msg *msg = NULL;
2665     int32_t ret = RET_CODE_FAILURE;
2666 
2667     interfaceId = if_nametoindex(ifName);
2668     if (interfaceId == 0) {
2669         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2670         return RET_CODE_FAILURE;
2671     }
2672     msg = nlmsg_alloc();
2673     if (msg == NULL) {
2674         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2675         return RET_CODE_NOMEM;
2676     }
2677     do {
2678         HILOG_INFO(LOG_CORE, "genlmsg_put NL80211_CMD_STOP_SCHED_SCAN");
2679         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_ACK, NL80211_CMD_STOP_SCHED_SCAN, 0)) {
2680             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2681             break;
2682         }
2683         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2684             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed.", __FUNCTION__);
2685             break;
2686         }
2687         ret = NetlinkSendCmdSync(msg, NULL, NULL);
2688         if (ret != RET_CODE_SUCCESS) {
2689             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2690         }
2691     } while (0);
2692     nlmsg_free(msg);
2693     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
2694     return ret;
2695 }
2696 
GetAssociatedInfoHandler(struct nl_msg * msg,void * arg)2697 static int32_t GetAssociatedInfoHandler(struct nl_msg *msg, void *arg)
2698 {
2699     struct nlattr *attr[NL80211_ATTR_MAX + 1];
2700     struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2701     struct nlattr *bss[NL80211_BSS_MAX + 1];
2702     uint32_t status;
2703     AssociatedInfo *associatedInfo = (AssociatedInfo *)arg;
2704     struct nla_policy bssPolicy[NL80211_BSS_MAX + 1];
2705     bssPolicy[NL80211_BSS_BSSID].type = NLA_UNSPEC;
2706     bssPolicy[NL80211_BSS_FREQUENCY].type = NLA_U32;
2707     bssPolicy[NL80211_BSS_STATUS].type = NLA_U32;
2708 
2709     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
2710     if (!attr[NL80211_ATTR_BSS]) {
2711         HILOG_ERROR(LOG_CORE, "%s: BSS info missing!", __FUNCTION__);
2712         return NL_SKIP;
2713     }
2714     if (nla_parse_nested(bss, NL80211_BSS_MAX, attr[NL80211_ATTR_BSS], bssPolicy) < 0 ||
2715         bss[NL80211_BSS_STATUS] == NULL) {
2716         HILOG_INFO(LOG_CORE, "%s: BSS attr or status missing!", __FUNCTION__);
2717         return NL_SKIP;
2718     }
2719     status = nla_get_u32(bss[NL80211_BSS_STATUS]);
2720     if (status == BSS_STATUS_ASSOCIATED && bss[NL80211_BSS_FREQUENCY]) {
2721         associatedInfo->associatedFreq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
2722     }
2723     if (status == BSS_STATUS_ASSOCIATED && bss[NL80211_BSS_BSSID]) {
2724         if (memcpy_s(associatedInfo->associatedBssid, ETH_ADDR_LEN,
2725             nla_data(bss[NL80211_BSS_BSSID]), ETH_ADDR_LEN) != EOK) {
2726             HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed!", __FUNCTION__);
2727             return NL_SKIP;
2728         }
2729     }
2730     return NL_SKIP;
2731 }
2732 
WifiGetAssociatedInfo(const char * ifName,AssociatedInfo * associatedInfo)2733 static int32_t WifiGetAssociatedInfo(const char *ifName, AssociatedInfo *associatedInfo)
2734 {
2735     HILOG_INFO(LOG_CORE, "hal enter %{public}s ifName:%{public}s", __FUNCTION__, ifName);
2736     struct nl_msg *msg = NULL;
2737     uint32_t interfaceId;
2738     int32_t ret = RET_CODE_FAILURE;
2739 
2740     interfaceId = if_nametoindex(ifName);
2741     if (interfaceId == 0) {
2742         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2743         return RET_CODE_FAILURE;
2744     }
2745     msg = nlmsg_alloc();
2746     if (msg == NULL) {
2747         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2748         return RET_CODE_NOMEM;
2749     }
2750     do {
2751         HILOG_INFO(LOG_CORE, "genlmsg_put NL80211_CMD_GET_SCAN");
2752         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0)) {
2753             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2754             break;
2755         }
2756         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2757             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId faile", __FUNCTION__);
2758             break;
2759         }
2760         ret = NetlinkSendCmdSync(msg, GetAssociatedInfoHandler, associatedInfo);
2761         if (ret != RET_CODE_SUCCESS) {
2762             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2763         }
2764     } while (0);
2765     nlmsg_free(msg);
2766     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
2767     return ret;
2768 }
2769 
FillSignalExt(struct nlattr ** stats,uint32_t size,struct SignalResult * signalResult)2770 static void FillSignalExt(struct nlattr **stats, uint32_t size, struct SignalResult *signalResult)
2771 {
2772     if (size < NL80211_STA_INFO_MAX + 1) {
2773         HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
2774         return;
2775     }
2776 
2777     if (stats[NL80211_STA_INFO_NOISE] != NULL) {
2778         signalResult->currentNoise = nla_get_s32(stats[NL80211_STA_INFO_NOISE]);
2779     }
2780     if (stats[NL80211_STA_INFO_SNR] != NULL) {
2781         signalResult->currentSnr = nla_get_s32(stats[NL80211_STA_INFO_SNR]);
2782     }
2783     if (stats[NL80211_STA_INFO_CNAHLOAD] != NULL) {
2784         signalResult->currentChload = nla_get_s32(stats[NL80211_STA_INFO_CNAHLOAD]);
2785     }
2786     if (stats[NL80211_STA_INFO_UL_DELAY] != NULL) {
2787         signalResult->currentUlDelay = nla_get_s32(stats[NL80211_STA_INFO_UL_DELAY]);
2788     }
2789 }
2790 
FillSignalRate(struct nlattr ** stats,uint32_t size,struct SignalResult * signalResult)2791 static void FillSignalRate(struct nlattr **stats, uint32_t size, struct SignalResult *signalResult)
2792 {
2793     struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
2794     struct nla_policy ratePolicy[NL80211_RATE_INFO_MAX + 1];
2795     ratePolicy[NL80211_RATE_INFO_BITRATE].type = NLA_U16;
2796     ratePolicy[NL80211_RATE_INFO_BITRATE32].type = NLA_U32;
2797 
2798     if (size < NL80211_STA_INFO_MAX + 1) {
2799         HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
2800         return;
2801     }
2802     if (stats[NL80211_STA_INFO_RX_BITRATE] != NULL &&
2803         nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_RX_BITRATE], ratePolicy) == 0) {
2804         if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
2805             signalResult->rxBitrate = (int32_t)nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
2806         } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
2807             signalResult->rxBitrate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
2808         }
2809     }
2810     if (stats[NL80211_STA_INFO_TX_BITRATE] != NULL &&
2811         nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_TX_BITRATE], ratePolicy) == 0) {
2812         if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
2813             signalResult->txBitrate = (int32_t)nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
2814         } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
2815             signalResult->txBitrate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
2816         }
2817     }
2818 }
2819 
SignalInfoHandler(struct nl_msg * msg,void * arg)2820 static int32_t SignalInfoHandler(struct nl_msg *msg, void *arg)
2821 {
2822     struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2823     struct nlattr *attr[NL80211_ATTR_MAX + 1];
2824     struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
2825     struct nla_policy statsPolicy[NL80211_STA_INFO_MAX + 1];
2826     struct SignalResult *signalResult = (struct SignalResult *)arg;
2827     statsPolicy[NL80211_STA_INFO_SIGNAL].type = NLA_S8;
2828     statsPolicy[NL80211_STA_INFO_RX_BYTES].type = NLA_U32;
2829     statsPolicy[NL80211_STA_INFO_TX_BYTES].type = NLA_U32;
2830     statsPolicy[NL80211_STA_INFO_RX_PACKETS].type = NLA_U32;
2831     statsPolicy[NL80211_STA_INFO_TX_PACKETS].type = NLA_U32;
2832     statsPolicy[NL80211_STA_INFO_TX_FAILED].type = NLA_U32;
2833     statsPolicy[NL80211_STA_INFO_NOISE].type = NLA_S32;
2834     statsPolicy[NL80211_STA_INFO_SNR].type = NLA_S32;
2835     statsPolicy[NL80211_STA_INFO_CNAHLOAD].type = NLA_S32;
2836     statsPolicy[NL80211_STA_INFO_UL_DELAY].type = NLA_S32;
2837 
2838     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
2839     if (!attr[NL80211_ATTR_STA_INFO]) {
2840         HILOG_ERROR(LOG_CORE, "%s: sta stats missing!", __FUNCTION__);
2841         return NL_SKIP;
2842     }
2843     if (nla_parse_nested(stats, NL80211_STA_INFO_MAX, attr[NL80211_ATTR_STA_INFO], statsPolicy) < 0) {
2844         HILOG_ERROR(LOG_CORE, "%s: nla_parse_nested NL80211_ATTR_STA_INFO failed!", __FUNCTION__);
2845         return NL_SKIP;
2846     }
2847     if (stats[NL80211_STA_INFO_SIGNAL] != NULL) {
2848         signalResult->currentRssi = nla_get_s8(stats[NL80211_STA_INFO_SIGNAL]);
2849     }
2850     if (stats[NL80211_STA_INFO_TX_BYTES] != NULL) {
2851         signalResult->currentTxBytes = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
2852     }
2853     if (stats[NL80211_STA_INFO_RX_BYTES] != NULL) {
2854         signalResult->currentRxBytes = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
2855     }
2856     if (stats[NL80211_STA_INFO_TX_PACKETS] != NULL) {
2857         signalResult->currentTxPackets = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
2858     }
2859     if (stats[NL80211_STA_INFO_RX_PACKETS] != NULL) {
2860         signalResult->currentRxPackets = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
2861     }
2862     if (stats[NL80211_STA_INFO_TX_FAILED] != NULL) {
2863         signalResult->currentTxFailed = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
2864     }
2865     FillSignalExt(stats, NL80211_STA_INFO_MAX + 1, signalResult);
2866     FillSignalRate(stats, NL80211_STA_INFO_MAX + 1, signalResult);
2867 
2868     return NL_SKIP;
2869 }
2870 
ClientGetApBandwidth(const char * ifName,uint8_t * bandwidth)2871 int32_t ClientGetApBandwidth(const char *ifName, uint8_t *bandwidth)
2872 {
2873     if (ifName == NULL || bandwidth == NULL) {
2874         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2875         return RET_CODE_FAILURE;
2876     }
2877 
2878     const char *cmd = CMD_GET_AP_BANDWIDTH;
2879     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2880     WifiPrivCmd out = {0};
2881     out.buf = buf;
2882     out.size = MAX_PRIV_CMD_SIZE;
2883     int32_t ret = SendCommandToDriver(cmd, strlen(cmd), ifName, &out);
2884     if (ret != RET_CODE_SUCCESS) {
2885         HILOG_ERROR(LOG_CORE, "%s: send command to driver failed, code=%d", __FUNCTION__, ret);
2886         return ret;
2887     }
2888     *bandwidth = *out.buf;
2889 
2890     HILOG_INFO(LOG_CORE, "%s: AP bandwidth: %d", __FUNCTION__, *bandwidth);
2891     return RET_CODE_SUCCESS;
2892 }
2893 
WifiGetSignalPollInfo(const char * ifName,struct SignalResult * signalResult)2894 int32_t WifiGetSignalPollInfo(const char *ifName, struct SignalResult *signalResult)
2895 {
2896     struct nl_msg *msg = NULL;
2897     uint32_t interfaceId;
2898     int32_t ret = RET_CODE_FAILURE;
2899     AssociatedInfo associatedInfo;
2900     (void)memset_s(&associatedInfo, sizeof(associatedInfo), 0, sizeof(associatedInfo));
2901 
2902     if (ifName == NULL || signalResult == NULL) {
2903         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2904         return RET_CODE_FAILURE;
2905     }
2906     interfaceId = if_nametoindex(ifName);
2907     if (interfaceId == 0) {
2908         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2909         return RET_CODE_FAILURE;
2910     }
2911     if (WifiGetAssociatedInfo(ifName, &associatedInfo) != RET_CODE_SUCCESS) {
2912         HILOG_ERROR(LOG_CORE, "%s: WifiGetAssociatedInfo failed", __FUNCTION__);
2913         return RET_CODE_FAILURE;
2914     }
2915     signalResult->associatedFreq = (int32_t)(associatedInfo.associatedFreq);
2916     msg = nlmsg_alloc();
2917     if (msg == NULL) {
2918         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2919         return RET_CODE_NOMEM;
2920     }
2921     do {
2922         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_STATION, 0)) {
2923             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2924             break;
2925         }
2926         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2927             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId faile", __FUNCTION__);
2928             break;
2929         }
2930         if (nla_put(msg, NL80211_ATTR_MAC, ETH_ADDR_LEN, associatedInfo.associatedBssid) != RET_CODE_SUCCESS) {
2931             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId faile", __FUNCTION__);
2932             break;
2933         }
2934         ret = NetlinkSendCmdSync(msg, SignalInfoHandler, signalResult);
2935         if (ret != RET_CODE_SUCCESS) {
2936             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2937         }
2938     } while (0);
2939     nlmsg_free(msg);
2940     return ret;
2941 }
2942 
WifiAbortScan(const char * ifName)2943 static int32_t WifiAbortScan(const char *ifName)
2944 {
2945     HILOG_INFO(LOG_CORE, "hal enter %{public}s ifName:%{public}s", __FUNCTION__, ifName);
2946     int32_t ret = RET_CODE_FAILURE;
2947     struct nl_msg *msg = NULL;
2948     uint32_t interfaceId;
2949     if (ifName == NULL) {
2950         HILOG_ERROR(LOG_CORE, "%s: ifName is NULL.", __FUNCTION__);
2951         return RET_CODE_FAILURE;
2952     }
2953     interfaceId = if_nametoindex(ifName);
2954     if (interfaceId == 0) {
2955         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2956         return RET_CODE_FAILURE;
2957     }
2958     msg = nlmsg_alloc();
2959     if (msg == NULL) {
2960         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2961         return RET_CODE_NOMEM;
2962     }
2963     do {
2964         HILOG_INFO(LOG_CORE, "genlmsg_put NL80211_CMD_ABORT_SCAN");
2965         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_ABORT_SCAN, 0)) {
2966             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2967             break;
2968         }
2969         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2970             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed", __FUNCTION__);
2971             break;
2972         }
2973         ret = NetlinkSendCmdSync(msg, NULL, NULL);
2974         if (ret != RET_CODE_SUCCESS) {
2975             HILOG_ERROR(LOG_CORE, "%s: abort scan failed", __FUNCTION__);
2976         }
2977     } while (0);
2978     nlmsg_free(msg);
2979     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
2980     return ret;
2981 }
2982 
WifiSendActionFrameHandler(struct nl_msg * msg,void * arg)2983 static int32_t WifiSendActionFrameHandler(struct nl_msg *msg, void *arg)
2984 {
2985     return NL_SKIP;
2986 }
2987 
WifiSendActionFrame(const char * ifName,uint32_t freq,const uint8_t * frameData,uint32_t frameDataLen)2988 int32_t WifiSendActionFrame(const char *ifName, uint32_t freq, const uint8_t *frameData, uint32_t frameDataLen)
2989 {
2990     int32_t ret = RET_CODE_FAILURE;
2991     struct nl_msg *msg = NULL;
2992     uint32_t interfaceId;
2993     uint64_t cookie;
2994     if (ifName == NULL || freq == 0 || frameData == NULL || frameDataLen == 0) {
2995         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2996         return RET_CODE_FAILURE;
2997     }
2998     interfaceId = if_nametoindex(ifName);
2999     if (interfaceId == 0) {
3000         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
3001         return RET_CODE_FAILURE;
3002     }
3003     ret = WifiAbortScan(STR_WLAN0);
3004     if (ret != RET_CODE_SUCCESS) {
3005         HILOG_ERROR(LOG_CORE, "%s: wifi abort scan failed", __FUNCTION__);
3006         return ret;
3007     }
3008     msg = nlmsg_alloc();
3009     if (msg == NULL) {
3010         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
3011         return RET_CODE_NOMEM;
3012     }
3013     do {
3014         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_FRAME, 0)) {
3015             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
3016             break;
3017         }
3018         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
3019             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed", __FUNCTION__);
3020             break;
3021         }
3022         if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) != RET_CODE_SUCCESS) {
3023             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 freq failed", __FUNCTION__);
3024             break;
3025         }
3026         if (nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK) != RET_CODE_SUCCESS) {
3027             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 offchannel failed", __FUNCTION__);
3028             break;
3029         }
3030         if (nla_put(msg, NL80211_ATTR_FRAME, frameDataLen, frameData) != RET_CODE_SUCCESS) {
3031             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 frameData failed", __FUNCTION__);
3032             break;
3033         }
3034         cookie = 0;
3035         ret = NetlinkSendCmdSync(msg, WifiSendActionFrameHandler, &cookie);
3036         if (ret != RET_CODE_SUCCESS) {
3037             HILOG_ERROR(LOG_CORE, "%s: send action failed", __FUNCTION__);
3038         }
3039     } while (0);
3040     nlmsg_free(msg);
3041     return ret;
3042 }
3043 
WifiRegisterActionFrameReceiver(const char * ifName,const uint8_t * match,uint32_t matchLen)3044 int32_t WifiRegisterActionFrameReceiver(const char *ifName, const uint8_t *match, uint32_t matchLen)
3045 {
3046     int32_t ret = RET_CODE_FAILURE;
3047     struct nl_msg *msg = NULL;
3048     uint32_t interfaceId;
3049     if (ifName == NULL || match == NULL || matchLen == 0) {
3050         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
3051         return RET_CODE_FAILURE;
3052     }
3053     interfaceId = if_nametoindex(ifName);
3054     if (interfaceId == 0) {
3055         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
3056         return RET_CODE_FAILURE;
3057     }
3058     msg = nlmsg_alloc();
3059     if (msg == NULL) {
3060         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
3061         return RET_CODE_NOMEM;
3062     }
3063     do {
3064         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_REGISTER_FRAME, 0)) {
3065             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
3066             break;
3067         }
3068         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
3069             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed", __FUNCTION__);
3070             break;
3071         }
3072         if (nla_put(msg, NL80211_ATTR_FRAME_MATCH, matchLen, match) != RET_CODE_SUCCESS) {
3073             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 frameData failed", __FUNCTION__);
3074             break;
3075         }
3076         if (g_wifiHalInfo.ctrlSock == NULL) {
3077             HILOG_ERROR(LOG_CORE, "%s: ctrlSock is NULL", __FUNCTION__);
3078             break;
3079         }
3080         ret = nl_send_auto(g_wifiHalInfo.ctrlSock, msg);
3081         if (ret < 0) {
3082             HILOG_ERROR(LOG_CORE, "%s: register ctrl sock failed", __FUNCTION__);
3083             break;
3084         }
3085         ret = RET_CODE_SUCCESS;
3086     } while (0);
3087     nlmsg_free(msg);
3088     return ret;
3089 }
3090