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