• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <net/if.h>
17 #include <arpa/inet.h>
18 #include <dirent.h>
19 #include <netlink-private/types.h>
20 #include <netlink/genl/ctrl.h>
21 #include <netlink/genl/genl.h>
22 #include <netlink/handlers.h>
23 #include <securec.h>
24 #include <stdbool.h>
25 #include <stdio.h>
26 #include <sys/ioctl.h>
27 #include <sys/socket.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31 #include <linux/ethtool.h>
32 #include <linux/if_arp.h>
33 #include <linux/netlink.h>
34 #include <linux/nl80211.h>
35 #include <linux/sockios.h>
36 #include <linux/wireless.h>
37 #include <linux/version.h>
38 #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 == RET_CODE_FAILURE) {
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     pthread_setname_np(g_wifiHalInfo.thread, "WifiHalThread");
715 
716     // waiting for thread start running
717     while (g_wifiHalInfo.status != THREAD_RUN) {
718         HILOG_INFO(LOG_CORE, "%s: waiting for thread start running.", __FUNCTION__);
719         if (count < RETRIES) {
720             count++;
721             usleep(WAITFORTHREAD);
722         } else {
723             HILOG_ERROR(LOG_CORE, "%s: warit for thread running timeout", __FUNCTION__);
724             if (g_wifiHalInfo.status != THREAD_STOP) {
725                 g_wifiHalInfo.status = THREAD_STOP;
726                 pthread_join(g_wifiHalInfo.thread, NULL);
727             }
728             return RET_CODE_FAILURE;
729         }
730     }
731     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
732     return RET_CODE_SUCCESS;
733 }
734 
WifiMsgUnregisterEventListener(void)735 static void WifiMsgUnregisterEventListener(void)
736 {
737     HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
738     g_wifiHalInfo.status = THREAD_STOPPING;
739     pthread_join(g_wifiHalInfo.thread, NULL);
740     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
741 }
742 
WifiDriverClientInit(void)743 int32_t WifiDriverClientInit(void)
744 {
745     HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
746     if (g_wifiHalInfo.cmdSock != NULL) {
747         HILOG_ERROR(LOG_CORE, "%s: already create cmd socket", __FUNCTION__);
748         return RET_CODE_FAILURE;
749     }
750 
751     if (InitEventcallbackMutex() != RET_CODE_SUCCESS) {
752         HILOG_ERROR(LOG_CORE, "%s: init callbackmutex failed.", __FUNCTION__);
753         return RET_CODE_FAILURE;
754     }
755 
756     if (pthread_mutex_init(&g_wifiHalInfo.mutex, NULL) != RET_CODE_SUCCESS) {
757         HILOG_ERROR(LOG_CORE, "%s: init mutex failed.", __FUNCTION__);
758         goto err_mutex;
759     }
760 
761     if (ConnectCmdSocket() != RET_CODE_SUCCESS) {
762         HILOG_ERROR(LOG_CORE, "%s: connect cmd socket failed.", __FUNCTION__);
763         goto err_cmd;
764     }
765 
766     if (ConnectCtrlSocket() != RET_CODE_SUCCESS) {
767         HILOG_ERROR(LOG_CORE, "%s: connect ctrl socket failed", __FUNCTION__);
768         goto err_ctrl;
769     }
770 
771     if (ConnectEventSocket() != RET_CODE_SUCCESS) {
772         HILOG_ERROR(LOG_CORE, "%s: connect event socket failed", __FUNCTION__);
773         goto err_event;
774     }
775 
776     if (WifiMsgRegisterEventListener() != RET_CODE_SUCCESS) {
777         HILOG_ERROR(LOG_CORE, "%s: WifiMsgRegisterEventListener failed", __FUNCTION__);
778         goto err_reg;
779     }
780     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
781     return RET_CODE_SUCCESS;
782 err_reg:
783     DisconnectEventSocket();
784 err_event:
785     DisconnectCtrlSocket();
786 err_ctrl:
787     DisconnectCmdSocket();
788 err_cmd:
789     pthread_mutex_destroy(&g_wifiHalInfo.mutex);
790 err_mutex:
791     DeinitEventcallbackMutex();
792     return RET_CODE_FAILURE;
793 }
794 
WifiDriverClientDeinit(void)795 void WifiDriverClientDeinit(void)
796 {
797     HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
798     WifiMsgUnregisterEventListener();
799 
800     if (g_wifiHalInfo.cmdSock == NULL) {
801         HILOG_ERROR(LOG_CORE, "%s: cmd socket not inited", __FUNCTION__);
802     } else {
803         DisconnectCmdSocket();
804     }
805 
806     if (g_wifiHalInfo.ctrlSock == NULL) {
807         HILOG_ERROR(LOG_CORE, "%s: ctrl socket not inited", __FUNCTION__);
808     } else {
809         DisconnectCtrlSocket();
810     }
811 
812     if (g_wifiHalInfo.eventSock == NULL) {
813         HILOG_ERROR(LOG_CORE, "%s: event socket not inited", __FUNCTION__);
814     } else {
815         DisconnectEventSocket();
816     }
817 
818     pthread_mutex_destroy(&g_wifiHalInfo.mutex);
819     DeinitEventcallbackMutex();
820     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
821 }
822 
ParserIsSupportCombo(struct nl_msg * msg,void * arg)823 static int32_t ParserIsSupportCombo(struct nl_msg *msg, void *arg)
824 {
825     struct nlattr *attr[NL80211_ATTR_MAX + 1];
826     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
827     struct nlattr *nlComb = NULL;
828     struct nlattr *attrComb[NUM_NL80211_IFACE_COMB];
829     uint8_t *isSupportCombo = (uint8_t *)arg;
830     int32_t ret, i;
831     static struct nla_policy ifaceCombPolicy[NUM_NL80211_IFACE_COMB];
832     ifaceCombPolicy[NL80211_IFACE_COMB_LIMITS].type = NLA_NESTED;
833     ifaceCombPolicy[NL80211_IFACE_COMB_MAXNUM].type = NLA_U32;
834     ifaceCombPolicy[NL80211_IFACE_COMB_NUM_CHANNELS].type = NLA_U32;
835 
836     // parse all enum nl80211_attrs type
837     ret = nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
838     if (ret != 0) {
839         HILOG_ERROR(LOG_CORE, "%s: nla_parse tb failed", __FUNCTION__);
840         return NL_SKIP;
841     }
842 
843     if (attr[NL80211_ATTR_INTERFACE_COMBINATIONS] != NULL) {
844         nla_for_each_nested(nlComb, attr[NL80211_ATTR_INTERFACE_COMBINATIONS], i) {
845             // parse all enum nl80211_if_combination_attrs type
846             ret = nla_parse_nested(attrComb, MAX_NL80211_IFACE_COMB, nlComb, ifaceCombPolicy);
847             if (ret != 0) {
848                 HILOG_ERROR(LOG_CORE, "%s: nla_parse_nested nlComb failed", __FUNCTION__);
849                 return NL_SKIP;
850             }
851             if (!attrComb[NL80211_IFACE_COMB_LIMITS] || !attrComb[NL80211_IFACE_COMB_MAXNUM] ||
852                 !attrComb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
853                 *isSupportCombo = 0;
854             } else {
855                 *isSupportCombo = 1;
856             }
857         }
858     }
859     HILOG_INFO(LOG_CORE, "%s: isSupportCombo is %hhu", __FUNCTION__, *isSupportCombo);
860     return NL_SKIP;
861 }
862 
ParserSupportComboInfo(struct nl_msg * msg,void * arg)863 static int32_t ParserSupportComboInfo(struct nl_msg *msg, void *arg)
864 {
865     (void)arg;
866     struct nlattr *attr[NL80211_ATTR_MAX + 1];
867     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
868     struct nlattr *nlComb = NULL, *nlLimit = NULL, *nlMode = NULL;
869     struct nlattr *attrComb[NUM_NL80211_IFACE_COMB];
870     struct nlattr *attrLimit[NUM_NL80211_IFACE_LIMIT];
871     int32_t ret, i, j, k, type;
872     static struct nla_policy ifaceCombPolicy[NUM_NL80211_IFACE_COMB];
873     ifaceCombPolicy[NL80211_IFACE_COMB_LIMITS].type = NLA_NESTED;
874     ifaceCombPolicy[NL80211_IFACE_COMB_MAXNUM].type = NLA_U32;
875     ifaceCombPolicy[NL80211_IFACE_COMB_NUM_CHANNELS].type = NLA_U32;
876 
877     static struct nla_policy ifaceLimitPolicy[NUM_NL80211_IFACE_LIMIT];
878     ifaceLimitPolicy[NL80211_IFACE_LIMIT_MAX].type = NLA_U32;
879     ifaceLimitPolicy[NL80211_IFACE_LIMIT_TYPES].type = NLA_NESTED;
880 
881     ret = nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
882     if (ret != 0) {
883         HILOG_ERROR(LOG_CORE, "%s: nla_parse tb failed", __FUNCTION__);
884         return NL_SKIP;
885     }
886 
887     if (attr[NL80211_ATTR_INTERFACE_COMBINATIONS] != NULL) {
888         // get each ieee80211_iface_combination
889         nla_for_each_nested(nlComb, attr[NL80211_ATTR_INTERFACE_COMBINATIONS], i) {
890             ret = nla_parse_nested(attrComb, MAX_NL80211_IFACE_COMB, nlComb, ifaceCombPolicy);
891             if (ret != 0) {
892                 HILOG_ERROR(LOG_CORE, "%s: nla_parse_nested nlComb failed", __FUNCTION__);
893                 return NL_SKIP;
894             }
895             if (!attrComb[NL80211_IFACE_COMB_LIMITS] || !attrComb[NL80211_IFACE_COMB_MAXNUM] ||
896                 !attrComb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
897                 return RET_CODE_NOT_SUPPORT;
898             }
899             // parse each ieee80211_iface_limit
900             nla_for_each_nested(nlLimit, attrComb[NL80211_IFACE_COMB_LIMITS], j) {
901                 ret = nla_parse_nested(attrLimit, MAX_NL80211_IFACE_LIMIT, nlLimit, ifaceLimitPolicy);
902                 if (ret || !attrLimit[NL80211_IFACE_LIMIT_TYPES]) {
903                     HILOG_ERROR(LOG_CORE, "%s: iface limit types not supported", __FUNCTION__);
904                     return RET_CODE_NOT_SUPPORT; /* broken combination */
905                 }
906                 // parse each ieee80211_iface_limit's types
907                 nla_for_each_nested(nlMode, attrLimit[NL80211_IFACE_LIMIT_TYPES], k) {
908                     type = nla_type(nlMode);
909                     if (type > WIFI_IFTYPE_UNSPECIFIED && type < WIFI_IFTYPE_MAX) {
910                         HILOG_INFO(LOG_CORE, "%s: mode: %d", __FUNCTION__, type);
911                     }
912                 }
913                 HILOG_INFO(LOG_CORE, "%s: has parse a attrLimit", __FUNCTION__);
914             }
915         }
916     }
917     return NL_SKIP;
918 }
919 
GetWiphyBands(struct genlmsghdr * hdr)920 static struct nlattr *GetWiphyBands(struct genlmsghdr *hdr)
921 {
922     struct nlattr *attrMsg[NL80211_ATTR_MAX + 1];
923     void *data = genlmsg_attrdata(hdr, 0);
924     int32_t len = genlmsg_attrlen(hdr, 0);
925     nla_parse(attrMsg, NL80211_ATTR_MAX, data, len, NULL);
926     if (!attrMsg[NL80211_ATTR_WIPHY_BANDS]) {
927         HILOG_ERROR(LOG_CORE, "%s: no wiphy bands", __FUNCTION__);
928     }
929     return attrMsg[NL80211_ATTR_WIPHY_BANDS];
930 }
931 
GetCenterFreq(struct nlattr * bands,struct FreqInfoResult * result)932 static void GetCenterFreq(struct nlattr *bands, struct FreqInfoResult *result)
933 {
934     struct nlattr *attrFreq[NL80211_FREQUENCY_ATTR_MAX + 1];
935     struct nlattr *nlFreq = NULL;
936     void *data = NULL;
937     int32_t len;
938     int32_t i;
939     uint32_t freq;
940     static struct nla_policy freqPolicy[NL80211_FREQUENCY_ATTR_MAX + 1];
941     freqPolicy[NL80211_FREQUENCY_ATTR_FREQ].type = NLA_U32;
942     freqPolicy[NL80211_FREQUENCY_ATTR_MAX_TX_POWER].type = NLA_U32;
943 
944     // get each ieee80211_channel
945     nla_for_each_nested(nlFreq, bands, i) {
946         data = nla_data(nlFreq);
947         len = nla_len(nlFreq);
948         nla_parse(attrFreq, NL80211_FREQUENCY_ATTR_MAX, data, len, freqPolicy);
949         // get center freq
950         if (attrFreq[NL80211_FREQUENCY_ATTR_FREQ] == NULL) {
951             continue;
952         }
953         freq = nla_get_u32(attrFreq[NL80211_FREQUENCY_ATTR_FREQ]);
954         switch (result->band) {
955             case NL80211_BAND_2GHZ:
956                 if (attrFreq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) {
957                     if (freq > LOW_LITMIT_FREQ_2_4G && freq < HIGH_LIMIT_FREQ_2_4G) {
958                         result->freqs[result->nums] = freq;
959                         result->txPower[result->nums] = nla_get_u32(attrFreq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]);
960                         result->nums++;
961                     }
962                 }
963                 break;
964             case NL80211_BAND_5GHZ:
965                 if (freq > LOW_LIMIT_FREQ_5G && freq < HIGH_LIMIT_FREQ_5G) {
966                     result->freqs[result->nums] = freq;
967                     result->nums++;
968                 }
969                 break;
970             default:
971                 break;
972         }
973     }
974 }
975 
ParserValidFreq(struct nl_msg * msg,void * arg)976 static int32_t ParserValidFreq(struct nl_msg *msg, void *arg)
977 {
978     struct FreqInfoResult *result = (struct FreqInfoResult *)arg;
979     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
980     struct nlattr *attrWiphyBands = NULL;
981     struct nlattr *attrBand[NL80211_BAND_ATTR_MAX + 1];
982     struct nlattr *nlBand = NULL;
983     int32_t i;
984     void *data = NULL;
985     int32_t len;
986 
987     attrWiphyBands = GetWiphyBands(hdr);
988     if (attrWiphyBands == NULL) {
989         return NL_SKIP;
990     }
991 
992     // get each ieee80211_supported_band
993     nla_for_each_nested(nlBand, attrWiphyBands, i) {
994         data = nla_data(nlBand);
995         len = nla_len(nlBand);
996         nla_parse(attrBand, NL80211_BAND_ATTR_MAX, data, len, NULL);
997         if (attrBand[NL80211_BAND_ATTR_FREQS] == NULL) {
998             continue;
999         }
1000         GetCenterFreq(attrBand[NL80211_BAND_ATTR_FREQS], result);
1001     }
1002     return NL_SKIP;
1003 }
1004 
IsWifiIface(const char * name)1005 static bool IsWifiIface(const char *name)
1006 {
1007     if (strncmp(name, "wlan", WLAN_IFACE_LENGTH) != 0 && strncmp(name, "p2p", P2P_IFACE_LENGTH) != 0 &&
1008         strncmp(name, "chba", CHBA_IFACE_LENGTH) != 0) {
1009         /* not a wifi interface; ignore it */
1010         return false;
1011     } else {
1012         return true;
1013     }
1014 }
1015 
GetAllIfaceInfo(struct NetworkInfoResult * infoResult)1016 static int32_t GetAllIfaceInfo(struct NetworkInfoResult *infoResult)
1017 {
1018     struct dirent **namelist = NULL;
1019     char *ifName = NULL;
1020     int32_t num;
1021     int32_t i;
1022     int32_t ret = RET_CODE_SUCCESS;
1023 
1024     num = scandir(NET_DEVICE_INFO_PATH, &namelist, NULL, alphasort);
1025     if (num < 0) {
1026         HILOG_ERROR(LOG_CORE, "%s: scandir failed, errno = %d, %s", __FUNCTION__, errno, strerror(errno));
1027         return RET_CODE_FAILURE;
1028     }
1029     infoResult->nums = 0;
1030     for (i = 0; i < num; i++) {
1031         if (infoResult->nums < MAX_IFACE_NUM && IsWifiIface(namelist[i]->d_name)) {
1032             ifName = infoResult->infos[infoResult->nums].name;
1033             if (strncpy_s(ifName, IFNAMSIZ, namelist[i]->d_name, strlen(namelist[i]->d_name)) != EOK) {
1034                 HILOG_ERROR(LOG_CORE, "%s: strncpy_s infoResult->infos failed", __FUNCTION__);
1035                 ret = RET_CODE_FAILURE;
1036             }
1037             HILOG_DEBUG(LOG_CORE, "%{public}s: ifName = %{public}s", __FUNCTION__, ifName);
1038             infoResult->nums++;
1039         }
1040         free(namelist[i]);
1041     }
1042     free(namelist);
1043     return ret;
1044 }
1045 
NetLinkGetChipProp(void)1046 static bool NetLinkGetChipProp(void)
1047 {
1048     char preValue[SUBCHIP_WIFI_PROP_LEN] = { 0 };
1049     int errCode = GetParameter(SUBCHIP_WIFI_PROP, 0, preValue, SUBCHIP_WIFI_PROP_LEN);
1050     if (errCode > 0) {
1051         if (strncmp(preValue, SUPPORT_COEXCHIP, SUPPORT_COEXCHIP_LEN) == 0) {
1052             return true;
1053         }
1054     }
1055 
1056     return false;
1057 }
1058 
GetUsableNetworkInfo(struct NetworkInfoResult * result)1059 int32_t GetUsableNetworkInfo(struct NetworkInfoResult *result)
1060 {
1061     int32_t ret;
1062     uint32_t i;
1063 
1064     ret = GetAllIfaceInfo(result);
1065     if (ret != RET_CODE_SUCCESS) {
1066         HILOG_ERROR(LOG_CORE, "%s: GetAllIfaceInfo failed", __FUNCTION__);
1067         return ret;
1068     }
1069 
1070     HILOG_INFO(LOG_CORE, "%{public}s: wifi iface num %{public}d", __FUNCTION__, result->nums);
1071     for (i = 0; i < result->nums; ++i) {
1072         ret = memset_s(result->infos[i].supportMode, sizeof(result->infos[i].supportMode), 0,
1073             sizeof(result->infos[i].supportMode));
1074         if (ret != EOK) {
1075             HILOG_ERROR(LOG_CORE, "%s: memset_s esult->infos failed", __FUNCTION__);
1076             return RET_CODE_FAILURE;
1077         }
1078         if (strncmp(result->infos[i].name, STR_WLAN0, strlen(STR_WLAN0)) == 0) {
1079             result->infos[i].supportMode[WIFI_IFTYPE_STATION] = 1;
1080             result->infos[i].supportMode[WIFI_IFTYPE_AP] = NetLinkGetChipProp() ? 0 : 1;
1081         } else if (strncmp(result->infos[i].name, STR_WLAN1, strlen(STR_WLAN1)) == 0) {
1082             result->infos[i].supportMode[WIFI_IFTYPE_STATION] = 1;
1083             result->infos[i].supportMode[WIFI_IFTYPE_AP] = NetLinkGetChipProp() ? 1 : 0;
1084         } else if (strncmp(result->infos[i].name, STR_P2P0, strlen(STR_P2P0)) == 0) {
1085             result->infos[i].supportMode[WIFI_IFTYPE_P2P_DEVICE] = 1;
1086         } else if (strncmp(result->infos[i].name, STR_P2P0_X, strlen(STR_P2P0_X)) == 0) {
1087             result->infos[i].supportMode[WIFI_IFTYPE_P2P_CLIENT] = 1;
1088             result->infos[i].supportMode[WIFI_IFTYPE_P2P_GO] = 1;
1089         } else if (strncmp(result->infos[i].name, STR_CHBA, strlen(STR_CHBA)) == 0) {
1090             result->infos[i].supportMode[WIFI_IFTYPE_CHBA] = 1;
1091         }
1092     }
1093     return RET_CODE_SUCCESS;
1094 }
1095 
IsSupportCombo(uint8_t * isSupportCombo)1096 int32_t IsSupportCombo(uint8_t *isSupportCombo)
1097 {
1098     uint32_t ifaceId;
1099     struct nl_msg *msg = NULL;
1100     struct NetworkInfoResult networkInfo;
1101     int32_t ret;
1102 
1103     ret = GetUsableNetworkInfo(&networkInfo);
1104     if (ret != RET_CODE_SUCCESS) {
1105         HILOG_ERROR(LOG_CORE, "%s: get network info failed", __FUNCTION__);
1106         return ret;
1107     }
1108 
1109     ifaceId = if_nametoindex(networkInfo.infos[0].name);
1110     if (ifaceId == 0) {
1111         HILOG_ERROR(LOG_CORE, "%s: get iface id(%u) failed", __FUNCTION__, ifaceId);
1112         return RET_CODE_FAILURE;
1113     }
1114 
1115     msg = nlmsg_alloc();
1116     if (msg == NULL) {
1117         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1118         return RET_CODE_NOMEM;
1119     }
1120 
1121     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1122     nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1123     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1124     ret = NetlinkSendCmdSync(msg, ParserIsSupportCombo, isSupportCombo);
1125     if (ret != RET_CODE_SUCCESS) {
1126         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1127     }
1128     nlmsg_free(msg);
1129     return ret;
1130 }
1131 
GetComboInfo(uint64_t * comboInfo,uint32_t size)1132 int32_t GetComboInfo(uint64_t *comboInfo, uint32_t size)
1133 {
1134     (void)size;
1135     uint32_t ifaceId;
1136     struct nl_msg *msg = NULL;
1137     struct NetworkInfoResult networkInfo;
1138     int32_t ret;
1139 
1140     ret = GetUsableNetworkInfo(&networkInfo);
1141     if (ret != RET_CODE_SUCCESS) {
1142         HILOG_ERROR(LOG_CORE, "%s: get network info failed", __FUNCTION__);
1143         return ret;
1144     }
1145 
1146     ifaceId = if_nametoindex(networkInfo.infos[0].name);
1147     if (ifaceId == 0) {
1148         HILOG_ERROR(LOG_CORE, "%s: get iface id(%u) failed", __FUNCTION__, ifaceId);
1149         return RET_CODE_FAILURE;
1150     }
1151 
1152     msg = nlmsg_alloc();
1153     if (msg == NULL) {
1154         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1155         return RET_CODE_NOMEM;
1156     }
1157     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1158     nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1159     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1160     ret = NetlinkSendCmdSync(msg, ParserSupportComboInfo, comboInfo);
1161     if (ret != RET_CODE_SUCCESS) {
1162         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1163     }
1164     nlmsg_free(msg);
1165     return ret;
1166 }
1167 
SetMacAddr(const char * ifName,unsigned char * mac,uint8_t len)1168 int32_t SetMacAddr(const char *ifName, unsigned char *mac, uint8_t len)
1169 {
1170     int32_t fd;
1171     int32_t ret;
1172     struct ifreq req;
1173 
1174     if (memset_s(&req, sizeof(req), 0, sizeof(req)) != EOK) {
1175         HILOG_ERROR(LOG_CORE, "%s: memset_s req failed", __FUNCTION__);
1176         return RET_CODE_FAILURE;
1177     }
1178     fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1179     if (fd < 0) {
1180         HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1181         return RET_CODE_FAILURE;
1182     }
1183     if (strncpy_s(req.ifr_name, IFNAMSIZ, ifName, strlen(ifName)) != EOK) {
1184         HILOG_ERROR(LOG_CORE, "%s: strncpy_s fail", __FUNCTION__);
1185         close(fd);
1186         return RET_CODE_FAILURE;
1187     }
1188     req.ifr_addr.sa_family = ARPHRD_ETHER;
1189     if (memcpy_s(req.ifr_hwaddr.sa_data, len, mac, len) != EOK) {
1190         HILOG_ERROR(LOG_CORE, "%s: memcpy_s req.ifr_hwaddr.sa_data failed", __FUNCTION__);
1191         close(fd);
1192         return RET_CODE_FAILURE;
1193     }
1194     ret = ioctl(fd, SIOCSIFHWADDR, &req);
1195     if (ret != RET_CODE_SUCCESS) {
1196         HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1197         if (errno == EPERM) {
1198             ret = RET_CODE_NOT_SUPPORT;
1199         } else if (errno == EBUSY) {
1200             ret = RET_CODE_DEVICE_BUSY;
1201         } else {
1202             ret = RET_CODE_FAILURE;
1203         }
1204     }
1205     close(fd);
1206     return ret;
1207 }
1208 
ParserChipId(struct nl_msg * msg,void * arg)1209 static int32_t ParserChipId(struct nl_msg *msg, void *arg)
1210 {
1211     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
1212     struct nlattr *attr[NL80211_ATTR_MAX + 1];
1213     uint8_t *chipId = (uint8_t *)arg;
1214     uint8_t *getChipId = NULL;
1215     int32_t ret;
1216 
1217     ret = nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
1218     if (ret != 0) {
1219         HILOG_ERROR(LOG_CORE, "%s: nla_parse failed", __FUNCTION__);
1220         return NL_SKIP;
1221     }
1222 
1223     if (attr[NL80211_ATTR_MAX]) {
1224         getChipId = nla_data(attr[NL80211_ATTR_MAX]);
1225         *chipId = *getChipId;
1226     }
1227 
1228     return NL_SKIP;
1229 }
1230 
GetDevMacAddr(const char * ifName,int32_t type,uint8_t * mac,uint8_t len)1231 int32_t GetDevMacAddr(const char *ifName, int32_t type, uint8_t *mac, uint8_t len)
1232 {
1233     (void)type;
1234     int32_t fd;
1235     int32_t ret;
1236     struct ifreq req;
1237 
1238     if (memset_s(&req, sizeof(req), 0, sizeof(req)) != EOK) {
1239         HILOG_ERROR(LOG_CORE, "%s: memset_s req failed", __FUNCTION__);
1240         return RET_CODE_FAILURE;
1241     }
1242     fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1243     if (fd < 0) {
1244         HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1245         return RET_CODE_FAILURE;
1246     }
1247 
1248     if (strncpy_s(req.ifr_name, IFNAMSIZ, ifName, strlen(ifName)) != EOK) {
1249         HILOG_ERROR(LOG_CORE, "%s: strncpy_s failed", __FUNCTION__);
1250         close(fd);
1251         return RET_CODE_FAILURE;
1252     }
1253     struct ethtool_perm_addr *epaddr =
1254         (struct ethtool_perm_addr *)malloc(sizeof(struct ethtool_perm_addr) + ETH_ADDR_LEN);
1255     if (epaddr == NULL) {
1256         HILOG_ERROR(LOG_CORE, "%s: malloc failed", __FUNCTION__);
1257         close(fd);
1258         return RET_CODE_FAILURE;
1259     }
1260     epaddr->cmd = ETHTOOL_GPERMADDR;
1261     epaddr->size = ETH_ADDR_LEN;
1262     req.ifr_data = (char*)epaddr;
1263     ret = ioctl(fd, SIOCETHTOOL, &req);
1264     if (ret != 0) {
1265         HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1266         free(epaddr);
1267         close(fd);
1268         return RET_CODE_FAILURE;
1269     }
1270 
1271     if (memcpy_s(mac, len, (unsigned char *)epaddr->data, ETH_ADDR_LEN) != EOK) {
1272         HILOG_ERROR(LOG_CORE, "%s: memcpy_s mac failed", __FUNCTION__);
1273         ret = RET_CODE_FAILURE;
1274     }
1275     free(epaddr);
1276     close(fd);
1277     return ret;
1278 }
1279 
GetValidFreqByBand(const char * ifName,int32_t band,struct FreqInfoResult * result,uint32_t size)1280 int32_t GetValidFreqByBand(const char *ifName, int32_t band, struct FreqInfoResult *result, uint32_t size)
1281 {
1282     uint32_t ifaceId;
1283     struct nl_msg *msg = NULL;
1284     int32_t ret;
1285 
1286     if (result == NULL || result->freqs == NULL || result->txPower == NULL) {
1287         HILOG_ERROR(LOG_CORE, "%s:  Invalid input parameter", __FUNCTION__);
1288         return RET_CODE_INVALID_PARAM;
1289     }
1290 
1291     if (band >= IEEE80211_NUM_BANDS) {
1292         HILOG_ERROR(LOG_CORE, "%s:  Invalid input parameter, band = %d", __FUNCTION__, band);
1293         return RET_CODE_INVALID_PARAM;
1294     }
1295 
1296     ifaceId = if_nametoindex(ifName);
1297     if (ifaceId == 0) {
1298         HILOG_ERROR(LOG_CORE, "%s: get iface id(%u) failed", __FUNCTION__, ifaceId);
1299         return RET_CODE_INVALID_PARAM;
1300     }
1301 
1302     msg = nlmsg_alloc();
1303     if (msg == NULL) {
1304         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1305         return RET_CODE_NOMEM;
1306     }
1307 
1308     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1309     nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1310     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1311     ret = memset_s(result->freqs, size * sizeof(uint32_t), 0, size * sizeof(uint32_t));
1312     if (ret != EOK) {
1313         HILOG_ERROR(LOG_CORE, "%s: memset_s result->freqs  failed", __FUNCTION__);
1314         nlmsg_free(msg);
1315         return RET_CODE_FAILURE;
1316     }
1317     result->nums = 0;
1318     result->band = band;
1319     ret = NetlinkSendCmdSync(msg, ParserValidFreq, result);
1320     if (ret != RET_CODE_SUCCESS) {
1321         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1322     }
1323     nlmsg_free(msg);
1324     return ret;
1325 }
1326 
SetTxPower(const char * ifName,int32_t power)1327 int32_t SetTxPower(const char *ifName, int32_t power)
1328 {
1329     uint32_t ifaceId;
1330     struct nl_msg *msg = NULL;
1331     int32_t ret;
1332 
1333     ifaceId = if_nametoindex(ifName);
1334     if (ifaceId == 0) {
1335         HILOG_ERROR(LOG_CORE, "%s: get iface id(%d) failed", __FUNCTION__, ifaceId);
1336         return RET_CODE_INVALID_PARAM;
1337     }
1338 
1339     msg = nlmsg_alloc();
1340     if (msg == NULL) {
1341         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1342         return RET_CODE_NOMEM;
1343     }
1344 
1345     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_SET_WIPHY, 0);
1346     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1347     nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_SETTING, NL80211_TX_POWER_LIMITED);
1348     nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, 100 * power);
1349     ret = NetlinkSendCmdSync(msg, NULL, NULL);
1350     if (ret != RET_CODE_SUCCESS) {
1351         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1352     } else {
1353         HILOG_INFO(LOG_CORE, "%s: send end success", __FUNCTION__);
1354     }
1355     nlmsg_free(msg);
1356     return ret;
1357 }
1358 
GetAssociatedStas(const char * ifName,struct AssocStaInfoResult * result)1359 int32_t GetAssociatedStas(const char *ifName, struct AssocStaInfoResult *result)
1360 {
1361     (void)ifName;
1362     if (memset_s(result, sizeof(struct AssocStaInfoResult), 0, sizeof(struct AssocStaInfoResult)) != EOK) {
1363         HILOG_ERROR(LOG_CORE, "%s: memset_s result failed", __FUNCTION__);
1364         return RET_CODE_FAILURE;
1365     }
1366     return RET_CODE_SUCCESS;
1367 }
1368 
WifiSetCountryCode(const char * ifName,const char * code,uint32_t len)1369 int32_t WifiSetCountryCode(const char *ifName, const char *code, uint32_t len)
1370 {
1371     uint32_t ifaceId = if_nametoindex(ifName);
1372     struct nl_msg *msg = NULL;
1373     struct nlattr *data = NULL;
1374     int32_t ret;
1375 
1376     if (ifaceId == 0) {
1377         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1378         return RET_CODE_FAILURE;
1379     }
1380 
1381     msg = nlmsg_alloc();
1382     if (msg == NULL) {
1383         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1384         return RET_CODE_NOMEM;
1385     }
1386 
1387     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_VENDOR, 0);
1388     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1389     nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, VENDOR_ID);
1390     nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, WIFI_SUBCMD_SET_COUNTRY_CODE);
1391     data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1392     if (data == NULL) {
1393         HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1394         nlmsg_free(msg);
1395         return RET_CODE_FAILURE;
1396     }
1397     if (nla_put(msg, WIFI_ATTRIBUTE_COUNTRY, len, code) != RET_CODE_SUCCESS) {
1398         HILOG_ERROR(LOG_CORE, "%s: nla_put code failed", __FUNCTION__);
1399         nlmsg_free(msg);
1400         return RET_CODE_FAILURE;
1401     }
1402     nla_nest_end(msg, data);
1403 
1404     ret = NetlinkSendCmdSync(msg, NULL, NULL);
1405     if (ret != RET_CODE_SUCCESS) {
1406         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1407     }
1408     nlmsg_free(msg);
1409     return ret;
1410 }
1411 
SetScanMacAddr(const char * ifName,uint8_t * scanMac,uint8_t len)1412 int32_t SetScanMacAddr(const char *ifName, uint8_t *scanMac, uint8_t len)
1413 {
1414     int32_t ret;
1415     uint32_t ifaceId = if_nametoindex(ifName);
1416     struct nl_msg *msg = nlmsg_alloc();
1417     struct nlattr *data = NULL;
1418 
1419     if (msg == NULL) {
1420         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1421         return RET_CODE_NOMEM;
1422     }
1423     if (ifaceId == 0) {
1424         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1425         nlmsg_free(msg);
1426         return RET_CODE_FAILURE;
1427     }
1428     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_VENDOR, 0);
1429     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1430     nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, VENDOR_ID);
1431     nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, WIFI_SUBCMD_SET_RANDOM_MAC_OUI);
1432     data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1433     if (data == NULL) {
1434         HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1435         nlmsg_free(msg);
1436         return RET_CODE_FAILURE;
1437     }
1438     if (nla_put(msg, WIFI_ATTRIBUTE_RANDOM_MAC_OUI, len, scanMac) !=RET_CODE_SUCCESS) {
1439         HILOG_ERROR(LOG_CORE, "%s: nla_put scanMac failed", __FUNCTION__);
1440         nlmsg_free(msg);
1441         return RET_CODE_FAILURE;
1442     }
1443     nla_nest_end(msg, data);
1444     ret = NetlinkSendCmdSync(msg, NULL, NULL);
1445     if (ret != RET_CODE_SUCCESS) {
1446         HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1447     }
1448     nlmsg_free(msg);
1449     return ret;
1450 }
1451 
AcquireChipId(const char * ifName,uint8_t * chipId)1452 int32_t AcquireChipId(const char *ifName, uint8_t *chipId)
1453 {
1454     struct nl_msg *msg = NULL;
1455     uint32_t ifaceId;
1456     int32_t ret;
1457 
1458     if (ifName == NULL || chipId == NULL) {
1459         HILOG_ERROR(LOG_CORE, "%s params is NULL", __FUNCTION__);
1460         return RET_CODE_INVALID_PARAM;
1461     }
1462 
1463     ifaceId = if_nametoindex(ifName);
1464     if (ifaceId == 0) {
1465         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1466         return RET_CODE_FAILURE;
1467     }
1468 
1469     msg = nlmsg_alloc();
1470     if (msg == NULL) {
1471         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1472         return RET_CODE_NOMEM;
1473     }
1474 
1475     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1476     nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1477     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1478 
1479     ret = NetlinkSendCmdSync(msg, ParserChipId, chipId);
1480     if (ret != RET_CODE_SUCCESS) {
1481         HILOG_ERROR(LOG_CORE, "%s: NetlinkSendCmdSync failed.", __FUNCTION__);
1482     }
1483     nlmsg_free(msg);
1484     return ret;
1485 }
1486 
GetIfNamesByChipId(const uint8_t chipId,char ** ifNames,uint32_t * num)1487 int32_t GetIfNamesByChipId(const uint8_t chipId, char **ifNames, uint32_t *num)
1488 {
1489     if (ifNames == NULL || num == NULL) {
1490         HILOG_ERROR(LOG_CORE, "%s params is NULL", __FUNCTION__);
1491         return RET_CODE_INVALID_PARAM;
1492     }
1493 
1494     if (chipId >= MAX_WLAN_DEVICE) {
1495         HILOG_ERROR(LOG_CORE, "%s: chipId = %u", __FUNCTION__, chipId);
1496         return RET_CODE_INVALID_PARAM;
1497     }
1498     *num = 1;
1499     *ifNames = (char *)calloc(*num, IFNAMSIZ);
1500     if (*ifNames == NULL) {
1501         HILOG_ERROR(LOG_CORE, "%s: calloc failed", __FUNCTION__);
1502         return RET_CODE_FAILURE;
1503     }
1504     if (memcpy_s(*ifNames, IFNAMSIZ, "wlan0", IFNAMSIZ) != EOK) {
1505         HILOG_ERROR(LOG_CORE, "%s: memcpy failed", __FUNCTION__);
1506         free(*ifNames);
1507         *ifNames = NULL;
1508         return RET_CODE_FAILURE;
1509     }
1510     return RET_CODE_SUCCESS;
1511 }
1512 
SetResetDriver(const uint8_t chipId,const char * ifName)1513 int32_t SetResetDriver(const uint8_t chipId, const char *ifName)
1514 {
1515     (void)chipId;
1516     (void)ifName;
1517     return RET_CODE_SUCCESS;
1518 }
1519 
NetDeviceInfoHandler(struct nl_msg * msg,void * arg)1520 static int32_t NetDeviceInfoHandler(struct nl_msg *msg, void *arg)
1521 {
1522     struct NetDeviceInfo *info = (struct NetDeviceInfo *)arg;
1523     struct nlattr *attr[NL80211_ATTR_MAX + 1];
1524     struct genlmsghdr *hdr = NULL;
1525     void *data = NULL;
1526     int32_t len;
1527 
1528     hdr = nlmsg_data(nlmsg_hdr(msg));
1529     if (hdr == NULL) {
1530         HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
1531         return NL_SKIP;
1532     }
1533     data = genlmsg_attrdata(hdr, 0);
1534     len = genlmsg_attrlen(hdr, 0);
1535     nla_parse(attr, NL80211_ATTR_MAX, data, len, NULL);
1536     if (attr[NL80211_ATTR_IFTYPE]) {
1537         info->iftype = nla_get_u32(attr[NL80211_ATTR_IFTYPE]);
1538         HILOG_ERROR(LOG_CORE, "%s: %s iftype is %hhu", __FUNCTION__, info->ifName, info->iftype);
1539     }
1540     if (attr[NL80211_ATTR_MAC]) {
1541         if (memcpy_s(info->mac, ETH_ADDR_LEN, nla_data(attr[NL80211_ATTR_MAC]), ETH_ADDR_LEN) != EOK) {
1542             HILOG_ERROR(LOG_CORE, "%s: memcpy_s mac address fail", __FUNCTION__);
1543         }
1544     }
1545 
1546     return NL_SKIP;
1547 }
1548 
GetIftypeAndMac(struct NetDeviceInfo * info)1549 static int32_t GetIftypeAndMac(struct NetDeviceInfo *info)
1550 {
1551     struct nl_msg *msg = nlmsg_alloc();
1552     int32_t ret;
1553 
1554     if (msg == NULL) {
1555         HILOG_ERROR(LOG_CORE, "%s: nlmsg_alloc failed.", __FUNCTION__);
1556         return RET_CODE_FAILURE;
1557     }
1558 
1559     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_INTERFACE, 0);
1560     nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(info->ifName));
1561 
1562     ret = NetlinkSendCmdSync(msg, NetDeviceInfoHandler, info);
1563     if (ret != RET_CODE_SUCCESS) {
1564         HILOG_ERROR(LOG_CORE, "%s: NetlinkSendCmdSync failed.", __FUNCTION__);
1565     }
1566     nlmsg_free(msg);
1567     return ret;
1568 }
1569 
GetNetDeviceInfo(struct NetDeviceInfoResult * netDeviceInfoResult)1570 int32_t GetNetDeviceInfo(struct NetDeviceInfoResult *netDeviceInfoResult)
1571 {
1572     struct NetworkInfoResult networkInfo;
1573     uint32_t i;
1574     int32_t ret;
1575 
1576     ret = GetUsableNetworkInfo(&networkInfo);
1577     if (ret != RET_CODE_SUCCESS) {
1578         HILOG_ERROR(LOG_CORE, "%s: get network info failed", __FUNCTION__);
1579         return ret;
1580     }
1581 
1582     for (i = 0; i < networkInfo.nums && i < MAX_NETDEVICE_COUNT; i++) {
1583         if (memset_s(&netDeviceInfoResult->deviceInfos[i], sizeof(struct NetDeviceInfo), 0,
1584             sizeof(struct NetDeviceInfo)) != EOK) {
1585             HILOG_ERROR(LOG_CORE, "%s: memset_s fail", __FUNCTION__);
1586             return RET_CODE_FAILURE;
1587         }
1588         netDeviceInfoResult->deviceInfos[i].index = i + 1;
1589         if (strncpy_s(netDeviceInfoResult->deviceInfos[i].ifName, IFNAMSIZ,
1590             networkInfo.infos[i].name, IFNAMSIZ) != EOK) {
1591             HILOG_ERROR(LOG_CORE, "%s: strncpy_s fail", __FUNCTION__);
1592             return RET_CODE_FAILURE;
1593         }
1594         ret = GetIftypeAndMac(&netDeviceInfoResult->deviceInfos[i]);
1595         if (ret != RET_CODE_SUCCESS) {
1596             HILOG_ERROR(LOG_CORE, "%s: get iftype and mac failed", __FUNCTION__);
1597             return ret;
1598         }
1599     }
1600 
1601     return RET_CODE_SUCCESS;
1602 }
1603 
CmdScanPutSsidsMsg(struct nl_msg * msg,const WifiScan * scan,const WiphyInfo * wiphyInfo)1604 static int32_t CmdScanPutSsidsMsg(struct nl_msg *msg, const WifiScan *scan, const WiphyInfo *wiphyInfo)
1605 {
1606     struct nlattr *nest = NULL;
1607     int32_t i;
1608 
1609     if (scan->ssids) {
1610         nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
1611         if (nest == NULL) {
1612             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1613             return RET_CODE_FAILURE;
1614         }
1615         int attrtype = 1;
1616         /*add an empty ssid for a wildcard scan*/
1617         if (nla_put(msg, attrtype, 0, NULL) != RET_CODE_SUCCESS) {
1618             HILOG_ERROR(LOG_CORE, "%s: nla_put NULL failed", __FUNCTION__);
1619             return RET_CODE_FAILURE;
1620         }
1621         for (i = 0; i < scan->numSsids; i++) {
1622             if (attrtype >= wiphyInfo->scanCapabilities.maxNumScanSsids) {
1623                 HILOG_INFO(LOG_CORE, "%s: Skip the excess hidden ssids for scan,current:%{public}d,max:%{public}d",
1624                     __FUNCTION__, attrtype, wiphyInfo->scanCapabilities.maxNumScanSsids);
1625                 break;
1626             }
1627             if (strlen((const char *)scan->ssids[i].ssid) == 0 || scan->ssids[i].ssidLen == 0) {
1628                 HILOG_ERROR(LOG_CORE, "%s: nla_put ssid is empty", __FUNCTION__);
1629                 continue;
1630             }
1631             attrtype++;
1632             if (nla_put(msg, attrtype, scan->ssids[i].ssidLen, scan->ssids[i].ssid) != RET_CODE_SUCCESS) {
1633                 HILOG_ERROR(LOG_CORE, "%s: nla_put ssid failed", __FUNCTION__);
1634                 return RET_CODE_FAILURE;
1635             }
1636         }
1637         nla_nest_end(msg, nest);
1638         HILOG_INFO(LOG_CORE, "%{public}s numSsids:%{public}d", __FUNCTION__, attrtype);
1639     }
1640     return RET_CODE_SUCCESS;
1641 }
1642 
CmdScanPutFreqsMsg(struct nl_msg * msg,const WifiScan * scan)1643 static int32_t CmdScanPutFreqsMsg(struct nl_msg *msg, const WifiScan *scan)
1644 {
1645     struct nlattr *nest = NULL;
1646     int32_t i;
1647 
1648     if (scan->freqs) {
1649         nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
1650         if (nest == NULL) {
1651             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1652             return RET_CODE_FAILURE;
1653         }
1654         for (i = 0; i < scan->numFreqs; i++) {
1655             nla_put_u32(msg, i + 1, scan->freqs[i]);
1656         }
1657         nla_nest_end(msg, nest);
1658     }
1659     return RET_CODE_SUCCESS;
1660 }
1661 
CmdScanPutMsg(const char * ifName,struct nl_msg * msg,const WifiScan * scan)1662 static int32_t CmdScanPutMsg(const char *ifName, struct nl_msg *msg, const WifiScan *scan)
1663 {
1664     uint32_t wiphyIndex;
1665     WiphyInfo wiphyInfo;
1666 
1667     if (memset_s(&wiphyInfo, sizeof(wiphyInfo), 0, sizeof(wiphyInfo)) != EOK) {
1668         HILOG_ERROR(LOG_CORE, "%s: memset_s wiphyInfo failed", __FUNCTION__);
1669         return RET_CODE_FAILURE;
1670     }
1671     if (GetWiphyIndex(ifName, &wiphyIndex) != RET_CODE_SUCCESS) {
1672         HILOG_ERROR(LOG_CORE, "%s: GetWiphyIndex failed", __FUNCTION__);
1673         return RET_CODE_FAILURE;
1674     }
1675     if (GetWiphyInfo(wiphyIndex, &wiphyInfo) != RET_CODE_SUCCESS) {
1676         HILOG_ERROR(LOG_CORE, "%s: GetWiphyInfo failed", __FUNCTION__);
1677         return RET_CODE_FAILURE;
1678     }
1679 
1680     if (CmdScanPutSsidsMsg(msg, scan, &wiphyInfo) != RET_CODE_SUCCESS) {
1681         return RET_CODE_FAILURE;
1682     }
1683 
1684     if (CmdScanPutFreqsMsg(msg, scan) != RET_CODE_SUCCESS) {
1685         return RET_CODE_FAILURE;
1686     }
1687 
1688     if (scan->extraIes) {
1689         if (nla_put(msg, NL80211_ATTR_IE, scan->extraIesLen, scan->extraIes) != RET_CODE_SUCCESS) {
1690             HILOG_ERROR(LOG_CORE, "%s: nla_put extraIes failed", __FUNCTION__);
1691             return RET_CODE_FAILURE;
1692         }
1693     }
1694 
1695     if (scan->bssid) {
1696         if (nla_put(msg, NL80211_ATTR_MAC, ETH_ADDR_LEN, scan->bssid) != RET_CODE_SUCCESS) {
1697             HILOG_ERROR(LOG_CORE, "%s: nla_put bssid failed", __FUNCTION__);
1698             return RET_CODE_FAILURE;
1699         }
1700     }
1701 
1702     return RET_CODE_SUCCESS;
1703 }
1704 
WifiCmdScan(const char * ifName,WifiScan * scan)1705 int32_t WifiCmdScan(const char *ifName, WifiScan *scan)
1706 {
1707     uint32_t ifaceId = if_nametoindex(ifName);
1708     struct nl_msg *msg = NULL;
1709     int32_t ret;
1710 
1711     if (ifaceId == 0) {
1712         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1713         return RET_CODE_FAILURE;
1714     }
1715 
1716     msg = nlmsg_alloc();
1717     if (msg == NULL) {
1718         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1719         return RET_CODE_NOMEM;
1720     }
1721 
1722     genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_TRIGGER_SCAN, 0);
1723     nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1724     do {
1725         ret = CmdScanPutMsg(ifName, msg, scan);
1726         if (ret != RET_CODE_SUCCESS) {
1727             HILOG_ERROR(LOG_CORE, "%s: put msg failed", __FUNCTION__);
1728             break;
1729         }
1730         ret = NetlinkSendCmdSync(msg, NULL, NULL);
1731         if (ret != RET_CODE_SUCCESS) {
1732             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1733         }
1734     } while (0);
1735     nlmsg_free(msg);
1736     return ret;
1737 }
1738 
ParsePowerMode(const char * buf,uint16_t len,uint8_t * mode)1739 static int32_t ParsePowerMode(const char *buf, uint16_t len, uint8_t *mode)
1740 {
1741     char *key[WIFI_POWER_MODE_NUM] = {"sleep\n", "third\n", "init\n"};
1742     char *str = "pow_mode = ";
1743     if (buf == NULL || mode == NULL) {
1744         return RET_CODE_INVALID_PARAM;
1745     }
1746     char *pos = strstr(buf, str);
1747     if (pos == NULL) {
1748         HILOG_ERROR(LOG_CORE, "%s: no power mode", __FUNCTION__);
1749         return RET_CODE_FAILURE;
1750     }
1751     pos += strlen(str);
1752     if (!strncmp(pos, key[WIFI_POWER_MODE_SLEEPING], strlen(key[WIFI_POWER_MODE_SLEEPING]))) {
1753         *mode = WIFI_POWER_MODE_SLEEPING;
1754     } else if (!strncmp(pos, key[WIFI_POWER_MODE_GENERAL], strlen(key[WIFI_POWER_MODE_GENERAL]))) {
1755         *mode = WIFI_POWER_MODE_GENERAL;
1756     } else if (!strncmp(pos, key[WIFI_POWER_MODE_THROUGH_WALL], strlen(key[WIFI_POWER_MODE_THROUGH_WALL]))) {
1757         *mode = WIFI_POWER_MODE_THROUGH_WALL;
1758     } else {
1759         HILOG_ERROR(LOG_CORE, "%s: no invalid power mode", __FUNCTION__);
1760         return RET_CODE_FAILURE;
1761     }
1762     return RET_CODE_SUCCESS;
1763 }
1764 
GetCurrentPowerMode(const char * ifName,uint8_t * mode)1765 int32_t GetCurrentPowerMode(const char *ifName, uint8_t *mode)
1766 {
1767     int32_t fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1768     int32_t ret;
1769     HwprivIoctlData ioctlData;
1770 
1771     (void)memset_s(&ioctlData, sizeof(ioctlData), 0, sizeof(ioctlData));
1772     if (fd < 0) {
1773         HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1774         return RET_CODE_FAILURE;
1775     }
1776     do {
1777         if (strcpy_s(ioctlData.interfaceName, IFNAMSIZ, ifName) != EOK) {
1778             HILOG_ERROR(LOG_CORE, "%s: strcpy_s failed", __FUNCTION__);
1779             ret = RET_CODE_FAILURE;
1780             break;
1781         }
1782         ioctlData.data.point.flags = SECONDARY_ID_POWER_MODE;
1783         ioctlData.data.point.length = strlen(GET_POWER_MODE) + 1;
1784         ioctlData.data.point.buf = calloc(ioctlData.data.point.length, sizeof(char));
1785         if (ioctlData.data.point.buf == NULL) {
1786             HILOG_ERROR(LOG_CORE, "%s: calloc failed", __FUNCTION__);
1787             ret = RET_CODE_NOMEM;
1788             break;
1789         }
1790         if (memcpy_s(ioctlData.data.point.buf, ioctlData.data.point.length,
1791             GET_POWER_MODE, strlen(GET_POWER_MODE)) != EOK) {
1792             HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed", __FUNCTION__);
1793             ret = RET_CODE_FAILURE;
1794             break;
1795         }
1796         ret = ioctl(fd, PRIMARY_ID_POWER_MODE, &ioctlData);
1797         if (ret != RET_CODE_SUCCESS) {
1798             HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1799             if (errno == EOPNOTSUPP) {
1800                 ret = RET_CODE_NOT_SUPPORT;
1801             } else {
1802                 ret = RET_CODE_FAILURE;
1803             }
1804             break;
1805         }
1806         ret = ParsePowerMode(ioctlData.data.point.buf, ioctlData.data.point.length, mode);
1807         if (ret != RET_CODE_SUCCESS) {
1808             HILOG_ERROR(LOG_CORE, "%s: ParsePowerMode failed", __FUNCTION__);
1809             break;
1810         }
1811     } while (0);
1812     if (ioctlData.data.point.buf != NULL) {
1813         free(ioctlData.data.point.buf);
1814         ioctlData.data.point.buf = NULL;
1815     }
1816     close(fd);
1817     return ret;
1818 }
1819 
FillHwprivIoctlData(HwprivIoctlData * ioctlData,uint8_t mode)1820 static int32_t FillHwprivIoctlData(HwprivIoctlData *ioctlData, uint8_t mode)
1821 {
1822     const char *strTable[WIFI_POWER_MODE_NUM] = {SET_POWER_MODE_SLEEP, SET_POWER_MODE_THIRD, SET_POWER_MODE_INIT};
1823     const char *modeStr = strTable[mode];
1824 
1825     ioctlData->data.point.length = strlen(strTable[mode]) + 1;
1826     ioctlData->data.point.buf = calloc(ioctlData->data.point.length, sizeof(char));
1827     if (ioctlData->data.point.buf == NULL) {
1828         HILOG_ERROR(LOG_CORE, "%s: calloc failed", __FUNCTION__);
1829         return RET_CODE_NOMEM;
1830     }
1831     ioctlData->data.point.flags = SECONDARY_ID_POWER_MODE;
1832     if (strncpy_s(ioctlData->data.point.buf, ioctlData->data.point.length, modeStr, strlen(modeStr)) != EOK) {
1833         HILOG_ERROR(LOG_CORE, "%s: strncpy_s failed", __FUNCTION__);
1834         free(ioctlData->data.point.buf);
1835         ioctlData->data.point.buf = NULL;
1836         return RET_CODE_FAILURE;
1837     }
1838 
1839     return RET_CODE_SUCCESS;
1840 }
1841 
SetPowerMode(const char * ifName,uint8_t mode)1842 int32_t SetPowerMode(const char *ifName, uint8_t mode)
1843 {
1844     int32_t fd;
1845     int32_t ret;
1846     HwprivIoctlData ioctlData;
1847 
1848     if (ifName == NULL || mode >= WIFI_POWER_MODE_NUM) {
1849         HILOG_ERROR(LOG_CORE, "%s: Invalid parameter", __FUNCTION__);
1850         return RET_CODE_FAILURE;
1851     }
1852     (void)memset_s(&ioctlData, sizeof(ioctlData), 0, sizeof(ioctlData));
1853     fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1854     if (fd < 0) {
1855         HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1856         return RET_CODE_FAILURE;
1857     }
1858 
1859     do {
1860         if (strcpy_s(ioctlData.interfaceName, IFNAMSIZ, ifName) != EOK) {
1861             HILOG_ERROR(LOG_CORE, "%s: strcpy_s failed", __FUNCTION__);
1862             ret = RET_CODE_FAILURE;
1863             break;
1864         }
1865         ret = FillHwprivIoctlData(&ioctlData, mode);
1866         if (ret != RET_CODE_SUCCESS) {
1867             break;
1868         }
1869         ret = ioctl(fd, PRIMARY_ID_POWER_MODE, &ioctlData);
1870         if (ret != RET_CODE_SUCCESS) {
1871             HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1872             if (errno == EOPNOTSUPP) {
1873                 ret = RET_CODE_NOT_SUPPORT;
1874             } else {
1875                 ret = RET_CODE_FAILURE;
1876             }
1877         }
1878     } while (0);
1879 
1880     if (ioctlData.data.point.buf != NULL) {
1881         free(ioctlData.data.point.buf);
1882         ioctlData.data.point.buf = NULL;
1883     }
1884     close(fd);
1885     return ret;
1886 }
1887 
StartChannelMeas(const char * ifName,const struct MeasParam * measParam)1888 int32_t StartChannelMeas(const char *ifName, const struct MeasParam *measParam)
1889 {
1890     (void)ifName;
1891     (void)measParam;
1892     return RET_CODE_NOT_SUPPORT;
1893 }
1894 
GetChannelMeasResult(const char * ifName,struct MeasResult * measResult)1895 int32_t GetChannelMeasResult(const char *ifName, struct MeasResult *measResult)
1896 {
1897     (void)ifName;
1898     (void)measResult;
1899     return RET_CODE_NOT_SUPPORT;
1900 }
1901 
SendCommandToDriver(const char * cmd,uint32_t len,const char * ifName,WifiPrivCmd * out)1902 static int32_t SendCommandToDriver(const char *cmd, uint32_t len, const char *ifName, WifiPrivCmd *out)
1903 {
1904     struct ifreq ifr;
1905     int32_t ret = RET_CODE_FAILURE;
1906 
1907     if (cmd == NULL || out == NULL) {
1908         HILOG_ERROR(LOG_CORE, "%{public}s: cmd or out is null", __FUNCTION__);
1909         return RET_CODE_INVALID_PARAM;
1910     }
1911     if (len > out->size) {
1912         HILOG_ERROR(LOG_CORE, "%{public}s: Size of command is too large", __FUNCTION__);
1913         return RET_CODE_INVALID_PARAM;
1914     }
1915     if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
1916         HILOG_ERROR(LOG_CORE, "%s: memset_s ifr failed", __FUNCTION__);
1917         return RET_CODE_FAILURE;
1918     }
1919     if (memcpy_s(out->buf, out->size, cmd, len) != EOK) {
1920         HILOG_ERROR(LOG_CORE, "%{public}s: memcpy_s error", __FUNCTION__);
1921         return RET_CODE_FAILURE;
1922     }
1923     out->len = len;
1924     ifr.ifr_data = (void *)out;
1925     if (strcpy_s(ifr.ifr_name, IFNAMSIZ, ifName) != EOK) {
1926         HILOG_ERROR(LOG_CORE, "%s: strcpy_s error", __FUNCTION__);
1927         return RET_CODE_FAILURE;
1928     }
1929     int32_t sock = socket(AF_INET, SOCK_DGRAM, 0);
1930     if (sock < 0) {
1931         HILOG_ERROR(LOG_CORE, "%{public}s: socket failed, errno = %{public}d, (%{public}s)", __FUNCTION__, errno,
1932             strerror(errno));
1933         return ret;
1934     }
1935     do {
1936         ret = ioctl(sock, SIOCDEVPRIVATE + 1, &ifr);
1937         if (ret < 0) {
1938             HILOG_ERROR(LOG_CORE, "%{public}s: ioctl failed, errno = %{public}d, (%{public}s)", __FUNCTION__, errno,
1939                 strerror(errno));
1940             ret = (errno == EOPNOTSUPP) ? RET_CODE_NOT_SUPPORT : RET_CODE_FAILURE;
1941             break;
1942         }
1943     } while (0);
1944 
1945     close(sock);
1946     return ret;
1947 }
1948 
GetInterfaceState(const char * interfaceName,uint16_t * state)1949 static int32_t GetInterfaceState(const char *interfaceName, uint16_t *state)
1950 {
1951     int32_t ret = RET_CODE_FAILURE;
1952     struct ifreq ifr;
1953     int32_t fd;
1954 
1955     if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
1956         HILOG_ERROR(LOG_CORE, "%s: memset_s req failed", __FUNCTION__);
1957         return RET_CODE_FAILURE;
1958     }
1959 
1960     fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1961     if (fd < 0) {
1962         HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1963         return RET_CODE_FAILURE;
1964     }
1965     do {
1966         if (strncpy_s(ifr.ifr_name, MAX_INTERFACE_NAME_SIZE, interfaceName, strlen(interfaceName)) != EOK) {
1967             HILOG_ERROR(LOG_CORE, "%s: strncpy_s failed", __FUNCTION__);
1968             break;
1969         }
1970         ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
1971         if (ret < 0) {
1972             HILOG_ERROR(LOG_CORE, "%s:could not read interface state for %s, errno = %d, (%s)", __FUNCTION__,
1973                 interfaceName, errno, strerror(errno));
1974             ret = RET_CODE_FAILURE;
1975             break;
1976         }
1977         *state = ifr.ifr_flags;
1978     } while (0);
1979 
1980     close(fd);
1981     return ret;
1982 }
1983 
DisableNextCacOnce(const char * ifName)1984 static int32_t DisableNextCacOnce(const char *ifName)
1985 {
1986     char cmdBuf[P2P_BUF_SIZE] = {CMD_SET_CLOSE_GO_CAC};
1987 
1988     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
1989     WifiPrivCmd out = {0};
1990     out.buf = buf;
1991     out.size = MAX_PRIV_CMD_SIZE;
1992     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
1993 }
1994 
SetGoChannel(const char * ifName,const int8_t * data,uint32_t len)1995 static int32_t SetGoChannel(const char *ifName, const int8_t *data, uint32_t len)
1996 {
1997     int32_t ret = RET_CODE_FAILURE;
1998     char cmdBuf[P2P_BUF_SIZE] = {0};
1999     uint32_t cmdLen;
2000     uint16_t state;
2001 
2002     cmdLen = strlen(CMD_SET_CHANGE_GO_CHANNEL);
2003     if ((cmdLen + len) >= P2P_BUF_SIZE) {
2004         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
2005         return ret;
2006     }
2007     ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_CHANGE_GO_CHANNEL, *data);
2008     if (ret < RET_CODE_SUCCESS) {
2009         HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
2010         return RET_CODE_FAILURE;
2011     }
2012     if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
2013         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2014         return RET_CODE_NETDOWN;
2015     }
2016 
2017     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2018     WifiPrivCmd out = {0};
2019     out.buf = buf;
2020     out.size = MAX_PRIV_CMD_SIZE;
2021     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2022 }
2023 
SetGoDetectRadar(const char * ifName,const int8_t * data,uint32_t len)2024 static int32_t SetGoDetectRadar(const char *ifName, const int8_t *data, uint32_t len)
2025 {
2026     int32_t ret = RET_CODE_FAILURE;
2027     char cmdBuf[P2P_BUF_SIZE] = {0};
2028     uint32_t cmdLen;
2029     uint16_t state;
2030 
2031     cmdLen = strlen(CMD_SET_GO_DETECT_RADAR);
2032     if ((cmdLen + len) >= P2P_BUF_SIZE) {
2033         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
2034         return ret;
2035     }
2036     ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_GO_DETECT_RADAR, *data);
2037     if (ret < RET_CODE_SUCCESS) {
2038         HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
2039         return RET_CODE_FAILURE;
2040     }
2041     if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
2042         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2043         return RET_CODE_NETDOWN;
2044     }
2045 
2046     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2047     WifiPrivCmd out = {0};
2048     out.buf = buf;
2049     out.size = MAX_PRIV_CMD_SIZE;
2050     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2051 }
2052 
SetP2pScenes(const char * ifName,const int8_t * data,uint32_t len)2053 static int32_t SetP2pScenes(const char *ifName, const int8_t *data, uint32_t len)
2054 {
2055     int32_t ret = RET_CODE_FAILURE;
2056     char cmdBuf[P2P_BUF_SIZE] = {0};
2057     uint32_t cmdLen;
2058     uint16_t state;
2059 
2060     cmdLen = strlen(CMD_SET_P2P_SCENES);
2061     if ((cmdLen + len) >= P2P_BUF_SIZE) {
2062         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
2063         return ret;
2064     }
2065     ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_P2P_SCENES, *data);
2066     if (ret < RET_CODE_SUCCESS) {
2067         HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
2068         return RET_CODE_FAILURE;
2069     }
2070     if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
2071         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2072         return RET_CODE_NETDOWN;
2073     }
2074 
2075     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2076     WifiPrivCmd out = {0};
2077     out.buf = buf;
2078     out.size = MAX_PRIV_CMD_SIZE;
2079     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2080 }
2081 
SetDynamicDbacMode(const char * ifName,const int8_t * data,uint32_t len)2082 static int32_t SetDynamicDbacMode(const char *ifName, const int8_t *data, uint32_t len)
2083 {
2084     int32_t ret = RET_CODE_FAILURE;
2085     char cmdBuf[P2P_BUF_SIZE] = {0};
2086     uint32_t cmdLen;
2087     uint16_t state;
2088 
2089     cmdLen = strlen(CMD_SET_DYNAMIC_DBAC_MODE);
2090     if ((cmdLen + len) >= P2P_BUF_SIZE) {
2091         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
2092         return ret;
2093     }
2094     ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_DYNAMIC_DBAC_MODE, *data);
2095     if (ret < RET_CODE_SUCCESS) {
2096         HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
2097         return RET_CODE_FAILURE;
2098     }
2099     if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
2100         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2101         return RET_CODE_NETDOWN;
2102     }
2103 
2104     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2105     WifiPrivCmd out = {0};
2106     out.buf = buf;
2107     out.size = MAX_PRIV_CMD_SIZE;
2108     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2109 }
2110 
SetRxRemainOnChannel(const char * ifName,const int8_t * data,uint32_t len)2111 static int32_t SetRxRemainOnChannel(const char *ifName, const int8_t *data, uint32_t len)
2112 {
2113     int32_t ret = RET_CODE_FAILURE;
2114     char cmdBuf[P2P_BUF_SIZE] = {0};
2115     uint32_t cmdLen;
2116     uint16_t state;
2117 
2118     cmdLen = strlen(CMD_SET_RX_MGMT_REMAIN_ON_CHANNEL);
2119     if ((cmdLen + len) >= P2P_BUF_SIZE) {
2120         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
2121         return ret;
2122     }
2123     ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s", CMD_SET_RX_MGMT_REMAIN_ON_CHANNEL);
2124     if (ret < RET_CODE_SUCCESS) {
2125         HILOG_ERROR(LOG_CORE, "%{public}s: snprintf failed!, ret = %{public}d", __FUNCTION__, ret);
2126         return RET_CODE_FAILURE;
2127     }
2128     cmdLen = (uint32_t)ret;
2129     ret = memcpy_s(cmdBuf + cmdLen + 1, P2P_BUF_SIZE - cmdLen - 1, data, len);
2130     if (ret < RET_CODE_SUCCESS) {
2131         HILOG_ERROR(LOG_CORE, "%{public}s: memcpy failed!, ret = %{public}d", __FUNCTION__, ret);
2132         return RET_CODE_FAILURE;
2133     }
2134     if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
2135         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2136         return RET_CODE_NETDOWN;
2137     }
2138 
2139     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2140     WifiPrivCmd out = {0};
2141     out.buf = buf;
2142     out.size = MAX_PRIV_CMD_SIZE;
2143     return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2144 }
2145 
InitInstallWlanParam(const char * ifName,uint32_t interfaceId,struct nl_msg ** msg,struct nl_msg ** keyMsg)2146 static int32_t InitInstallWlanParam(const char *ifName, uint32_t interfaceId,
2147     struct nl_msg **msg, struct nl_msg **keyMsg)
2148 {
2149     if (interfaceId == 0) {
2150         HILOG_ERROR(LOG_CORE, "%{public}s: if_nametoindex failed", __FUNCTION__);
2151         return RET_CODE_FAILURE;
2152     }
2153 
2154     *msg = nlmsg_alloc();
2155     if (*msg == NULL) {
2156         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2157         return RET_CODE_NOMEM;
2158     }
2159 
2160     *keyMsg = nlmsg_alloc();
2161     if (*keyMsg == NULL) {
2162         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2163         nlmsg_free(*msg);
2164         return RET_CODE_NOMEM;
2165     }
2166     return RET_CODE_SUCCESS;
2167 }
2168 
InstallParam(struct nl_msg * msg,struct nl_msg * keyMsg)2169 static int32_t InstallParam(struct nl_msg *msg, struct nl_msg *keyMsg)
2170 {
2171     HILOG_INFO(LOG_CORE, "enter %{public}s", __FUNCTION__);
2172     if (msg == NULL || keyMsg == NULL) {
2173         HILOG_ERROR(LOG_CORE, "%s: param is NULL ", __FUNCTION__);
2174         return RET_CODE_FAILURE;
2175     }
2176     struct nlmsghdr *hdr = nlmsg_hdr(keyMsg);
2177     void *data = nlmsg_data(hdr);
2178     int len = (int)hdr->nlmsg_len - NLMSG_HDRLEN;
2179     if (memset_s(data, len, 0, len) != 0) {
2180         HILOG_ERROR(LOG_CORE, "%s: memset_s failed", __FUNCTION__);
2181         return RET_CODE_FAILURE;
2182     }
2183 
2184     return NetlinkSendCmdSync(msg, NULL, NULL);
2185 }
2186 
FreeMsg(struct nl_msg * msg,struct nl_msg * keyMsg)2187 static void FreeMsg(struct nl_msg *msg, struct nl_msg *keyMsg)
2188 {
2189     if (msg != NULL) {
2190         nlmsg_free(msg);
2191     }
2192     if (keyMsg != NULL) {
2193         nlmsg_free(keyMsg);
2194     }
2195 }
2196 
WifiInstallWlanExtParam(const char * ifName,const InstallWlanParam * param)2197 int32_t WifiInstallWlanExtParam(const char *ifName, const InstallWlanParam *param)
2198 {
2199     HILOG_INFO(LOG_CORE, "enter %{public}s", __FUNCTION__);
2200     int32_t ret = RET_CODE_FAILURE;
2201     if (ifName == NULL || param == NULL) {
2202         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2203         return RET_CODE_FAILURE;
2204     }
2205 
2206     uint32_t interfaceId = if_nametoindex(ifName);
2207     struct nl_msg *msg = NULL;
2208     struct nl_msg *keyMsg = NULL;
2209     ret = InitInstallWlanParam(ifName, interfaceId, &msg, &keyMsg);
2210     if (ret != RET_CODE_SUCCESS) {
2211         goto err;
2212     }
2213     do {
2214         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_NEW_KEY, 0)) {
2215             break;
2216         }
2217         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2218             break;
2219         }
2220         if (nla_put(keyMsg, NL80211_KEY_DATA, param->len, param->buf)  != RET_CODE_SUCCESS) {
2221             break;
2222         }
2223 
2224         if (nla_put_u32(keyMsg, NL80211_KEY_CIPHER, param->suite)  != RET_CODE_SUCCESS) {
2225             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 suite failed", __FUNCTION__);
2226             break;
2227         }
2228         if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, param->addr)  != RET_CODE_SUCCESS) {
2229             HILOG_ERROR(LOG_CORE, "%s: nla_put addr failed", __FUNCTION__);
2230             break;
2231         }
2232         if (nla_put_u8(keyMsg, NL80211_KEY_IDX, param->id) != RET_CODE_SUCCESS) {
2233             HILOG_ERROR(LOG_CORE, "%s: nla_put_u8 index failed", __FUNCTION__);
2234             break;
2235         }
2236         if (nla_put_nested(msg, NL80211_ATTR_KEY, keyMsg) != RET_CODE_SUCCESS) {
2237             HILOG_ERROR(LOG_CORE, "%s: nla_put_nested failed", __FUNCTION__);
2238             break;
2239         }
2240         ret = InstallParam(msg, keyMsg);
2241         if (ret != RET_CODE_SUCCESS) {
2242             HILOG_ERROR(LOG_CORE, "%s: install wlan ext param failed", __FUNCTION__);
2243             break;
2244         }
2245     } while (0);
2246 err:
2247     FreeMsg(msg, keyMsg);
2248     return ret;
2249 }
2250 
InstallWlanExtParam(const char * ifName,const int8_t * data,uint32_t dataLen)2251 static int32_t InstallWlanExtParam(const char *ifName, const int8_t *data, uint32_t dataLen)
2252 {
2253     if (dataLen > sizeof(InstallWlanParam) || dataLen < sizeof(InstallWlanParam) - MAX_BUF_LEN) {
2254         HILOG_ERROR(LOG_CORE, "%s: dataLen error", __FUNCTION__);
2255         return HDF_FAILURE;
2256     }
2257     uint8_t newData[dataLen];
2258     int32_t ret = memset_s(newData, dataLen, 0, dataLen);
2259     if (ret != EOK) {
2260         HILOG_ERROR(LOG_CORE, "%s: memset_s failed", __FUNCTION__);
2261         return HDF_FAILURE;
2262     }
2263     for (uint32_t i = 0; i < dataLen; i++) {
2264         newData[i] = (uint8_t)(data[i]);
2265     }
2266 
2267     uint8_t id = newData[0];
2268     uint8_t len = newData[1];
2269     const uint8_t *buf = newData + INSTALL_WLAN_HEAD_LEN;
2270     const uint8_t *suite = buf + len;
2271     const uint8_t *mac = buf + len + sizeof(uint32_t);
2272     InstallWlanParam param;
2273     param.id = id;
2274     param.len = len;
2275     param.suite = ((suite[0] << SUITE_LEFT_LEN_24) | (suite[SUITE_INDEX_1] << SUITE_LEFT_LEN_16) |
2276         (suite[SUITE_INDEX_2] << SUITE_LEFT_LEN_8) | suite[SUITE_INDEX_3]);
2277     if (memcpy_s(param.buf, MAX_BUF_LEN, buf, len) != EOK ||
2278         memcpy_s(param.addr, ETH_ADDR_LEN, mac, ETH_ADDR_LEN) != EOK) {
2279         HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed", __FUNCTION__);
2280         return HDF_FAILURE;
2281     }
2282     return WifiInstallWlanExtParam(ifName, &param);
2283 }
2284 
SetProjectionScreenParam(const char * ifName,const ProjectionScreenParam * param)2285 int32_t SetProjectionScreenParam(const char *ifName, const ProjectionScreenParam *param)
2286 {
2287     int32_t ret;
2288     switch (param->cmdId) {
2289         case CMD_CLOSE_GO_CAC:
2290             ret = DisableNextCacOnce(ifName);
2291             break;
2292         case CMD_SET_GO_CSA_CHANNEL:
2293             ret = SetGoChannel(ifName, param->buf, param->bufLen);
2294             break;
2295         case CMD_SET_GO_RADAR_DETECT:
2296             ret = SetGoDetectRadar(ifName, param->buf, param->bufLen);
2297             break;
2298         case CMD_ID_MCC_STA_P2P_QUOTA_TIME:
2299             ret = SetDynamicDbacMode(ifName, param->buf, param->bufLen);
2300             break;
2301         case CMD_ID_CTRL_ROAM_CHANNEL:
2302             ret = SetP2pScenes(ifName, param->buf, param->bufLen);
2303             break;
2304         case CMD_ID_RX_REMAIN_ON_CHANNEL:
2305             ret = SetRxRemainOnChannel(ifName, param->buf, param->bufLen);
2306             break;
2307         case CMD_ID_INSTALL_WLAN_KEY:
2308             ret = InstallWlanExtParam(ifName, param->buf, param->bufLen);
2309             break;
2310         default:
2311             HILOG_ERROR(LOG_CORE, "%{public}s: Invalid command id", __FUNCTION__);
2312             return RET_CODE_NOT_SUPPORT;
2313     }
2314     if (ret != RET_CODE_SUCCESS) {
2315         HILOG_ERROR(LOG_CORE, "%{public}s: Config projection screen fail, ret = %{public}d", __FUNCTION__, ret);
2316     }
2317     return ret;
2318 }
2319 
SendCmdIoctl(const char * ifName,int32_t cmdId,const int8_t * paramBuf,uint32_t paramBufLen)2320 int32_t SendCmdIoctl(const char *ifName, int32_t cmdId, const int8_t *paramBuf, uint32_t paramBufLen)
2321 {
2322     (void)ifName;
2323     (void)cmdId;
2324     (void)paramBuf;
2325     (void)paramBufLen;
2326     return RET_CODE_NOT_SUPPORT;
2327 }
2328 
ParseStaTxRate(struct nlattr ** stats,uint32_t size,StationInfo * info)2329 static void ParseStaTxRate(struct nlattr **stats, uint32_t size, StationInfo *info)
2330 {
2331     struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
2332     static struct nla_policy ratePolicy[NL80211_RATE_INFO_MAX + 1];
2333 
2334     if (size < NL80211_STA_INFO_MAX + 1) {
2335         HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
2336         return;
2337     }
2338     ratePolicy[NL80211_RATE_INFO_BITRATE].type = NLA_U16;
2339     ratePolicy[NL80211_RATE_INFO_BITRATE32].type = NLA_U32;
2340     ratePolicy[NL80211_RATE_INFO_MCS].type = NLA_U8;
2341     ratePolicy[NL80211_RATE_INFO_VHT_MCS].type = NLA_U8;
2342     ratePolicy[NL80211_RATE_INFO_SHORT_GI].type = NLA_FLAG;
2343     ratePolicy[NL80211_RATE_INFO_VHT_NSS].type = NLA_U8;
2344     if (stats[NL80211_STA_INFO_TX_BITRATE] != NULL &&
2345         nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_TX_BITRATE], ratePolicy) == 0) {
2346         if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
2347             info->txRate = nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
2348         } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
2349             info->txRate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
2350         }
2351         if (rate[NL80211_RATE_INFO_MCS] != NULL) {
2352             info->txMcs = nla_get_u8(rate[NL80211_RATE_INFO_MCS]);
2353             info->flags |= STA_DRV_DATA_TX_MCS;
2354         }
2355         if (rate[NL80211_RATE_INFO_VHT_MCS] != NULL) {
2356             info->txVhtmcs = nla_get_u8(rate[NL80211_RATE_INFO_VHT_MCS]);
2357             info->flags |= STA_DRV_DATA_TX_VHT_MCS;
2358         }
2359         if (rate[NL80211_RATE_INFO_SHORT_GI] != NULL) {
2360             info->flags |= STA_DRV_DATA_TX_SHORT_GI;
2361         }
2362         if (rate[NL80211_RATE_INFO_VHT_NSS] != NULL) {
2363             info->txVhtNss = nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]);
2364             info->flags |= STA_DRV_DATA_TX_VHT_NSS;
2365         }
2366     }
2367 }
2368 
ParseStaRxRate(struct nlattr ** stats,uint32_t size,StationInfo * info)2369 static void ParseStaRxRate(struct nlattr **stats, uint32_t size, StationInfo *info)
2370 {
2371     struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
2372     static struct nla_policy ratePolicy[NL80211_RATE_INFO_MAX + 1];
2373 
2374     if (size < NL80211_STA_INFO_MAX + 1) {
2375         HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
2376         return;
2377     }
2378     ratePolicy[NL80211_RATE_INFO_BITRATE].type = NLA_U16;
2379     ratePolicy[NL80211_RATE_INFO_BITRATE32].type = NLA_U32;
2380     ratePolicy[NL80211_RATE_INFO_MCS].type = NLA_U8;
2381     ratePolicy[NL80211_RATE_INFO_VHT_MCS].type = NLA_U8;
2382     ratePolicy[NL80211_RATE_INFO_SHORT_GI].type = NLA_FLAG;
2383     ratePolicy[NL80211_RATE_INFO_VHT_NSS].type = NLA_U8;
2384     if (stats[NL80211_STA_INFO_RX_BITRATE] != NULL &&
2385         nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_RX_BITRATE], ratePolicy) == 0) {
2386         if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
2387             info->rxRate = nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
2388         } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
2389             info->rxRate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
2390         }
2391         if (rate[NL80211_RATE_INFO_MCS] != NULL) {
2392             info->rxMcs = nla_get_u8(rate[NL80211_RATE_INFO_MCS]);
2393             info->flags |= STA_DRV_DATA_RX_MCS;
2394         }
2395         if (rate[NL80211_RATE_INFO_VHT_MCS] != NULL) {
2396             info->rxVhtmcs = nla_get_u8(rate[NL80211_RATE_INFO_VHT_MCS]);
2397             info->flags |= STA_DRV_DATA_RX_VHT_MCS;
2398         }
2399         if (rate[NL80211_RATE_INFO_SHORT_GI] != NULL) {
2400             info->flags |= STA_DRV_DATA_RX_SHORT_GI;
2401         }
2402         if (rate[NL80211_RATE_INFO_VHT_NSS] != NULL) {
2403             info->rxVhtNss = nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]);
2404             info->flags |= STA_DRV_DATA_RX_VHT_NSS;
2405         }
2406     }
2407 }
2408 
ParseStaInfo(struct nlattr ** stats,uint32_t size,StationInfo * info)2409 static void ParseStaInfo(struct nlattr **stats, uint32_t size, StationInfo *info)
2410 {
2411     ParseStaTxRate(stats, size, info);
2412     ParseStaRxRate(stats, size, info);
2413 }
2414 
StationInfoHandler(struct nl_msg * msg,void * arg)2415 static int32_t StationInfoHandler(struct nl_msg *msg, void *arg)
2416 {
2417     StationInfo *info = (StationInfo *)arg;
2418     struct genlmsghdr *hdr = NULL;
2419     struct nlattr *attr[NL80211_ATTR_MAX + 1];
2420     struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
2421     static struct nla_policy statsPolicy[NL80211_STA_INFO_MAX + 1];
2422 
2423     statsPolicy[NL80211_STA_INFO_INACTIVE_TIME].type = NLA_U32;
2424     statsPolicy[NL80211_STA_INFO_RX_BYTES].type = NLA_U32;
2425     statsPolicy[NL80211_STA_INFO_TX_BYTES].type = NLA_U32;
2426     statsPolicy[NL80211_STA_INFO_RX_PACKETS].type = NLA_U32;
2427     statsPolicy[NL80211_STA_INFO_TX_PACKETS].type = NLA_U32;
2428     statsPolicy[NL80211_STA_INFO_TX_FAILED].type = NLA_U32;
2429     statsPolicy[NL80211_STA_INFO_RX_BYTES64].type = NLA_U64;
2430     statsPolicy[NL80211_STA_INFO_TX_BYTES64].type = NLA_U64;
2431     statsPolicy[NL80211_STA_INFO_SIGNAL].type = NLA_U8;
2432     statsPolicy[NL80211_STA_INFO_ACK_SIGNAL].type = NLA_U8;
2433     statsPolicy[NL80211_STA_INFO_RX_DURATION].type = NLA_U64;
2434 
2435     hdr = nlmsg_data(nlmsg_hdr(msg));
2436     if (hdr == NULL) {
2437         HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
2438         return NL_SKIP;
2439     }
2440 
2441     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
2442     if (!attr[NL80211_ATTR_STA_INFO]) {
2443         HILOG_ERROR(LOG_CORE, "%s: sta stats missing!", __FUNCTION__);
2444         return NL_SKIP;
2445     }
2446 
2447     if (nla_parse_nested(stats, NL80211_STA_INFO_MAX, attr[NL80211_ATTR_STA_INFO], statsPolicy)) {
2448         HILOG_ERROR(LOG_CORE, "%s: failed to parse nested attributes!", __FUNCTION__);
2449         return NL_SKIP;
2450     }
2451 
2452     ParseStaInfo(stats, NL80211_STA_INFO_MAX + 1, info);
2453     return NL_SKIP;
2454 }
2455 
GetStationInfo(const char * ifName,StationInfo * info,const uint8_t * mac,uint32_t macLen)2456 int32_t GetStationInfo(const char *ifName, StationInfo *info, const uint8_t *mac, uint32_t macLen)
2457 {
2458     uint32_t ifaceId = if_nametoindex(ifName);
2459     struct nl_msg *msg = NULL;
2460     int32_t ret = RET_CODE_FAILURE;
2461 
2462     if (ifaceId == 0) {
2463         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2464         return RET_CODE_FAILURE;
2465     }
2466 
2467     msg = nlmsg_alloc();
2468     if (msg == NULL) {
2469         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2470         return RET_CODE_NOMEM;
2471     }
2472     do {
2473         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_STATION, 0)) {
2474             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2475             break;
2476         }
2477         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId) != RET_CODE_SUCCESS) {
2478             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 ifaceId faile", __FUNCTION__);
2479             break;
2480         }
2481         if (nla_put(msg, NL80211_ATTR_MAC, ETH_ADDR_LEN, mac) != RET_CODE_SUCCESS) {
2482             HILOG_ERROR(LOG_CORE, "%s: nla_put mac address faile", __FUNCTION__);
2483             break;
2484         }
2485 
2486         ret = NetlinkSendCmdSync(msg, StationInfoHandler, info);
2487         if (ret != RET_CODE_SUCCESS) {
2488             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2489         }
2490     } while (0);
2491     nlmsg_free(msg);
2492     return ret;
2493 }
2494 
SetExtFeatureFlag(const uint8_t * extFeatureFlagsBytes,uint32_t extFeatureFlagsLen,uint32_t extFeatureFlag)2495 static bool SetExtFeatureFlag(const uint8_t *extFeatureFlagsBytes, uint32_t extFeatureFlagsLen, uint32_t extFeatureFlag)
2496 {
2497     uint32_t extFeatureFlagBytePos;
2498     uint32_t extFeatureFlagBitPos;
2499 
2500     if (extFeatureFlagsBytes == NULL || extFeatureFlagsLen == 0) {
2501         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2502         return false;
2503     }
2504     extFeatureFlagBytePos = extFeatureFlag / BITNUMS_OF_ONE_BYTE;
2505     extFeatureFlagBitPos = extFeatureFlag % BITNUMS_OF_ONE_BYTE;
2506     if (extFeatureFlagBytePos >= extFeatureFlagsLen) {
2507         return false;
2508     }
2509     return extFeatureFlagsBytes[extFeatureFlagBytePos] & (1U << extFeatureFlagBitPos);
2510 }
2511 
GetWiphyInfoHandler(struct nl_msg * msg,void * arg)2512 static int32_t GetWiphyInfoHandler(struct nl_msg *msg, void *arg)
2513 {
2514     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
2515     struct nlattr *attr[NL80211_ATTR_MAX + 1];
2516     WiphyInfo *wiphyInfo = (WiphyInfo *)arg;
2517     uint32_t featureFlags = 0;
2518     uint8_t *extFeatureFlagsBytes = NULL;
2519     uint32_t extFeatureFlagsLen = 0;
2520 
2521     if (hdr == NULL) {
2522         HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
2523         return NL_SKIP;
2524     }
2525     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
2526     if (attr[NL80211_ATTR_MAX_NUM_SCAN_SSIDS] != NULL) {
2527         wiphyInfo->scanCapabilities.maxNumScanSsids = nla_get_u8(attr[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
2528     }
2529     if (attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS] != NULL) {
2530         wiphyInfo->scanCapabilities.maxNumSchedScanSsids = nla_get_u8(attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
2531     }
2532     if (attr[NL80211_ATTR_MAX_MATCH_SETS] != NULL) {
2533         wiphyInfo->scanCapabilities.maxMatchSets = nla_get_u8(attr[NL80211_ATTR_MAX_MATCH_SETS]);
2534     }
2535     if (attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS] != NULL) {
2536         wiphyInfo->scanCapabilities.maxNumScanPlans = nla_get_u32(attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS]);
2537     }
2538     if (attr[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL] != NULL) {
2539         wiphyInfo->scanCapabilities.maxScanPlanInterval = nla_get_u32(attr[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL]);
2540     }
2541     if (attr[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS] != NULL) {
2542         wiphyInfo->scanCapabilities.maxScanPlanIterations = nla_get_u32(attr[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]);
2543     }
2544     if (attr[NL80211_ATTR_FEATURE_FLAGS] != NULL) {
2545         featureFlags = nla_get_u32(attr[NL80211_ATTR_FEATURE_FLAGS]);
2546     }
2547     wiphyInfo->wiphyFeatures.supportsRandomMacSchedScan = featureFlags & NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
2548     if (attr[NL80211_ATTR_EXT_FEATURES] != NULL) {
2549         extFeatureFlagsBytes = nla_data(attr[NL80211_ATTR_EXT_FEATURES]);
2550         extFeatureFlagsLen = (uint32_t)nla_len(attr[NL80211_ATTR_EXT_FEATURES]);
2551         wiphyInfo->wiphyFeatures.supportsLowPowerOneshotScan =
2552             SetExtFeatureFlag(extFeatureFlagsBytes, extFeatureFlagsLen, NL80211_EXT_FEATURE_LOW_POWER_SCAN);
2553         wiphyInfo->wiphyFeatures.supportsExtSchedScanRelativeRssi =
2554             SetExtFeatureFlag(extFeatureFlagsBytes, extFeatureFlagsLen, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI);
2555     }
2556     return NL_SKIP;
2557 }
2558 
GetWiphyInfo(const uint32_t wiphyIndex,WiphyInfo * wiphyInfo)2559 static int32_t GetWiphyInfo(const uint32_t wiphyIndex, WiphyInfo *wiphyInfo)
2560 {
2561     struct nl_msg *msg = NULL;
2562     int32_t ret = RET_CODE_FAILURE;
2563 
2564     if (wiphyInfo == NULL) {
2565         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2566         return RET_CODE_INVALID_PARAM;
2567     }
2568     msg = nlmsg_alloc();
2569     if (msg == NULL) {
2570         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2571         return RET_CODE_NOMEM;
2572     }
2573     do {
2574         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_WIPHY, 0)) {
2575             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2576             break;
2577         }
2578         if (nla_put_u32(msg, NL80211_ATTR_WIPHY, wiphyIndex) != RET_CODE_SUCCESS) {
2579             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 wiphyIndex failed.", __FUNCTION__);
2580             break;
2581         }
2582         ret = NetlinkSendCmdSync(msg, GetWiphyInfoHandler, wiphyInfo);
2583         if (ret != RET_CODE_SUCCESS) {
2584             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2585         }
2586     } while (0);
2587     nlmsg_free(msg);
2588     return ret;
2589 }
2590 
GetWiphyIndexHandler(struct nl_msg * msg,void * arg)2591 static int32_t GetWiphyIndexHandler(struct nl_msg *msg, void *arg)
2592 {
2593     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
2594     struct nlattr *attr[NL80211_ATTR_MAX + 1];
2595     uint32_t *wiphyIndex = (uint32_t *)arg;
2596 
2597     if (hdr == NULL) {
2598         HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
2599         return NL_SKIP;
2600     }
2601     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
2602     if (!attr[NL80211_ATTR_WIPHY]) {
2603         HILOG_ERROR(LOG_CORE, "%s: wiphy info missing!", __FUNCTION__);
2604         return NL_SKIP;
2605     }
2606     *wiphyIndex = nla_get_u32(attr[NL80211_ATTR_WIPHY]);
2607     return NL_SKIP;
2608 }
2609 
GetWiphyIndex(const char * ifName,uint32_t * wiphyIndex)2610 static int32_t GetWiphyIndex(const char *ifName, uint32_t *wiphyIndex)
2611 {
2612     struct nl_msg *msg = NULL;
2613     uint32_t interfaceId;
2614     int32_t ret = RET_CODE_FAILURE;
2615 
2616     if (ifName == NULL || wiphyIndex == NULL) {
2617         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2618         return RET_CODE_INVALID_PARAM;
2619     }
2620     interfaceId = if_nametoindex(ifName);
2621     if (interfaceId == 0) {
2622         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2623         return RET_CODE_FAILURE;
2624     }
2625     msg = nlmsg_alloc();
2626     if (msg == NULL) {
2627         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2628         return RET_CODE_NOMEM;
2629     }
2630     do {
2631         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0)) {
2632             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2633             break;
2634         }
2635         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2636             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed.", __FUNCTION__);
2637             break;
2638         }
2639         ret = NetlinkSendCmdSync(msg, GetWiphyIndexHandler, wiphyIndex);
2640         if (ret != RET_CODE_SUCCESS) {
2641             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2642         }
2643     } while (0);
2644     nlmsg_free(msg);
2645     return ret;
2646 }
2647 
ProcessMatchSsidToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2648 static int32_t ProcessMatchSsidToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2649 {
2650     struct nlattr *nestedMatchSsid = NULL;
2651     struct nlattr *nest = NULL;
2652     uint8_t matchSsidsCount = 0;
2653 
2654     nestedMatchSsid = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
2655     if (nestedMatchSsid == NULL) {
2656         HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2657         return RET_CODE_FAILURE;
2658     }
2659     for (uint32_t i = 0; i < pnoSettings->pnoNetworksLen; i++) {
2660         if (matchSsidsCount + 1 > wiphyInfo->scanCapabilities.maxMatchSets) {
2661             break;
2662         }
2663         nest = nla_nest_start(msg, i);
2664         if (nest == NULL) {
2665             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2666             return RET_CODE_FAILURE;
2667         }
2668         if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID, pnoSettings->pnoNetworks[i].ssid.ssidLen,
2669             pnoSettings->pnoNetworks[i].ssid.ssid) != RET_CODE_SUCCESS) {
2670             HILOG_ERROR(LOG_CORE, "%s: nla_put ssid failed.", __FUNCTION__);
2671             return RET_CODE_FAILURE;
2672         }
2673         nla_put_u32(msg, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI, pnoSettings->min5gRssi);
2674         nla_nest_end(msg, nest);
2675         matchSsidsCount++;
2676     }
2677     nla_nest_end(msg, nestedMatchSsid);
2678     return RET_CODE_SUCCESS;
2679 }
2680 
ClearSsidsList(struct DListHead * ssidsList)2681 static void ClearSsidsList(struct DListHead *ssidsList)
2682 {
2683     if (!ssidsList) {
2684         return;
2685     }
2686     struct SsidListNode *ssidListNode = NULL;
2687     struct SsidListNode *tmp = NULL;
2688 
2689     DLIST_FOR_EACH_ENTRY_SAFE(ssidListNode, tmp, ssidsList, struct SsidListNode, entry) {
2690         DListRemove(&ssidListNode->entry);
2691         free(ssidListNode);
2692         ssidListNode = NULL;
2693     }
2694     DListHeadInit(ssidsList);
2695 }
2696 
SsidToMsg(struct nl_msg * msg,struct DListHead * scanSsids)2697 static int32_t SsidToMsg(struct nl_msg *msg, struct DListHead *scanSsids)
2698 {
2699     struct SsidListNode *ssidListNode = NULL;
2700     uint32_t index = 0;
2701     struct nlattr *nestedSsid = NULL;
2702 
2703     if (!scanSsids) {
2704         HILOG_ERROR(LOG_CORE, "%s: scanSsids is null.", __FUNCTION__);
2705         ClearSsidsList(scanSsids);
2706         return RET_CODE_FAILURE;
2707     }
2708     if (!DListIsEmpty(scanSsids)) {
2709         nestedSsid = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
2710         if (nestedSsid == NULL) {
2711             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2712             ClearSsidsList(scanSsids);
2713             return RET_CODE_FAILURE;
2714         }
2715         DLIST_FOR_EACH_ENTRY(ssidListNode, scanSsids, struct SsidListNode, entry) {
2716             if (nla_put(msg, index, ssidListNode->ssidInfo.ssidLen, ssidListNode->ssidInfo.ssid) != RET_CODE_SUCCESS) {
2717                 HILOG_ERROR(LOG_CORE, "%s: nla_put ssid failed.", __FUNCTION__);
2718                 ClearSsidsList(scanSsids);
2719                 return RET_CODE_FAILURE;
2720             }
2721             index++;
2722         }
2723         nla_nest_end(msg, nestedSsid);
2724     }
2725     ClearSsidsList(scanSsids);
2726     return RET_CODE_SUCCESS;
2727 }
2728 
ProcessSsidToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2729 static int32_t ProcessSsidToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2730 {
2731     uint8_t scanSsidsCount = 0;
2732     struct DListHead scanSsids = {0};
2733 
2734     DListHeadInit(&scanSsids);
2735     for (uint32_t i = 0; i < pnoSettings->pnoNetworksLen; i++) {
2736         if (!(pnoSettings->pnoNetworks[i].isHidden)) {
2737             continue;
2738         }
2739         if (scanSsidsCount + 1 > wiphyInfo->scanCapabilities.maxNumSchedScanSsids) {
2740             break;
2741         }
2742         struct SsidListNode *ssidNode = (struct SsidListNode *)malloc(sizeof(struct SsidListNode));
2743         if (ssidNode == NULL) {
2744             HILOG_ERROR(LOG_CORE, "%s: malloc failed.", __FUNCTION__);
2745             ClearSsidsList(&scanSsids);
2746             return RET_CODE_FAILURE;
2747         }
2748         (void)memset_s(ssidNode, sizeof(struct SsidListNode), 0, sizeof(struct SsidListNode));
2749         ssidNode->ssidInfo.ssidLen = pnoSettings->pnoNetworks[i].ssid.ssidLen;
2750         if (memcpy_s(ssidNode->ssidInfo.ssid, MAX_SSID_LEN, pnoSettings->pnoNetworks[i].ssid.ssid,
2751                 pnoSettings->pnoNetworks[i].ssid.ssidLen) != EOK) {
2752             HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed.", __FUNCTION__);
2753             free(ssidNode);
2754             ssidNode = NULL;
2755             ClearSsidsList(&scanSsids);
2756             return RET_CODE_FAILURE;
2757         }
2758         DListInsertTail(&ssidNode->entry, &scanSsids);
2759         scanSsidsCount++;
2760     }
2761     return SsidToMsg(msg, &scanSsids);
2762 }
2763 
ProcessScanPlanToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2764 static int32_t ProcessScanPlanToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2765 {
2766     struct nlattr *nestedPlan = NULL;
2767     struct nlattr *plan = NULL;
2768 
2769     bool supportNumScanPlans = (wiphyInfo->scanCapabilities.maxNumScanPlans >= 2);
2770     bool supportScanPlanInterval = (wiphyInfo->scanCapabilities.maxScanPlanInterval * MS_PER_SECOND >=
2771         (uint32_t)pnoSettings->scanIntervalMs * SLOW_SCAN_INTERVAL_MULTIPLIER);
2772     bool supportScanPlanIterations = (wiphyInfo->scanCapabilities.maxScanPlanIterations >= FAST_SCAN_ITERATIONS);
2773 
2774     if (supportNumScanPlans && supportScanPlanInterval && supportScanPlanIterations) {
2775         nestedPlan = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
2776         if (nestedPlan == NULL) {
2777             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2778             return RET_CODE_FAILURE;
2779         }
2780         plan = nla_nest_start(msg, SCHED_SCAN_PLANS_ATTR_INDEX1);
2781         nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL, pnoSettings->scanIntervalMs);
2782         nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS, pnoSettings->scanIterations);
2783         nla_nest_end(msg, plan);
2784         plan = nla_nest_start(msg, SCHED_SCAN_PLANS_ATTR_INDEX2);
2785         nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL, pnoSettings->scanIntervalMs * SLOW_SCAN_INTERVAL_MULTIPLIER);
2786         nla_nest_end(msg, plan);
2787         nla_nest_end(msg, nestedPlan);
2788     } else {
2789         nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, pnoSettings->scanIntervalMs * MS_PER_SECOND);
2790     }
2791     return RET_CODE_SUCCESS;
2792 }
2793 
ClearFreqsList(struct DListHead * freqsList)2794 static void ClearFreqsList(struct DListHead *freqsList)
2795 {
2796     struct FreqListNode *freqListNode = NULL;
2797     struct FreqListNode *tmp = NULL;
2798 
2799     DLIST_FOR_EACH_ENTRY_SAFE(freqListNode, tmp, freqsList, struct FreqListNode, entry) {
2800         DListRemove(&freqListNode->entry);
2801         free(freqListNode);
2802         freqListNode = NULL;
2803     }
2804     DListHeadInit(freqsList);
2805 }
2806 
InsertFreqToList(int32_t freq,struct DListHead * scanFreqs)2807 static int32_t InsertFreqToList(int32_t freq, struct DListHead *scanFreqs)
2808 {
2809     bool isFreqExist = false;
2810     struct FreqListNode *freqListNode = NULL;
2811 
2812     DLIST_FOR_EACH_ENTRY(freqListNode, scanFreqs, struct FreqListNode, entry) {
2813         if (freqListNode == NULL) {
2814             HILOG_ERROR(LOG_CORE, "%s: freqListNode is NULL.", __FUNCTION__);
2815             return RET_CODE_FAILURE;
2816         }
2817         if (freqListNode->freq == freq) {
2818             isFreqExist = true;
2819             break;
2820         }
2821     }
2822     if (!isFreqExist) {
2823         struct FreqListNode *freqNode = (struct FreqListNode *)malloc(sizeof(struct FreqListNode));
2824         if (freqNode == NULL) {
2825             HILOG_ERROR(LOG_CORE, "%s: malloc failed.", __FUNCTION__);
2826             return RET_CODE_FAILURE;
2827         }
2828         (void)memset_s(freqNode, sizeof(struct FreqListNode), 0, sizeof(struct FreqListNode));
2829         freqNode->freq = freq;
2830         DListInsertTail(&freqNode->entry, scanFreqs);
2831     }
2832     return RET_CODE_SUCCESS;
2833 }
2834 
ProcessFreqToMsg(struct nl_msg * msg,const WifiPnoSettings * pnoSettings)2835 static int32_t ProcessFreqToMsg(struct nl_msg *msg, const WifiPnoSettings *pnoSettings)
2836 {
2837     struct FreqListNode *freqListNode = NULL;
2838     struct DListHead scanFreqs = {0};
2839     struct nlattr *nestedFreq = NULL;
2840     uint32_t index = 0;
2841 
2842     DListHeadInit(&scanFreqs);
2843     for (uint32_t i = 0; i < pnoSettings->pnoNetworksLen; i++) {
2844         for (uint32_t j = 0; j < pnoSettings->pnoNetworks[i].freqsLen; j++) {
2845             if (InsertFreqToList(pnoSettings->pnoNetworks[i].freqs[j], &scanFreqs) != RET_CODE_SUCCESS) {
2846                 HILOG_ERROR(LOG_CORE, "%s: InsertFreqToList failed.", __FUNCTION__);
2847                 ClearFreqsList(&scanFreqs);
2848                 return RET_CODE_FAILURE;
2849             }
2850         }
2851     }
2852     if (!DListIsEmpty(&scanFreqs)) {
2853         nestedFreq = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
2854         if (nestedFreq == NULL) {
2855             HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2856             ClearFreqsList(&scanFreqs);
2857             return RET_CODE_FAILURE;
2858         }
2859         DLIST_FOR_EACH_ENTRY(freqListNode, &scanFreqs, struct FreqListNode, entry) {
2860             nla_put_s32(msg, index, freqListNode->freq);
2861             index++;
2862         }
2863         nla_nest_end(msg, nestedFreq);
2864     }
2865     ClearFreqsList(&scanFreqs);
2866     return RET_CODE_SUCCESS;
2867 }
2868 
ProcessReqflagsToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2869 static int32_t ProcessReqflagsToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2870 {
2871     uint32_t scanFlag = 0;
2872 
2873     if (wiphyInfo->wiphyFeatures.supportsExtSchedScanRelativeRssi) {
2874         struct nl80211_bss_select_rssi_adjust rssiAdjust;
2875         (void)memset_s(&rssiAdjust, sizeof(rssiAdjust), 0, sizeof(rssiAdjust));
2876         rssiAdjust.band = NL80211_BAND_2GHZ;
2877         rssiAdjust.delta = pnoSettings->min2gRssi - pnoSettings->min5gRssi;
2878         if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST, sizeof(rssiAdjust), &rssiAdjust) != RET_CODE_SUCCESS) {
2879             HILOG_ERROR(LOG_CORE, "%s: nla_put rssiAdjust failed.", __FUNCTION__);
2880             return RET_CODE_FAILURE;
2881         }
2882     }
2883     if (wiphyInfo->wiphyFeatures.supportsRandomMacSchedScan) {
2884         scanFlag |= NL80211_SCAN_FLAG_RANDOM_ADDR;
2885     }
2886     if (wiphyInfo->wiphyFeatures.supportsLowPowerOneshotScan) {
2887         scanFlag |= NL80211_SCAN_FLAG_LOW_POWER;
2888     }
2889     if (scanFlag != 0) {
2890         nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, scanFlag);
2891     }
2892     return RET_CODE_SUCCESS;
2893 }
2894 
ConvertSetsToNetlinkmsg(struct nl_msg * msg,const char * ifName,const WifiPnoSettings * pnoSettings)2895 static int32_t ConvertSetsToNetlinkmsg(struct nl_msg *msg, const char *ifName, const WifiPnoSettings *pnoSettings)
2896 {
2897     int32_t ret;
2898     uint32_t wiphyIndex;
2899     WiphyInfo wiphyInfo;
2900 
2901     (void)memset_s(&wiphyInfo, sizeof(wiphyInfo), 0, sizeof(wiphyInfo));
2902     ret = GetWiphyIndex(ifName, &wiphyIndex);
2903     if (ret != RET_CODE_SUCCESS) {
2904         HILOG_ERROR(LOG_CORE, "%s: GetWiphyIndex failed", __FUNCTION__);
2905         return RET_CODE_FAILURE;
2906     }
2907     ret = GetWiphyInfo(wiphyIndex, &wiphyInfo);
2908     if (ret != RET_CODE_SUCCESS) {
2909         HILOG_ERROR(LOG_CORE, "%s: GetWiphyInfo failed", __FUNCTION__);
2910         return RET_CODE_FAILURE;
2911     }
2912     if (ProcessMatchSsidToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2913         ProcessSsidToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2914         ProcessScanPlanToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2915         ProcessReqflagsToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2916         ProcessFreqToMsg(msg, pnoSettings) != RET_CODE_SUCCESS) {
2917         HILOG_ERROR(LOG_CORE, "%s: Fill parameters to netlink failed.", __FUNCTION__);
2918         return RET_CODE_FAILURE;
2919     }
2920     return RET_CODE_SUCCESS;
2921 }
2922 
WifiStartPnoScan(const char * ifName,const WifiPnoSettings * pnoSettings)2923 int32_t WifiStartPnoScan(const char *ifName, const WifiPnoSettings *pnoSettings)
2924 {
2925     HILOG_INFO(LOG_CORE, "hal enter %{public}s ifName:%{public}s", __FUNCTION__, ifName);
2926     uint32_t interfaceId;
2927     struct nl_msg *msg = NULL;
2928     int32_t ret = RET_CODE_FAILURE;
2929 
2930     interfaceId = if_nametoindex(ifName);
2931     if (interfaceId == 0) {
2932         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2933         return RET_CODE_FAILURE;
2934     }
2935     msg = nlmsg_alloc();
2936     if (msg == NULL) {
2937         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2938         return RET_CODE_NOMEM;
2939     }
2940     do {
2941         HILOG_INFO(LOG_CORE, "genlmsg_put NL80211_CMD_START_SCHED_SCAN");
2942         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_ACK, NL80211_CMD_START_SCHED_SCAN, 0)) {
2943             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2944             break;
2945         }
2946         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2947             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed.", __FUNCTION__);
2948             break;
2949         }
2950         if (ConvertSetsToNetlinkmsg(msg, ifName, pnoSettings) != RET_CODE_SUCCESS) {
2951             HILOG_ERROR(LOG_CORE, "%s: ConvertSetsToNetlinkmsg failed.", __FUNCTION__);
2952             break;
2953         }
2954         ret = NetlinkSendCmdSync(msg, NULL, NULL);
2955         if (ret != RET_CODE_SUCCESS) {
2956             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2957         }
2958     } while (0);
2959     nlmsg_free(msg);
2960     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
2961     return ret;
2962 }
2963 
WifiStopPnoScan(const char * ifName)2964 int32_t WifiStopPnoScan(const char *ifName)
2965 {
2966     HILOG_INFO(LOG_CORE, "hal enter %{public}s ifName:%{public}s", __FUNCTION__, ifName);
2967     uint32_t interfaceId;
2968     struct nl_msg *msg = NULL;
2969     int32_t ret = RET_CODE_FAILURE;
2970 
2971     interfaceId = if_nametoindex(ifName);
2972     if (interfaceId == 0) {
2973         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2974         return RET_CODE_FAILURE;
2975     }
2976     msg = nlmsg_alloc();
2977     if (msg == NULL) {
2978         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2979         return RET_CODE_NOMEM;
2980     }
2981     do {
2982         HILOG_INFO(LOG_CORE, "genlmsg_put NL80211_CMD_STOP_SCHED_SCAN");
2983         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_ACK, NL80211_CMD_STOP_SCHED_SCAN, 0)) {
2984             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2985             break;
2986         }
2987         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2988             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed.", __FUNCTION__);
2989             break;
2990         }
2991         ret = NetlinkSendCmdSync(msg, NULL, NULL);
2992         if (ret != RET_CODE_SUCCESS) {
2993             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2994         }
2995     } while (0);
2996     nlmsg_free(msg);
2997     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
2998     return ret;
2999 }
3000 
GetAssociatedInfoHandler(struct nl_msg * msg,void * arg)3001 static int32_t GetAssociatedInfoHandler(struct nl_msg *msg, void *arg)
3002 {
3003     struct nlattr *attr[NL80211_ATTR_MAX + 1];
3004     struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3005     struct nlattr *bss[NL80211_BSS_MAX + 1];
3006     uint32_t status;
3007     AssociatedInfo *associatedInfo = (AssociatedInfo *)arg;
3008     struct nla_policy bssPolicy[NL80211_BSS_MAX + 1];
3009     bssPolicy[NL80211_BSS_BSSID].type = NLA_UNSPEC;
3010     bssPolicy[NL80211_BSS_FREQUENCY].type = NLA_U32;
3011     bssPolicy[NL80211_BSS_STATUS].type = NLA_U32;
3012 
3013     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
3014     if (!attr[NL80211_ATTR_BSS]) {
3015         HILOG_ERROR(LOG_CORE, "%s: BSS info missing!", __FUNCTION__);
3016         return NL_SKIP;
3017     }
3018     if (nla_parse_nested(bss, NL80211_BSS_MAX, attr[NL80211_ATTR_BSS], bssPolicy) < 0 ||
3019         bss[NL80211_BSS_STATUS] == NULL) {
3020         HILOG_INFO(LOG_CORE, "%s: BSS attr or status missing!", __FUNCTION__);
3021         return NL_SKIP;
3022     }
3023     status = nla_get_u32(bss[NL80211_BSS_STATUS]);
3024     if (status == BSS_STATUS_ASSOCIATED && bss[NL80211_BSS_FREQUENCY]) {
3025         associatedInfo->associatedFreq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
3026     }
3027     if (status == BSS_STATUS_ASSOCIATED && bss[NL80211_BSS_BSSID]) {
3028         if (memcpy_s(associatedInfo->associatedBssid, ETH_ADDR_LEN,
3029             nla_data(bss[NL80211_BSS_BSSID]), ETH_ADDR_LEN) != EOK) {
3030             HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed!", __FUNCTION__);
3031             return NL_SKIP;
3032         }
3033     }
3034     return NL_SKIP;
3035 }
3036 
WifiGetAssociatedInfo(const char * ifName,AssociatedInfo * associatedInfo)3037 static int32_t WifiGetAssociatedInfo(const char *ifName, AssociatedInfo *associatedInfo)
3038 {
3039     HILOG_INFO(LOG_CORE, "hal enter %{public}s ifName:%{public}s", __FUNCTION__, ifName);
3040     struct nl_msg *msg = NULL;
3041     uint32_t interfaceId;
3042     int32_t ret = RET_CODE_FAILURE;
3043 
3044     interfaceId = if_nametoindex(ifName);
3045     if (interfaceId == 0) {
3046         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
3047         return RET_CODE_FAILURE;
3048     }
3049     msg = nlmsg_alloc();
3050     if (msg == NULL) {
3051         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
3052         return RET_CODE_NOMEM;
3053     }
3054     do {
3055         HILOG_INFO(LOG_CORE, "genlmsg_put NL80211_CMD_GET_SCAN");
3056         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0)) {
3057             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
3058             break;
3059         }
3060         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
3061             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId faile", __FUNCTION__);
3062             break;
3063         }
3064         ret = NetlinkSendCmdSync(msg, GetAssociatedInfoHandler, associatedInfo);
3065         if (ret != RET_CODE_SUCCESS) {
3066             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
3067         }
3068     } while (0);
3069     nlmsg_free(msg);
3070     HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
3071     return ret;
3072 }
3073 
FillSignalExt(struct nlattr ** stats,uint32_t size,struct SignalResult * signalResult)3074 static void FillSignalExt(struct nlattr **stats, uint32_t size, struct SignalResult *signalResult)
3075 {
3076     if (size < NL80211_STA_INFO_MAX + 1) {
3077         HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
3078         return;
3079     }
3080 
3081     if (stats[NL80211_STA_INFO_NOISE] != NULL) {
3082         signalResult->currentNoise = nla_get_s32(stats[NL80211_STA_INFO_NOISE]);
3083     }
3084     if (stats[NL80211_STA_INFO_SNR] != NULL) {
3085         signalResult->currentSnr = nla_get_s32(stats[NL80211_STA_INFO_SNR]);
3086     }
3087     if (stats[NL80211_STA_INFO_CNAHLOAD] != NULL) {
3088         signalResult->currentChload = nla_get_s32(stats[NL80211_STA_INFO_CNAHLOAD]);
3089     }
3090     if (stats[NL80211_STA_INFO_UL_DELAY] != NULL) {
3091         signalResult->currentUlDelay = nla_get_s32(stats[NL80211_STA_INFO_UL_DELAY]);
3092     }
3093 }
3094 
FillSignalRate(struct nlattr ** stats,uint32_t size,struct SignalResult * signalResult)3095 static void FillSignalRate(struct nlattr **stats, uint32_t size, struct SignalResult *signalResult)
3096 {
3097     struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
3098     struct nla_policy ratePolicy[NL80211_RATE_INFO_MAX + 1];
3099     ratePolicy[NL80211_RATE_INFO_BITRATE].type = NLA_U16;
3100     ratePolicy[NL80211_RATE_INFO_BITRATE32].type = NLA_U32;
3101 
3102     if (size < NL80211_STA_INFO_MAX + 1) {
3103         HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
3104         return;
3105     }
3106     if (stats[NL80211_STA_INFO_RX_BITRATE] != NULL &&
3107         nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_RX_BITRATE], ratePolicy) == 0) {
3108         if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
3109             signalResult->rxBitrate = (int32_t)nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
3110         } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
3111             signalResult->rxBitrate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
3112         }
3113     }
3114     if (stats[NL80211_STA_INFO_TX_BITRATE] != NULL &&
3115         nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_TX_BITRATE], ratePolicy) == 0) {
3116         if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
3117             signalResult->txBitrate = (int32_t)nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
3118         } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
3119             signalResult->txBitrate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
3120         }
3121     }
3122 }
3123 
SignalInfoHandler(struct nl_msg * msg,void * arg)3124 static int32_t SignalInfoHandler(struct nl_msg *msg, void *arg)
3125 {
3126     struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3127     struct nlattr *attr[NL80211_ATTR_MAX + 1];
3128     struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
3129     struct nla_policy statsPolicy[NL80211_STA_INFO_MAX + 1];
3130     struct SignalResult *signalResult = (struct SignalResult *)arg;
3131     statsPolicy[NL80211_STA_INFO_SIGNAL].type = NLA_S8;
3132     statsPolicy[NL80211_STA_INFO_RX_BYTES].type = NLA_U32;
3133     statsPolicy[NL80211_STA_INFO_TX_BYTES].type = NLA_U32;
3134     statsPolicy[NL80211_STA_INFO_RX_PACKETS].type = NLA_U32;
3135     statsPolicy[NL80211_STA_INFO_TX_PACKETS].type = NLA_U32;
3136     statsPolicy[NL80211_STA_INFO_TX_FAILED].type = NLA_U32;
3137     statsPolicy[NL80211_STA_INFO_NOISE].type = NLA_S32;
3138     statsPolicy[NL80211_STA_INFO_SNR].type = NLA_S32;
3139     statsPolicy[NL80211_STA_INFO_CNAHLOAD].type = NLA_S32;
3140     statsPolicy[NL80211_STA_INFO_UL_DELAY].type = NLA_S32;
3141 
3142     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
3143     if (!attr[NL80211_ATTR_STA_INFO]) {
3144         HILOG_ERROR(LOG_CORE, "%s: sta stats missing!", __FUNCTION__);
3145         return NL_SKIP;
3146     }
3147     if (nla_parse_nested(stats, NL80211_STA_INFO_MAX, attr[NL80211_ATTR_STA_INFO], statsPolicy) < 0) {
3148         HILOG_ERROR(LOG_CORE, "%s: nla_parse_nested NL80211_ATTR_STA_INFO failed!", __FUNCTION__);
3149         return NL_SKIP;
3150     }
3151     if (stats[NL80211_STA_INFO_SIGNAL] != NULL) {
3152         signalResult->currentRssi = nla_get_s8(stats[NL80211_STA_INFO_SIGNAL]);
3153     }
3154     if (stats[NL80211_STA_INFO_TX_BYTES] != NULL) {
3155         signalResult->currentTxBytes = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
3156     }
3157     if (stats[NL80211_STA_INFO_RX_BYTES] != NULL) {
3158         signalResult->currentRxBytes = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
3159     }
3160     if (stats[NL80211_STA_INFO_TX_PACKETS] != NULL) {
3161         signalResult->currentTxPackets = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
3162     }
3163     if (stats[NL80211_STA_INFO_RX_PACKETS] != NULL) {
3164         signalResult->currentRxPackets = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
3165     }
3166     if (stats[NL80211_STA_INFO_TX_FAILED] != NULL) {
3167         signalResult->currentTxFailed = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
3168     }
3169     FillSignalExt(stats, NL80211_STA_INFO_MAX + 1, signalResult);
3170     FillSignalRate(stats, NL80211_STA_INFO_MAX + 1, signalResult);
3171 
3172     return NL_SKIP;
3173 }
3174 
ClientGetApBandwidth(const char * ifName,uint8_t * bandwidth)3175 int32_t ClientGetApBandwidth(const char *ifName, uint8_t *bandwidth)
3176 {
3177     if (ifName == NULL || bandwidth == NULL) {
3178         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
3179         return RET_CODE_FAILURE;
3180     }
3181 
3182     const char *cmd = CMD_GET_AP_BANDWIDTH;
3183     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
3184     WifiPrivCmd out = {0};
3185     out.buf = buf;
3186     out.size = MAX_PRIV_CMD_SIZE;
3187     int32_t ret = SendCommandToDriver(cmd, strlen(cmd), ifName, &out);
3188     if (ret != RET_CODE_SUCCESS) {
3189         HILOG_ERROR(LOG_CORE, "%s: send command to driver failed, code=%d", __FUNCTION__, ret);
3190         return ret;
3191     }
3192     *bandwidth = *out.buf;
3193 
3194     HILOG_INFO(LOG_CORE, "%s: AP bandwidth: %d", __FUNCTION__, *bandwidth);
3195     return RET_CODE_SUCCESS;
3196 }
3197 
WifiGetSignalPollInfo(const char * ifName,struct SignalResult * signalResult)3198 int32_t WifiGetSignalPollInfo(const char *ifName, struct SignalResult *signalResult)
3199 {
3200     struct nl_msg *msg = NULL;
3201     uint32_t interfaceId;
3202     int32_t ret = RET_CODE_FAILURE;
3203     AssociatedInfo associatedInfo;
3204     (void)memset_s(&associatedInfo, sizeof(associatedInfo), 0, sizeof(associatedInfo));
3205 
3206     if (ifName == NULL || signalResult == NULL) {
3207         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
3208         return RET_CODE_FAILURE;
3209     }
3210     interfaceId = if_nametoindex(ifName);
3211     if (interfaceId == 0) {
3212         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
3213         return RET_CODE_FAILURE;
3214     }
3215     if (WifiGetAssociatedInfo(ifName, &associatedInfo) != RET_CODE_SUCCESS) {
3216         HILOG_ERROR(LOG_CORE, "%s: WifiGetAssociatedInfo failed", __FUNCTION__);
3217         return RET_CODE_FAILURE;
3218     }
3219     signalResult->associatedFreq = (int32_t)(associatedInfo.associatedFreq);
3220     msg = nlmsg_alloc();
3221     if (msg == NULL) {
3222         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
3223         return RET_CODE_NOMEM;
3224     }
3225     do {
3226         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_STATION, 0)) {
3227             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
3228             break;
3229         }
3230         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
3231             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId faile", __FUNCTION__);
3232             break;
3233         }
3234         if (nla_put(msg, NL80211_ATTR_MAC, ETH_ADDR_LEN, associatedInfo.associatedBssid) != RET_CODE_SUCCESS) {
3235             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId faile", __FUNCTION__);
3236             break;
3237         }
3238         ret = NetlinkSendCmdSync(msg, SignalInfoHandler, signalResult);
3239         if (ret != RET_CODE_SUCCESS) {
3240             HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
3241         }
3242     } while (0);
3243     nlmsg_free(msg);
3244     return ret;
3245 }
3246 
WifiEventTxStatus(const char * ifName,struct nlattr ** attr)3247 void WifiEventTxStatus(const char *ifName, struct nlattr **attr)
3248 {
3249     if (ifName == NULL || attr == NULL) {
3250         HILOG_ERROR(LOG_CORE, "%{public}s: is null", __FUNCTION__);
3251         return;
3252     }
3253     if (WaitStartActionLock() == 0) {
3254         HILOG_ERROR(LOG_CORE, "%{public}s: WaitStartActionLock error", __FUNCTION__);
3255         return;
3256     }
3257     g_cookieSucess = (uint32_t)nla_get_u64(attr[NL80211_ATTR_COOKIE]);
3258     HILOG_DEBUG(LOG_CORE, "%{public}s: g_cookieStart = %{public}u g_cookieSucess = %{public}u "
3259         "ack = %{public}d", __FUNCTION__, g_cookieStart, g_cookieSucess,
3260         attr[NL80211_ATTR_ACK] != NULL);
3261 
3262     if (g_cookieStart != g_cookieSucess) {
3263         HILOG_ERROR(LOG_CORE, "%{public}s: ignore cookie", __FUNCTION__);
3264         return;
3265     }
3266     WifiActionData actionData;
3267     uint8_t action[MAX_INDEX] = { 0 };
3268     for (int i = 0; i < ACK_INDEX; i++) {
3269         action[i] = (uint8_t)((g_cookieSucess >> (i * BYTE_UNIT_8)) & 0xFF);
3270     }
3271     if (attr[NL80211_ATTR_ACK] == NULL) {
3272         action[ACK_INDEX] = NO_ACK;
3273     } else {
3274         action[ACK_INDEX] = ACK;
3275     }
3276     actionData.data = action;
3277     actionData.dataLen = MAX_INDEX;
3278     WifiEventReport("p2p0", WIFI_EVENT_ACTION_RECEIVED, &actionData);
3279 }
3280 
WifiSendActionFrameHandler(struct nl_msg * msg,void * arg)3281 static int32_t WifiSendActionFrameHandler(struct nl_msg *msg, void *arg)
3282 {
3283     struct nlattr *attr[NL80211_ATTR_MAX + 1];
3284     struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
3285     if (hdr == NULL) {
3286         HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
3287         return NL_SKIP;
3288     }
3289     nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
3290     if (!attr[NL80211_ATTR_COOKIE]) {
3291         HILOG_ERROR(LOG_CORE, "%{public}s: no attr cookie", __FUNCTION__);
3292         return NL_SKIP;
3293     }
3294     g_cookieStart = (uint32_t)nla_get_u64(attr[NL80211_ATTR_COOKIE]);
3295     HILOG_DEBUG(LOG_CORE, "%{public}s: g_cookieStart = %{public}u", __FUNCTION__, g_cookieStart);
3296     return NL_SKIP;
3297 }
3298 
WifiSendActionFrame(const char * ifName,uint32_t freq,const uint8_t * frameData,uint32_t frameDataLen)3299 int32_t WifiSendActionFrame(const char *ifName, uint32_t freq, const uint8_t *frameData, uint32_t frameDataLen)
3300 {
3301     int32_t ret = RET_CODE_FAILURE;
3302     struct nl_msg *msg = NULL;
3303     uint32_t interfaceId;
3304     if (ifName == NULL || freq == 0 || frameData == NULL || frameDataLen == 0) {
3305         HILOG_ERROR(LOG_CORE, "%{public}s: param is NULL.", __FUNCTION__);
3306         return RET_CODE_FAILURE;
3307     }
3308     interfaceId = if_nametoindex(ifName);
3309     if (interfaceId == 0) {
3310         HILOG_ERROR(LOG_CORE, "%{public}s: if_nametoindex failed", __FUNCTION__);
3311         return RET_CODE_FAILURE;
3312     }
3313     msg = nlmsg_alloc();
3314     if (msg == NULL) {
3315         HILOG_ERROR(LOG_CORE, "%{public}s: nlmsg alloc failed", __FUNCTION__);
3316         return RET_CODE_NOMEM;
3317     }
3318     do {
3319         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_FRAME, 0)) {
3320             HILOG_ERROR(LOG_CORE, "%{public}s: genlmsg_put faile", __FUNCTION__);
3321             break;
3322         }
3323         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
3324             HILOG_ERROR(LOG_CORE, "%{public}s: nla_put_u32 interfaceId failed", __FUNCTION__);
3325             break;
3326         }
3327         if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) != RET_CODE_SUCCESS) {
3328             HILOG_ERROR(LOG_CORE, "%{public}s: nla_put_u32 freq failed", __FUNCTION__);
3329             break;
3330         }
3331         if (strncmp(ifName, STR_CHBA, strlen(STR_CHBA)) != 0 &&
3332             nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK) != RET_CODE_SUCCESS) {
3333             HILOG_ERROR(LOG_CORE, "%{public}s: nla_put_u32 offchannel failed", __FUNCTION__);
3334             break;
3335         }
3336         if (nla_put(msg, NL80211_ATTR_FRAME, frameDataLen, frameData) != RET_CODE_SUCCESS) {
3337             HILOG_ERROR(LOG_CORE, "%{public}s: nla_put_u32 frameData failed", __FUNCTION__);
3338             break;
3339         }
3340         g_cookieStart = 0;
3341         ret = NetlinkSendCmdSync(msg, WifiSendActionFrameHandler, NULL);
3342         if (ret != RET_CODE_SUCCESS) {
3343             HILOG_ERROR(LOG_CORE, "%{public}s: send action failed", __FUNCTION__);
3344         }
3345     } while (0);
3346     nlmsg_free(msg);
3347     return ret;
3348 }
3349 
WifiRegisterActionFrameReceiver(const char * ifName,const uint8_t * match,uint32_t matchLen)3350 int32_t WifiRegisterActionFrameReceiver(const char *ifName, const uint8_t *match, uint32_t matchLen)
3351 {
3352     int32_t ret = RET_CODE_FAILURE;
3353     struct nl_msg *msg = NULL;
3354     uint32_t interfaceId;
3355     if (ifName == NULL || match == NULL || matchLen == 0) {
3356         HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
3357         return RET_CODE_FAILURE;
3358     }
3359     interfaceId = if_nametoindex(ifName);
3360     if (interfaceId == 0) {
3361         HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
3362         return RET_CODE_FAILURE;
3363     }
3364     msg = nlmsg_alloc();
3365     if (msg == NULL) {
3366         HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
3367         return RET_CODE_NOMEM;
3368     }
3369     do {
3370         if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_REGISTER_FRAME, 0)) {
3371             HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
3372             break;
3373         }
3374         if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
3375             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed", __FUNCTION__);
3376             break;
3377         }
3378         if (nla_put(msg, NL80211_ATTR_FRAME_MATCH, matchLen, match) != RET_CODE_SUCCESS) {
3379             HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 frameData failed", __FUNCTION__);
3380             break;
3381         }
3382         if (g_wifiHalInfo.ctrlSock == NULL) {
3383             HILOG_ERROR(LOG_CORE, "%s: ctrlSock is NULL", __FUNCTION__);
3384             break;
3385         }
3386         ret = nl_send_auto(g_wifiHalInfo.ctrlSock, msg);
3387         if (ret < 0) {
3388             HILOG_ERROR(LOG_CORE, "%s: register ctrl sock failed", __FUNCTION__);
3389             break;
3390         }
3391         ret = RET_CODE_SUCCESS;
3392     } while (0);
3393     nlmsg_free(msg);
3394     return ret;
3395 }
3396 
WifiSetPowerSaveMode(const char * ifName,int32_t frequency,int32_t mode)3397 int32_t WifiSetPowerSaveMode(const char *ifName, int32_t frequency, int32_t mode)
3398 {
3399     int32_t ret = RET_CODE_FAILURE;
3400     char cmdBuf[MAX_CMD_LEN] = {0};
3401     uint32_t cmdLen;
3402     uint16_t state;
3403     cmdLen = strlen(CMD_SET_STA_PM_ON);
3404     if (cmdLen >= MAX_CMD_LEN - 1) {
3405         HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large.", __FUNCTION__);
3406         return ret;
3407     }
3408 
3409     ret = snprintf_s(cmdBuf, MAX_CMD_LEN, MAX_CMD_LEN - 1, "%s %d", CMD_SET_STA_PM_ON, mode);
3410     if (ret < RET_CODE_SUCCESS) {
3411         HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
3412         return RET_CODE_FAILURE;
3413     }
3414 
3415     if (GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS || (state & INTERFACE_UP) == 0) {
3416         HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
3417         return RET_CODE_NETDOWN;
3418     }
3419     uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
3420     WifiPrivCmd out = {0};
3421     out.buf = buf;
3422     out.size = MAX_PRIV_CMD_SIZE;
3423     return SendCommandToDriver(cmdBuf, MAX_CMD_LEN, ifName, &out);
3424 }
3425 
3426 int g_dpiNtlFd = -1;
3427 
NtlLinkInit()3428 static int32_t NtlLinkInit()
3429 {
3430     struct sockaddr_nl ntlAddr;
3431     int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_HW_DPI);
3432     if (fd < 0) {
3433         HILOG_ERROR(LOG_CORE, "Cant create netlink socket, err: %{public}s", strerror(errno));
3434         return RET_CODE_FAILURE;
3435     }
3436 
3437     if (memset_s(&ntlAddr, sizeof(ntlAddr), 0, sizeof(ntlAddr)) != EOK) {
3438         HILOG_ERROR(LOG_CORE, "NtlLinkInit: memset_s is failed");
3439         close(fd);
3440         return RET_CODE_FAILURE;
3441     }
3442     ntlAddr.nl_family = AF_NETLINK;
3443     ntlAddr.nl_pid = getpid();
3444     ntlAddr.nl_groups = 0;
3445 
3446     if (bind(fd, (struct sockaddr*)&ntlAddr, sizeof(ntlAddr)) != 0) {
3447         HILOG_ERROR(LOG_CORE, "Cant bind netlink socket.");
3448         close(fd);
3449         return RET_CODE_FAILURE;
3450     }
3451 
3452     return fd;
3453 }
3454 
SendMsgToKernel(unsigned short nlmsgType,int opt,char * data,int datalen,int skfd)3455 static int32_t SendMsgToKernel(unsigned short nlmsgType, int opt, char *data, int datalen, int skfd)
3456 {
3457     struct sockaddr_nl ntlAddr;
3458     struct HwCommMsgT *ntlMsg = NULL;
3459     unsigned int len = datalen + sizeof(struct HwCommMsgT);
3460     int ret = -1;
3461     if (len <= 0) {
3462         return RET_CODE_FAILURE;
3463     }
3464 
3465     ntlMsg = (struct HwCommMsgT *)OsalMemAlloc(len);
3466     if (ntlMsg == NULL) {
3467         return RET_CODE_FAILURE;
3468     }
3469 
3470     if (memset_s(&ntlAddr, sizeof(ntlAddr), 0, sizeof(ntlAddr)) != EOK) {
3471         HILOG_ERROR(LOG_CORE, "ntlAddr memset_s is failed");
3472         OsalMemFree(ntlMsg);
3473         ntlMsg = NULL;
3474         return RET_CODE_FAILURE;
3475     }
3476     ntlAddr.nl_family = AF_NETLINK;
3477     ntlAddr.nl_pid = 0;
3478     ntlAddr.nl_groups = 0;
3479 
3480     if (memset_s(ntlMsg, len, 0, len) != EOK) {
3481         HILOG_ERROR(LOG_CORE, "ntlMsg memset_s is failed");
3482         OsalMemFree(ntlMsg);
3483         ntlMsg = NULL;
3484         return RET_CODE_FAILURE;
3485     }
3486     ntlMsg->hdr.nlmsg_len = NLMSG_LENGTH(DPI_MSG_LEN + datalen + 1);
3487     ntlMsg->hdr.nlmsg_flags = 0;
3488     ntlMsg->hdr.nlmsg_type = nlmsgType;
3489     ntlMsg->hdr.nlmsg_pid = (unsigned int)(getpid());
3490     ntlMsg->opt = opt;
3491 
3492     if (data != NULL && datalen != 0) {
3493         if (memcpy_s(ntlMsg->data, datalen, data, datalen) != EOK) {
3494             HILOG_ERROR(LOG_CORE, "memcpy_s is failed");
3495             OsalMemFree(ntlMsg);
3496             ntlMsg = NULL;
3497             return RET_CODE_FAILURE;
3498         }
3499     }
3500     ret = sendto(skfd, ntlMsg, ntlMsg->hdr.nlmsg_len, 0, (struct sockaddr*)&ntlAddr, sizeof(ntlAddr));
3501     OsalMemFree(ntlMsg);
3502     ntlMsg = NULL;
3503     return ret;
3504 }
3505 
WifiSetDpiMarkRule(int32_t uid,int32_t protocol,int32_t enable)3506 int32_t WifiSetDpiMarkRule(int32_t uid, int32_t protocol, int32_t enable)
3507 {
3508     DpiMarkRuleT dmr;
3509     if (g_dpiNtlFd < 0) {
3510         g_dpiNtlFd = NtlLinkInit();
3511         if (g_dpiNtlFd < 0) {
3512             HILOG_ERROR(LOG_CORE, "Failed to initialize netlink socket.");
3513             return RET_CODE_FAILURE;
3514         }
3515 
3516         HILOG_INFO(LOG_CORE, "Netlink socket created OK.");
3517         if (SendMsgToKernel(NETLINK_REG_TO_KERNEL, 0, NULL, 0, g_dpiNtlFd) < 0) {
3518             close(g_dpiNtlFd);
3519             g_dpiNtlFd = -1;
3520             HILOG_ERROR(LOG_CORE, "Failed to register to kernel.");
3521             return RET_CODE_FAILURE;
3522         }
3523     }
3524 
3525     if (enable == 0) {
3526         if (SendMsgToKernel(NETLINK_STOP_MARK, 0, NULL, 0, g_dpiNtlFd) < 0) {
3527             close(g_dpiNtlFd);
3528             g_dpiNtlFd = -1;
3529             HILOG_ERROR(LOG_CORE, "Failed to send msg to kernel.");
3530             return RET_CODE_FAILURE;
3531         }
3532         HILOG_INFO(LOG_CORE, "Disable Dpi.");
3533         return RET_CODE_SUCCESS;
3534     } else {
3535         if (SendMsgToKernel(NETLINK_START_MARK, 0, NULL, 0, g_dpiNtlFd) < 0) {
3536             close(g_dpiNtlFd);
3537             g_dpiNtlFd = -1;
3538             HILOG_ERROR(LOG_CORE, "Failed to send msg to kernel.");
3539             return RET_CODE_FAILURE;
3540         }
3541     }
3542 
3543     dmr.dmrAppUid = (unsigned int)uid;
3544     dmr.dmrRule.ruleType = DMR_MT_TP;
3545     dmr.dmrRule.ruleBody.matchTpVal = protocol;
3546     dmr.dmrRule.markNum = WZRY_MARK_NUM;
3547 
3548     if (SendMsgToKernel(NETLINK_SET_RULE_TO_KERNEL, 0, (char *)&dmr, sizeof(dmr), g_dpiNtlFd) < 0) {
3549         close(g_dpiNtlFd);
3550         g_dpiNtlFd = -1;
3551         HILOG_ERROR(LOG_CORE, "Failed to add rule.");
3552         return RET_CODE_FAILURE;
3553     }
3554 
3555     HILOG_INFO(LOG_CORE, "SetDpiMarkRule OK.");
3556     return RET_CODE_SUCCESS;
3557 }
3558