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