1/* 2 * Copyright (c) 2022-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 <poll.h> 17#include <sys/types.h> 18#include <securec.h> 19#include <unistd.h> 20#include <errno.h> 21#include <net/if.h> 22#include <linux/nl80211.h> 23#include <netlink/genl/ctrl.h> 24#include <netlink/genl/genl.h> 25#include <netlink/handlers.h> 26#include <osal_mem.h> 27 28#include "hilog/log.h" 29#include "../wifi_common_cmd.h" 30#include "netlink_adapter.h" 31 32#define OUI_QCA 0x001374 33 34#define LISTEN_FD_NUMS 2 35#define EVENT_SOCKET_INDEX 0 36#define CTRL_SOCKET_INDEX 1 37#define CTRL_SOCKET_WRITE_SIDE 0 38#define CTRL_SOCKET_READ_SIDE 1 39 40#define BUFSIZE 1024 41#define POLLTIMEOUT 1000 42 43static inline uint32_t BitLeftShift(uint8_t x) 44{ 45 return 1U << x; 46} 47 48#define SCAN_QUAL_INVALID BitLeftShift(0) 49#define SCAN_NOISE_INVALID BitLeftShift(1) 50#define SCAN_LEVEL_INVALID BitLeftShift(2) 51#define SCAN_LEVEL_DBM BitLeftShift(3) 52#define SCAN_ASSOCIATED BitLeftShift(5) 53 54#define SUCCESS_STATUS 0 55#define WLAN_ATTR_SCAN_COOKIE 7 56#define WLAN_ATTR_SCAN_STATUS 8 57#define WLAN_ATTR_SCAN_MAX 11 58#define SCAN_STATUS_MAX 2 59#define NL80211_SCAN_DONE 107 60#define WLAN_CMD_VDR_COMMON 0xCB 61#define DATA_FRAME_MAX_SIZE 1400 62 63typedef struct { 64 WifiScanResults *scanResults; 65 const char *ifName; 66} WifiScanResultArg; 67 68static int g_familyId = 0; 69 70static int NoSeqCheck(struct nl_msg *msg, void *arg) 71{ 72 (void)msg; 73 return NL_OK; 74} 75 76static void QcaWifiEventScanDoneProcess(const char *ifName, struct nlattr *data, size_t len) 77{ 78 struct nlattr *attr[WLAN_ATTR_SCAN_MAX + 1]; 79 uint32_t status; 80 81 if (nla_parse(attr, WLAN_ATTR_SCAN_MAX, data, len, NULL) || 82 attr[WLAN_ATTR_SCAN_STATUS] || 83 !attr[WLAN_ATTR_SCAN_COOKIE]) { 84 return; 85 } 86 87 status = nla_get_u8(attr[WLAN_ATTR_SCAN_STATUS]); 88 if (status >= SCAN_STATUS_MAX) { 89 HILOG_ERROR(LOG_CORE, "%s: invalid status", __FUNCTION__); 90 return; 91 } 92 93 WifiEventReport(ifName, WIFI_EVENT_SCAN_DONE, &status); 94} 95 96static void WifiEventVendorProcess(const char *ifName, struct nlattr **attr) 97{ 98 uint32_t vendorId; 99 uint32_t subCmd; 100 uint8_t *data = NULL; 101 uint32_t len; 102 103 if (attr[NL80211_ATTR_VENDOR_ID] == NULL) { 104 HILOG_ERROR(LOG_CORE, "%s: failed to get vendor id", __FUNCTION__); 105 return; 106 } 107 if (attr[NL80211_ATTR_VENDOR_SUBCMD] == NULL) { 108 HILOG_ERROR(LOG_CORE, "%s: failed to get vendor subcmd", __FUNCTION__); 109 return; 110 } 111 112 vendorId = nla_get_u32(attr[NL80211_ATTR_VENDOR_ID]); 113 subCmd = nla_get_u32(attr[NL80211_ATTR_VENDOR_SUBCMD]); 114 if (vendorId != OUI_QCA || subCmd != NL80211_SCAN_DONE) { 115 HILOG_ERROR(LOG_CORE, "%s: unsupported vendor event", __FUNCTION__); 116 return; 117 } 118 119 if (attr[NL80211_ATTR_VENDOR_DATA] == NULL) { 120 HILOG_ERROR(LOG_CORE, "%s: get vendor data fail", __FUNCTION__); 121 return; 122 } 123 data = nla_data(attr[NL80211_ATTR_VENDOR_DATA]); 124 len = (uint32_t)nla_len(attr[NL80211_ATTR_VENDOR_DATA]); 125 126 QcaWifiEventScanDoneProcess(ifName, (struct nlattr *)data, len); 127} 128 129static int32_t GetNlaDataScanResult(struct nlattr *attr[], int len, WifiScanResult *scanResult) 130{ 131 uint8_t *ie; 132 uint8_t *beaconIe; 133 uint8_t *bssid; 134 135 (void)len; 136 if (attr[NL80211_BSS_INFORMATION_ELEMENTS]) { 137 ie = nla_data(attr[NL80211_BSS_INFORMATION_ELEMENTS]); 138 scanResult->ieLen = (uint32_t)nla_len(attr[NL80211_BSS_INFORMATION_ELEMENTS]); 139 if (ie != NULL && scanResult->ieLen != 0) { 140 scanResult->ie = OsalMemCalloc(scanResult->ieLen); 141 if (scanResult->ie == NULL || memcpy_s(scanResult->ie, scanResult->ieLen, ie, scanResult->ieLen) != EOK) { 142 HILOG_ERROR(LOG_CORE, "%s: fill ie data fail", __FUNCTION__); 143 return RET_CODE_FAILURE; 144 } 145 } 146 } 147 if (attr[NL80211_BSS_BEACON_IES]) { 148 beaconIe = nla_data(attr[NL80211_BSS_INFORMATION_ELEMENTS]); 149 scanResult->beaconIeLen = (uint32_t)nla_len(attr[NL80211_BSS_INFORMATION_ELEMENTS]); 150 if (beaconIe != NULL && scanResult->beaconIeLen != 0) { 151 scanResult->beaconIe = OsalMemCalloc(scanResult->beaconIeLen); 152 if (scanResult->beaconIe == NULL || 153 memcpy_s(scanResult->beaconIe, scanResult->beaconIeLen, beaconIe, scanResult->beaconIeLen) != EOK) { 154 HILOG_ERROR(LOG_CORE, "%s: fill beacon ie data fail", __FUNCTION__); 155 return RET_CODE_FAILURE; 156 } 157 } 158 } 159 if (attr[NL80211_BSS_BSSID]) { 160 bssid = nla_data(attr[NL80211_BSS_BSSID]); 161 if (bssid != NULL) { 162 scanResult->bssid = OsalMemCalloc(ETH_ADDR_LEN); 163 if (scanResult->bssid == NULL || memcpy_s(scanResult->bssid, ETH_ADDR_LEN, bssid, ETH_ADDR_LEN) != EOK) { 164 HILOG_ERROR(LOG_CORE, "%s: fill bssid fail", __FUNCTION__); 165 return RET_CODE_FAILURE; 166 } 167 } 168 } 169 return RET_CODE_SUCCESS; 170} 171 172static int32_t DoGetScanResult(struct nlattr *attr[], int len, WifiScanResult *scanResult) 173{ 174 if (GetNlaDataScanResult(attr, len, scanResult) != RET_CODE_SUCCESS) { 175 return RET_CODE_FAILURE; 176 } 177 if (attr[NL80211_BSS_FREQUENCY]) { 178 scanResult->freq = nla_get_u32(attr[NL80211_BSS_FREQUENCY]); 179 } 180 if (attr[NL80211_BSS_BEACON_INTERVAL]) { 181 scanResult->beaconInt = nla_get_u16(attr[NL80211_BSS_BEACON_INTERVAL]); 182 } 183 if (attr[NL80211_BSS_CAPABILITY]) { 184 scanResult->caps = nla_get_u16(attr[NL80211_BSS_CAPABILITY]); 185 } 186 if (attr[NL80211_BSS_SIGNAL_MBM]) { 187 /* mBm to dBm */ 188 scanResult->level = (int32_t)nla_get_u32(attr[NL80211_BSS_SIGNAL_MBM]) / SIGNAL_LEVEL_CONFFICIENT; 189 scanResult->flags |= SCAN_LEVEL_DBM | SCAN_QUAL_INVALID; 190 } else if (attr[NL80211_BSS_SIGNAL_UNSPEC]) { 191 scanResult->level = (int32_t)nla_get_u8(attr[NL80211_BSS_SIGNAL_UNSPEC]); 192 scanResult->flags |= SCAN_QUAL_INVALID; 193 } else { 194 scanResult->flags |= SCAN_LEVEL_INVALID | SCAN_QUAL_INVALID; 195 } 196 if (attr[NL80211_BSS_TSF]) { 197 scanResult->tsf = nla_get_u64(attr[NL80211_BSS_TSF]); 198 } 199 if (attr[NL80211_BSS_BEACON_TSF]) { 200 uint64_t tsf = nla_get_u64(attr[NL80211_BSS_BEACON_TSF]); 201 if (tsf > scanResult->tsf) { 202 scanResult->tsf = tsf; 203 } 204 } 205 if (attr[NL80211_BSS_SEEN_MS_AGO]) { 206 scanResult->age = nla_get_u32(attr[NL80211_BSS_SEEN_MS_AGO]); 207 } 208 return RET_CODE_SUCCESS; 209} 210 211static int32_t WifiGetScanResultHandler(struct nl_msg *msg, void *arg) 212{ 213 WifiScanResult *scanResult = NULL; 214 WifiScanResults *scanResults = NULL; 215 struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg)); 216 WifiScanResultArg *handlerArg = (WifiScanResultArg *)arg; 217 struct nlattr *attr[NL80211_ATTR_MAX + 1], *bssAttr[NL80211_BSS_MAX + 1]; 218 static struct nla_policy bssPolicy[NL80211_BSS_MAX + 1]; 219 memset_s(bssPolicy, sizeof(bssPolicy), 0, sizeof(bssPolicy)); 220 bssPolicy[NL80211_BSS_FREQUENCY].type = NLA_U32; 221 bssPolicy[NL80211_BSS_TSF].type = NLA_U64; 222 bssPolicy[NL80211_BSS_BEACON_INTERVAL].type = NLA_U16; 223 bssPolicy[NL80211_BSS_CAPABILITY].type = NLA_U16; 224 bssPolicy[NL80211_BSS_SIGNAL_MBM].type = NLA_U32; 225 bssPolicy[NL80211_BSS_SIGNAL_UNSPEC].type = NLA_U8; 226 bssPolicy[NL80211_BSS_STATUS].type = NLA_U32; 227 bssPolicy[NL80211_BSS_SEEN_MS_AGO].type = NLA_U32; 228 229 if (handlerArg == NULL || handlerArg->scanResults == NULL || handlerArg->ifName == NULL) { 230 HILOG_ERROR(LOG_CORE, "%s: Invalid param", __FUNCTION__); 231 return NL_SKIP; 232 } 233 scanResults = handlerArg->scanResults; 234 scanResult = &scanResults->scanResult[scanResults->num]; 235 nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL); 236 if (!attr[NL80211_ATTR_BSS]) { 237 HILOG_ERROR(LOG_CORE, "%s: bss info missing", __FUNCTION__); 238 return NL_SKIP; 239 } 240 if (nla_parse_nested(bssAttr, NL80211_BSS_MAX, attr[NL80211_ATTR_BSS], bssPolicy)) { 241 HILOG_ERROR(LOG_CORE, "%s: failed to parse nested attributes", __FUNCTION__); 242 return NL_SKIP; 243 } 244 if (DoGetScanResult(bssAttr, NL80211_BSS_MAX + 1, scanResult) != RET_CODE_SUCCESS) { 245 HILOG_ERROR(LOG_CORE, "%s: DoGetScanResult fail", __FUNCTION__); 246 FreeScanResult(scanResult); 247 return NL_SKIP; 248 } 249 HILOG_DEBUG(LOG_CORE, "%{public}s, line:%{public}d num:%{public}u scanResultCapacity:%{public}u", __FUNCTION__, 250 __LINE__, scanResults->num, scanResults->scanResultCapacity); 251 scanResults->num++; 252 if (scanResults->num == scanResults->scanResultCapacity) { 253 scanResults->scanResultCapacity += INIT_SCAN_RES_NUM; 254 WifiScanResult *newScanResult = NULL; 255 newScanResult = (WifiScanResult *)OsalMemCalloc(sizeof(WifiScanResult) * (scanResults->scanResultCapacity)); 256 if (newScanResult == NULL) { 257 HILOG_ERROR(LOG_CORE, "%{public}s: newscanResult is NULL", __FUNCTION__); 258 scanResults->scanResultCapacity -= INIT_SCAN_RES_NUM; 259 scanResults->num = 0; 260 return NL_SKIP; 261 } 262 if (memcpy_s((void *)newScanResult, sizeof(WifiScanResult) * (scanResults->scanResultCapacity), 263 (void *)scanResults->scanResult, sizeof(WifiScanResult) * (scanResults->num)) != RET_CODE_SUCCESS) { 264 HILOG_ERROR(LOG_CORE, "%{public}s: memcpy_s fail", __FUNCTION__); 265 } 266 OsalMemFree(scanResults->scanResult); 267 scanResults->scanResult = newScanResult; 268 newScanResult = NULL; 269 } 270 return NL_SKIP; 271} 272 273static void WifiEventScanResultProcess(const char *ifName) 274{ 275 HILOG_DEBUG(LOG_CORE, "hal enter %{public}s", __FUNCTION__); 276 int32_t ret; 277 WifiScanResults scanResults = {0}; 278 WifiScanResultArg arg; 279 uint32_t ifaceId = if_nametoindex(ifName); 280 struct nl_msg *msg = nlmsg_alloc(); 281 if (NULL == msg) { 282 HILOG_ERROR(LOG_CORE, "%s: msg is NULL.", __FUNCTION__); 283 return; 284 } 285 if (InitScanResults(&scanResults) != RET_CODE_SUCCESS) { 286 HILOG_ERROR(LOG_CORE, "%s: InitScanResults failed", __FUNCTION__); 287 return; 288 } 289 arg.scanResults = &scanResults; 290 arg.ifName = ifName; 291 genlmsg_put(msg, 0, 0, g_familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0); 292 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId); 293 ret = NetlinkSendCmdSync(msg, WifiGetScanResultHandler, (void *)&arg); 294 if (ret != RET_CODE_SUCCESS) { 295 HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__); 296 } 297 WifiEventReport(ifName, WIFI_EVENT_SCAN_RESULTS, &scanResults); 298 HILOG_INFO(LOG_CORE, "%s: scanResults.num = %u", __FUNCTION__, scanResults.num); 299 FreeScanResults(&scanResults); 300 nlmsg_free(msg); 301 HILOG_DEBUG(LOG_CORE, "hal exit %{public}s", __FUNCTION__); 302} 303 304static void WifiEventScanAbortedProcess(const char *ifName) 305{ 306 WifiScanResults scanResults = {0}; 307 308 if (ifName == NULL) { 309 HILOG_ERROR(LOG_CORE, "%s: ifName is NULL.", __FUNCTION__); 310 return; 311 } 312 WifiEventReport(ifName, WIFI_EVENT_SCAN_ABORTED, &scanResults); 313} 314 315static void WifiEventDataFrameProcess(const char *ifName, struct nlattr **attr) 316{ 317 WifiDataFrame dataFrame; 318 /* The outer function can ensure that attr is not empty */ 319 if (ifName == NULL || attr[NL80211_ATTR_FRAME] == NULL) { 320 HILOG_ERROR(LOG_CORE, "%{public}s: ifName is invalid or failed to get frame data", __FUNCTION__); 321 return; 322 } 323 324 (void)memset_s(&dataFrame, sizeof(WifiDataFrame), 0, sizeof(WifiDataFrame)); 325 326 dataFrame.data = nla_data(attr[NL80211_ATTR_FRAME]); 327 dataFrame.dataLen = (uint32_t)nla_len(attr[NL80211_ATTR_FRAME]); 328 HILOG_INFO(LOG_CORE, "%{public}s: receive data frame len %{public}u", __FUNCTION__, dataFrame.dataLen); 329 if (dataFrame.dataLen > DATA_FRAME_MAX_SIZE) { 330 return; 331 } 332 333 WifiEventReport(ifName, WIFI_EVENT_DATA_FRAME_RECEIVED, &dataFrame); 334} 335 336static void DoProcessEvent(const char *ifName, int cmd, struct nlattr **attr) 337{ 338 HILOG_DEBUG(LOG_CORE, "hal enter %{public}s cmd=%{public}d ifName=%{public}s", __FUNCTION__, cmd, ifName); 339 switch (cmd) { 340 case NL80211_CMD_VENDOR: 341 HILOG_INFO(LOG_CORE, "receive cmd NL80211_CMD_VENDOR"); 342 WifiEventVendorProcess(ifName, attr); 343 break; 344 case NL80211_CMD_START_SCHED_SCAN: 345 HILOG_INFO(LOG_CORE, "receive cmd NL80211_CMD_START_SCHED_SCAN"); 346 break; 347 case NL80211_CMD_SCHED_SCAN_RESULTS: 348 HILOG_INFO(LOG_CORE, "receive cmd NL80211_CMD_SCHED_SCAN_RESULTS"); 349 WifiEventScanResultProcess(ifName); 350 break; 351 case NL80211_CMD_SCHED_SCAN_STOPPED: 352 HILOG_INFO(LOG_CORE, "receive cmd NL80211_CMD_SCHED_SCAN_STOPPED"); 353 break; 354 case NL80211_CMD_NEW_SCAN_RESULTS: 355 HILOG_INFO(LOG_CORE, "receive cmd NL80211_CMD_NEW_SCAN_RESULTS"); 356 WifiEventScanResultProcess(ifName); 357 break; 358 case NL80211_CMD_SCAN_ABORTED: 359 HILOG_INFO(LOG_CORE, "receive cmd NL80211_CMD_SCAN_ABORTED"); 360 WifiEventScanAbortedProcess(ifName); 361 break; 362 case NL80211_CMD_TRIGGER_SCAN: 363 HILOG_INFO(LOG_CORE, "receive cmd NL80211_CMD_TRIGGER_SCAN"); 364 break; 365 case NL80211_CMD_FRAME_TX_STATUS: 366 HILOG_INFO(LOG_CORE, "receive cmd NL80211_CMD_FRAME_TX_STATUS"); 367 WifiEventTxStatus(ifName, attr); 368 break; 369 case WLAN_CMD_VDR_COMMON: 370 HILOG_INFO(LOG_CORE, "receive cmd WLAN_CMD_VDR_COMMON"); 371 WifiEventDataFrameProcess(ifName, attr); 372 break; 373 default: 374 HILOG_INFO(LOG_CORE, "not supported cmd"); 375 break; 376 } 377 HILOG_DEBUG(LOG_CORE, "hal exit %{public}s", __FUNCTION__); 378} 379 380static int32_t ProcessEvent(struct nl_msg *msg, void *arg) 381{ 382 HILOG_DEBUG(LOG_CORE, "hal enter %{public}s", __FUNCTION__); 383 struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg)); 384 struct nlattr *attr[NL80211_ATTR_MAX + 1]; 385 struct NetworkInfoResult networkInfo; 386 uint32_t ifidx = -1; 387 uint32_t i; 388 int ret; 389 390 nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), 391 genlmsg_attrlen(hdr, 0), NULL); 392 393 if (attr[NL80211_ATTR_IFINDEX]) { 394 ifidx = nla_get_u32(attr[NL80211_ATTR_IFINDEX]); 395 } 396 HILOG_INFO(LOG_CORE, "ifidx = %{public}d", ifidx); 397 398 ret = GetUsableNetworkInfo(&networkInfo); 399 if (ret != RET_CODE_SUCCESS) { 400 HILOG_ERROR(LOG_CORE, "%s: get usable network information failed", __FUNCTION__); 401 return NL_SKIP; 402 } 403 404 for (i = 0; i < networkInfo.nums; i++) { 405 HILOG_DEBUG(LOG_CORE, "name=%{public}s index=%{public}d mode=%{public}s", 406 networkInfo.infos[i].name, if_nametoindex(networkInfo.infos[i].name), networkInfo.infos[i].supportMode); 407 if (ifidx == if_nametoindex(networkInfo.infos[i].name)) { 408 DoProcessEvent(networkInfo.infos[i].name, hdr->cmd, attr); 409 return NL_SKIP; 410 } 411 } 412 HILOG_DEBUG(LOG_CORE, "hal exit %{public}s", __FUNCTION__); 413 return NL_SKIP; 414} 415 416static struct nl_cb *CreateCb(void) 417{ 418 struct nl_cb *cb; 419 420 cb = nl_cb_alloc(NL_CB_DEFAULT); 421 if (cb == NULL) { 422 HILOG_ERROR(LOG_CORE, "%s: alloc cb failed", __FUNCTION__); 423 return NULL; 424 } 425 426 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, NoSeqCheck, NULL); 427 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, ProcessEvent, NULL); 428 429 return cb; 430} 431 432static int HandleEvent(struct nl_sock *sock) 433{ 434 HILOG_DEBUG(LOG_CORE, "hal enter %{public}s", __FUNCTION__); 435 int ret; 436 struct nl_cb *cb = CreateCb(); 437 if (cb == NULL) { 438 HILOG_ERROR(LOG_CORE, "%{public}s: Create cb failed", __FUNCTION__); 439 return RET_CODE_FAILURE; 440 } 441 442 ret = nl_recvmsgs(sock, cb); 443 HILOG_INFO(LOG_CORE, "nl_recvmsgs ret:%{public}d, errno:%{public}d %{public}s", ret, errno, strerror(errno)); 444 nl_cb_put(cb); 445 cb = NULL; 446 HILOG_DEBUG(LOG_CORE, "hal exit %{public}s", __FUNCTION__); 447 return ret; 448} 449 450static int32_t CtrlNoSeqCheck(struct nl_msg *msg, void *arg) 451{ 452 struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg)); 453 struct nlattr *attr[NL80211_ATTR_MAX + 1]; 454 455 nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), 456 genlmsg_attrlen(hdr, 0), NULL); 457 458 if (hdr->cmd != NL80211_CMD_FRAME) { 459 return NL_OK; 460 } 461 if (attr[NL80211_ATTR_FRAME] == NULL) { 462 HILOG_ERROR(LOG_CORE, "%s: failed to get frame data", __FUNCTION__); 463 return NL_OK; 464 } 465 466 WifiActionData actionData; 467 actionData.data = nla_data(attr[NL80211_ATTR_FRAME]); 468 actionData.dataLen = (uint32_t)nla_len(attr[NL80211_ATTR_FRAME]); 469 HILOG_INFO(LOG_CORE, "%s: receive data len = %{public}d", __FUNCTION__, actionData.dataLen); 470 WifiEventReport("p2p0", WIFI_EVENT_ACTION_RECEIVED, &actionData); 471 return NL_OK; 472} 473 474static int32_t CtrlSocketErrorHandler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) 475{ 476 int32_t *ret = (int32_t *)arg; 477 *ret = err->error; 478 HILOG_ERROR(LOG_CORE, "%s: ctrl sock error ret = %{public}d", __FUNCTION__, *ret); 479 return NL_SKIP; 480} 481 482static int32_t CtrlSocketFinishHandler(struct nl_msg *msg, void *arg) 483{ 484 int32_t *ret = (int32_t *)arg; 485 HILOG_ERROR(LOG_CORE, "%s: ctrl sock finish ret = %{public}d", __FUNCTION__, *ret); 486 *ret = 0; 487 return NL_SKIP; 488} 489 490static int32_t CtrlSocketAckHandler(struct nl_msg *msg, void *arg) 491{ 492 int32_t *err = (int32_t *)arg; 493 HILOG_ERROR(LOG_CORE, "%s: ctrl sock ack ret = %{public}d", __FUNCTION__, *err); 494 *err = 0; 495 return NL_STOP; 496} 497 498static int HandleCtrlEvent(struct nl_sock *sock) 499{ 500 HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__); 501 int ret; 502 struct nl_cb *cb; 503 int error; 504 505 cb = nl_cb_alloc(NL_CB_DEFAULT); 506 if (cb == NULL) { 507 HILOG_ERROR(LOG_CORE, "%{public}s: alloc ctrl cb failed", __FUNCTION__); 508 return RET_CODE_FAILURE; 509 } 510 511 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, CtrlNoSeqCheck, NULL); 512 nl_cb_err(cb, NL_CB_CUSTOM, CtrlSocketErrorHandler, &error); 513 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, CtrlSocketFinishHandler, &error); 514 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, CtrlSocketAckHandler, &error); 515 516 ret = nl_recvmsgs(sock, cb); 517 HILOG_INFO(LOG_CORE, "nl_recvmsgs ret:%{public}d, errno:%{public}d %{public}s", ret, errno, strerror(errno)); 518 nl_cb_put(cb); 519 cb = NULL; 520 HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__); 521 return ret; 522} 523 524void *EventThread(void *para) 525{ 526 HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__); 527 struct nl_sock *eventSock = NULL; 528 struct nl_sock *ctrlSock = NULL; 529 struct pollfd pollFds[LISTEN_FD_NUMS] = {0}; 530 struct WifiThreadParam *threadParam = NULL; 531 int ret; 532 enum ThreadStatus *status = NULL; 533 534 if (para == NULL) { 535 HILOG_ERROR(LOG_CORE, "%s: para is null", __FUNCTION__); 536 return NULL; 537 } else { 538 threadParam = (struct WifiThreadParam *)para; 539 eventSock = threadParam->eventSock; 540 ctrlSock = threadParam->ctrlSock; 541 g_familyId = threadParam->familyId; 542 status = threadParam->status; 543 *status = THREAD_RUN; 544 } 545 546 pollFds[EVENT_SOCKET_INDEX].fd = nl_socket_get_fd(eventSock); 547 pollFds[EVENT_SOCKET_INDEX].events = POLLIN | POLLERR; 548 pollFds[CTRL_SOCKET_INDEX].fd = nl_socket_get_fd(ctrlSock); 549 pollFds[CTRL_SOCKET_INDEX].events = POLLIN; 550 551 while (*status == THREAD_RUN) { 552 ret = TEMP_FAILURE_RETRY(poll(pollFds, LISTEN_FD_NUMS, POLLTIMEOUT)); 553 HILOG_DEBUG(LOG_CORE, "EventThread TEMP_FAILURE_RETRY ret:%{public}d status:%{public}d", ret, *status); 554 if (ret < 0) { 555 HILOG_ERROR(LOG_CORE, "%{public}s: fail poll", __FUNCTION__); 556 break; 557 } else if ((uint32_t)pollFds[EVENT_SOCKET_INDEX].revents & POLLERR) { 558 HILOG_ERROR(LOG_CORE, "%{public}s: event socket get POLLERR event", __FUNCTION__); 559 break; 560 } else if ((uint32_t)pollFds[EVENT_SOCKET_INDEX].revents & POLLIN) { 561 if (HandleEvent(eventSock) != RET_CODE_SUCCESS) { 562 HILOG_ERROR(LOG_CORE, "EventThread HandleEvent break"); 563 break; 564 } 565 } else if ((uint32_t)pollFds[CTRL_SOCKET_INDEX].revents & POLLIN) { 566 if (HandleCtrlEvent(ctrlSock) != RET_CODE_SUCCESS) { 567 HILOG_ERROR(LOG_CORE, "EventThread HandleCtrlEvent break"); 568 break; 569 } 570 } 571 } 572 573 *status = THREAD_STOP; 574 HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__); 575 return NULL; 576} 577