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