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
BitLeftShift(uint8_t x)43 static 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
63 typedef struct {
64 WifiScanResults *scanResults;
65 const char *ifName;
66 } WifiScanResultArg;
67
68 static int g_familyId = 0;
69
NoSeqCheck(struct nl_msg * msg,void * arg)70 static int NoSeqCheck(struct nl_msg *msg, void *arg)
71 {
72 (void)msg;
73 return NL_OK;
74 }
75
QcaWifiEventScanDoneProcess(const char * ifName,struct nlattr * data,size_t len)76 static 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
WifiEventVendorProcess(const char * ifName,struct nlattr ** attr)96 static 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
GetNlaDataScanResult(struct nlattr * attr[],int len,WifiScanResult * scanResult)129 static 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
DoGetScanResult(struct nlattr * attr[],int len,WifiScanResult * scanResult)172 static 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
WifiGetScanResultHandler(struct nl_msg * msg,void * arg)211 static 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
WifiEventScanResultProcess(const char * ifName)273 static 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
WifiEventScanAbortedProcess(const char * ifName)304 static 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
WifiEventDataFrameProcess(const char * ifName,struct nlattr ** attr)315 static 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
DoProcessEvent(const char * ifName,int cmd,struct nlattr ** attr)336 static 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
ProcessEvent(struct nl_msg * msg,void * arg)380 static 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
CreateCb(void)416 static 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
HandleEvent(struct nl_sock * sock)432 static 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
CtrlNoSeqCheck(struct nl_msg * msg,void * arg)450 static 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
CtrlSocketErrorHandler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)474 static 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
CtrlSocketFinishHandler(struct nl_msg * msg,void * arg)482 static 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
CtrlSocketAckHandler(struct nl_msg * msg,void * arg)490 static 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
HandleCtrlEvent(struct nl_sock * sock)498 static 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
EventThread(void * para)524 void *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