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