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