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