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