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