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