1 /*
2 * Copyright (C) 2021-2022 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 "wifi_wpa_hal.h"
17 #include <poll.h>
18 #include <unistd.h>
19 #include "securec.h"
20 #include "wifi_common_def.h"
21 #include "wifi_hal_callback.h"
22 #include "wifi_hal_common_func.h"
23 #include "wifi_hal_p2p_struct.h"
24 #include "wifi_hal_struct.h"
25 #include "wifi_p2p_hal.h"
26 #include "wifi_wpa_common.h"
27 #include "wifi_hal_sta_interface.h"
28 #include "wifi_hal_ap_interface.h"
29 #include "wifi_hal_p2p_interface.h"
30 #include "wifi_hal_module_manage.h"
31 #include "wifi_common_hal.h"
32
33 #ifndef __UT__
34 #include "wifi_log.h"
35 #endif
36
37 #ifdef __UT__
38 #define static
39 #define LOGI(...) ;
40 #define LOGD(...) ;
41 #define LOGE(...) ;
42 #endif
43
44 #undef LOG_TAG
45 #define LOG_TAG "WifiWpaHal"
46
47 #define WPA_TRY_CONNECT_TIMES 20
48 #define WPA_TRY_CONNECT_SLEEP_TIME (100 * 1000) /* 100ms */
49 #define WPA_CMD_BUF_LEN 256
50 #define WPA_CMD_REPLY_BUF_SMALL_LEN 64
51 #define P2P_SERVICE_INFO_FIRST_SECTION 1
52 #define P2P_SERVICE_INFO_SECOND_SECTION 2
53 #define P2P_SERVICE_INFO_THIRD_SECTION 3
54 #define P2P_SERVICE_DISC_REQ_ONE 1
55 #define P2P_SERVICE_DISC_REQ_TWO 2
56 #define P2P_SERVICE_DISC_REQ_THREE 3
57 #define P2P_SERVICE_DISC_REQ_FOUR 4
58 #define P2P_SERVICE_DISC_REQ_FIVE 5
59 #define WPA_CB_CONNECTED 1
60 #define WPA_CB_DISCONNECTED 2
61 #define WPA_CB_ASSOCIATING 3
62 #define WPA_CB_ASSOCIATED 4
63 #define WPS_EVENT_PBC_OVERLAP "WPS-OVERLAP-DETECTED PBC session overlap"
64 #define WPA_EVENT_BSSID_CHANGED "WPA-EVENT-BSSID-CHANGED "
65 #define WPA_EVENT_ASSOCIATING "Request association with "
66 #define WPA_EVENT_ASSOCIATED "Associated with "
67 #define REPLY_BUF_LENGTH 4096
68 #define CONNECTION_PWD_WRONG_STATUS 1
69 #define CONNECTION_FULL_STATUS 17
70 #define CONNECTION_REJECT_STATUS 37
71 #define WLAN_STATUS_AUTH_TIMEOUT 16
72 #define MAC_AUTH_RSP2_TIMEOUT 5201
73 #define MAC_AUTH_RSP4_TIMEOUT 5202
74 #define MAC_ASSOC_RSP_TIMEOUT 5203
75 #define SSID_EMPTY_LENGTH 1
76
77 #ifdef WPA_CTRL_IFACE_UNIX
78 #define WPA_CTRL_OPEN_IFNAME "@abstract:"CONFIG_ROOR_DIR"/sockets/wpa/wlan0"
79 #else
80 #define WPA_CTRL_OPEN_IFNAME ""CONFIG_ROOR_DIR"/sockets/wpa"
81 #endif // WPA_CTRL_IFACE_UNIX
82
83 static WifiWpaInterface *g_wpaInterface = NULL;
84
85 /* Detailed device string pattern from wpa_supplicant with WFD info
86 * Example: P2P-DEVICE-FOUND 00:18:6b:de:a3:6e p2p_dev_addr=00:18:6b:de:a3:6e
87 * pri_dev_type=1-0050F204-1 name='example p2p device' config_methods=0x188
88 * dev_capb=0x25 group_capab=0x9
89 * wfd_dev_info=0x000000000000 */
DealP2pFindInfo(char * buf)90 static void DealP2pFindInfo(char *buf)
91 {
92 if (buf == NULL || strlen(buf) < WIFI_MAC_LENGTH) {
93 return;
94 }
95 P2pDeviceInfo info = {0};
96 if (strncpy_s(info.srcAddress, sizeof(info.srcAddress), buf, WIFI_MAC_LENGTH) != EOK) {
97 return;
98 }
99 buf += WIFI_MAC_LENGTH + 1;
100 char *savedPtr = NULL;
101 char *s = strtok_r(buf, " ", &savedPtr);
102 while (s != NULL) {
103 WpaKeyValue retMsg = INIT_WPA_KEY_VALUE;
104 GetStrKeyVal(s, "=", &retMsg);
105 if (strncmp(retMsg.key, "p2p_dev_addr", strlen("p2p_dev_addr")) == 0) {
106 StrSafeCopy(info.p2pDeviceAddress, sizeof(info.p2pDeviceAddress), retMsg.value);
107 } else if (strncmp(retMsg.key, "pri_dev_type", strlen("pri_dev_type")) == 0) {
108 StrSafeCopy(info.primaryDeviceType, sizeof(info.primaryDeviceType), retMsg.value);
109 } else if (strncmp(retMsg.key, "config_methods", strlen("config_methods")) == 0) {
110 info.configMethods = Hex2Dec(retMsg.value);
111 } else if (strncmp(retMsg.key, "dev_capab", strlen("dev_capab")) == 0) {
112 info.deviceCapabilities = Hex2Dec(retMsg.value);
113 } else if (strncmp(retMsg.key, "group_capab", strlen("group_capab")) == 0) {
114 info.groupCapabilities = Hex2Dec(retMsg.value);
115 } else if (strncmp(retMsg.key, "wfd_dev_info", strlen("wfd_dev_info")) == 0) {
116 if (strlen(retMsg.value) != strlen("0x000000000000")) {
117 LOGD("Unexpected wfd device info, it's return 6 uint8 array convert to hex string!");
118 } else {
119 StrSafeCopy(info.wfdDeviceInfo, sizeof(info.wfdDeviceInfo), retMsg.value);
120 info.wfdLength = strlen(info.wfdDeviceInfo);
121 }
122 } else if (strncmp(retMsg.key, "name", strlen("name")) == 0) {
123 unsigned len = strlen(retMsg.value);
124 if (len == SSID_EMPTY_LENGTH || (len < sizeof(retMsg.value) - 1 && retMsg.value[len - 1] != '\'')) {
125 /* special deal: name='xxx xxx' || ' xxx' */
126 s = strtok_r(NULL, "\'", &savedPtr);
127 retMsg.value[len++] = ' ';
128 StrSafeCopy(retMsg.value + len, sizeof(retMsg.value) - len, s);
129 } /* can not deal with name=' x\' x'*/
130 TrimQuotationMark(retMsg.value, '\'');
131 StrSafeCopy(info.deviceName, sizeof(info.deviceName), retMsg.value);
132 }
133 s = strtok_r(NULL, " ", &savedPtr);
134 }
135 P2pHalCbDeviceFound(&info);
136 return;
137 }
138
DealP2pGoNegRequest(const char * buf)139 static void DealP2pGoNegRequest(const char *buf)
140 {
141 if (buf == NULL) {
142 return;
143 }
144 char macAddr[WIFI_MAC_LENGTH + 1] = {0};
145 if (strncpy_s(macAddr, sizeof(macAddr), buf, WIFI_MAC_LENGTH) != EOK) {
146 return;
147 }
148 const char *passId = strstr(buf, "dev_passwd_id=");
149 if (passId == NULL) {
150 LOGD("Not find dev_passwd_id");
151 return;
152 }
153 short passwordId = atoi(passId + strlen("dev_passwd_id="));
154 P2pHalCbGoNegotiationRequest(macAddr, passwordId);
155 return;
156 }
157
DealGroupStartInfo(char * buf)158 static void DealGroupStartInfo(char *buf)
159 {
160 if (buf == NULL) {
161 return;
162 }
163 P2pGroupInfo conf = {0};
164 if (memset_s(&conf, sizeof(conf), 0, sizeof(conf)) != EOK) {
165 return;
166 }
167 if (strstr(buf, "[PERSISTENT]") != NULL) {
168 conf.isPersistent = 1;
169 }
170
171 char *savedPtr = NULL;
172 char *token = strtok_r(buf, " ", &savedPtr);
173 while (token != NULL) {
174 WpaKeyValue retMsg = INIT_WPA_KEY_VALUE;
175 GetStrKeyVal(token, "=", &retMsg);
176 if (strncmp(retMsg.key, "GO", strlen("GO")) == 0) {
177 conf.isGo = 1;
178 } else if (strncmp(retMsg.key, "freq", strlen("freq")) == 0) {
179 conf.frequency = atoi(retMsg.value);
180 } else if (strncmp(retMsg.key, "go_dev_addr", strlen("go_dev_addr")) == 0) {
181 StrSafeCopy(conf.goDeviceAddress, sizeof(conf.goDeviceAddress), retMsg.value);
182 } else if (strncmp(retMsg.key, "p2p-", strlen("p2p-")) == 0) {
183 StrSafeCopy(conf.groupIfName, sizeof(conf.groupIfName), retMsg.key);
184 } else if (strncmp(retMsg.key, "psk", strlen("psk")) == 0) {
185 StrSafeCopy(conf.psk, sizeof(conf.psk), retMsg.value);
186 } else if (strncmp(retMsg.key, "ssid", strlen("ssid")) == 0 ||
187 strncmp(retMsg.key, "passphrase", strlen("passphrase")) == 0) {
188 TrimQuotationMark(retMsg.value, '\"');
189 if (strncmp(retMsg.key, "ssid", strlen("ssid")) == 0) {
190 StrSafeCopy(conf.ssid, sizeof(conf.ssid), retMsg.value);
191 PrintfDecode((u8 *)conf.ssid, sizeof(conf.ssid), conf.ssid);
192 } else {
193 StrSafeCopy(conf.passphrase, sizeof(conf.passphrase), retMsg.value);
194 }
195 }
196 token = strtok_r(NULL, " ", &savedPtr);
197 }
198 P2pHalCbGroupStarted(&conf);
199 return;
200 }
201
DealServiceDiscRespEvent(char * buf)202 static void DealServiceDiscRespEvent(char *buf)
203 {
204 if (buf == NULL) {
205 return;
206 }
207 P2pServDiscRespInfo info = {0};
208 if (memset_s(&info, sizeof(info), 0, sizeof(info)) != EOK) {
209 return;
210 }
211 char *savedPtr = NULL;
212 char *token = strtok_r(buf, " ", &savedPtr);
213 int index = 0;
214 while (token != NULL) {
215 if (index == P2P_SERVICE_INFO_FIRST_SECTION) {
216 if (strncpy_s(info.srcAddress, sizeof(info.srcAddress), token, strlen(token)) != EOK) {
217 free(info.tlvs);
218 info.tlvs = NULL;
219 return;
220 }
221 } else if (index == P2P_SERVICE_INFO_SECOND_SECTION) {
222 info.updateIndicator = atoi(token);
223 } else if (index == P2P_SERVICE_INFO_THIRD_SECTION) {
224 unsigned len = strlen(token) + 1;
225 if (info.tlvs != NULL || len > WPA_CMD_BUF_LEN) {
226 free(info.tlvs);
227 info.tlvs = NULL;
228 }
229 info.tlvs = (char *)calloc(len, sizeof(char));
230 if (info.tlvs == NULL || strncpy_s(info.tlvs, len, token, len - 1) != EOK) {
231 free(info.tlvs);
232 info.tlvs = NULL;
233 return;
234 }
235 }
236 index++;
237 token = strtok_r(NULL, " ", &savedPtr);
238 }
239 P2pHalCbServiceDiscoveryResponse(&info);
240 free(info.tlvs);
241 info.tlvs = NULL;
242 return;
243 }
244
DealP2pGroupRemove(const char * buf)245 static void DealP2pGroupRemove(const char *buf)
246 {
247 if (buf == NULL) {
248 return;
249 }
250 char groupIfname[WIFI_P2P_GROUP_IFNAME_LENGTH + 1] = {0};
251 const char *pos = strstr(buf, " ");
252 if (pos == NULL || pos - buf > WIFI_P2P_GROUP_IFNAME_LENGTH) {
253 LOGD("pos is %{public}s", ((pos == NULL) ? "NULL" : "bigger than ifname length"));
254 return;
255 }
256 if (strncpy_s(groupIfname, sizeof(groupIfname), buf, pos - buf) != EOK) {
257 return;
258 }
259 int flag = 0;
260 if (strstr(buf, "GO") != NULL) {
261 flag = 1;
262 }
263 P2pHalCbGroupRemoved(groupIfname, flag);
264 ReleaseWpaP2pGroupInterface(groupIfname); /* remove group interface */
265 return;
266 }
267
DealP2pConnectChanged(const char * buf,int type)268 static void DealP2pConnectChanged(const char *buf, int type)
269 {
270 if (buf == NULL) {
271 return;
272 }
273 char devAddr[WIFI_MAC_LENGTH + 1] = {0};
274 const char *pos = strstr(buf, "p2p_dev_addr=");
275 if (pos == NULL) {
276 return;
277 }
278 if (strncpy_s(devAddr, sizeof(devAddr), pos + strlen("p2p_dev_addr="), WIFI_MAC_LENGTH) != EOK) {
279 return;
280 }
281 char groupAddr[WIFI_MAC_LENGTH + 1] = {0};
282 if (strncpy_s(groupAddr, sizeof(groupAddr), buf, WIFI_MAC_LENGTH) != EOK) {
283 return;
284 }
285 P2pHalCbStaConnectState(devAddr, groupAddr, type);
286 return;
287 }
288
DealDeviceLostEvent(const char * buf)289 static void DealDeviceLostEvent(const char *buf)
290 {
291 if (buf == NULL) {
292 return;
293 }
294 const char *peeraddr = strstr(buf, "p2p_dev_addr=");
295 if (peeraddr == NULL) {
296 return;
297 }
298 peeraddr += strlen("p2p_dev_addr=");
299 char macAddr[WIFI_MAC_LENGTH + 1] = {0};
300 if (strncpy_s(macAddr, sizeof(macAddr), peeraddr, WIFI_MAC_LENGTH) != EOK) {
301 return;
302 }
303 P2pHalCbDeviceLost(macAddr);
304 return;
305 }
306
DealInvitationReceived(char * buf,int type)307 static void DealInvitationReceived(char *buf, int type)
308 {
309 if (buf == NULL) {
310 return;
311 }
312 P2pInvitationInfo info = {0};
313 if (memset_s(&info, sizeof(info), 0, sizeof(info)) != EOK) {
314 return;
315 }
316 info.type = type;
317 char *savedPtr = NULL;
318 char *token = strtok_r(buf, " ", &savedPtr);
319 while (token != NULL) {
320 WpaKeyValue retMsg = INIT_WPA_KEY_VALUE;
321 GetStrKeyVal(token, "=", &retMsg);
322 if (strncmp(retMsg.key, "sa", strlen("sa")) == 0) {
323 StrSafeCopy(info.srcAddress, sizeof(info.srcAddress), retMsg.value);
324 } else if (strncmp(retMsg.key, "persistent", strlen("persistent")) == 0) {
325 info.persistentNetworkId = atoi(retMsg.value);
326 } else if (strncmp(retMsg.key, "freq", strlen("freq")) == 0) {
327 info.operatingFrequency = atoi(retMsg.value);
328 } else if (strncmp(retMsg.key, "go_dev_addr", strlen("go_dev_addr")) == 0) {
329 StrSafeCopy(info.goDeviceAddress, sizeof(info.goDeviceAddress), retMsg.value);
330 } else if (strncmp(retMsg.key, "bssid", strlen("bssid")) == 0) {
331 StrSafeCopy(info.bssid, sizeof(info.bssid), retMsg.value);
332 }
333 token = strtok_r(NULL, " ", &savedPtr);
334 }
335 P2pHalCbInvitationReceived(&info);
336 return;
337 }
338
DealInvitationResultEvent(const char * buf)339 static void DealInvitationResultEvent(const char *buf)
340 {
341 if (buf == NULL) {
342 return;
343 }
344 const char *sta = strstr(buf, "status=");
345 if (sta == NULL) {
346 return;
347 }
348 int status = atoi(sta + strlen("status="));
349 const char *bssidpos = strstr(sta, " ");
350 if (bssidpos == NULL) {
351 return;
352 }
353 char macAddr[WIFI_MAC_LENGTH + 1] = {0};
354 if (strncpy_s(macAddr, sizeof(macAddr), bssidpos + 1, WIFI_MAC_LENGTH) != EOK) {
355 return;
356 }
357 P2pHalCbInvitationResult(macAddr, status);
358 return;
359 }
360
DealP2pGoNegotiationFailure(const char * buf)361 static void DealP2pGoNegotiationFailure(const char *buf)
362 {
363 if (buf == NULL) {
364 return;
365 }
366 const char *sta = strstr(buf, "status=");
367 if (sta == NULL) {
368 return;
369 }
370 int status = atoi(sta + strlen("status="));
371 P2pHalCbGoNegotiationFailure(status);
372 return;
373 }
374
DealP2pConnectFailed(const char * buf)375 static void DealP2pConnectFailed(const char *buf)
376 {
377 if (buf == NULL) {
378 return;
379 }
380 const char *bssidPos = strstr(buf, "bssid=");
381 if (bssidPos == NULL) {
382 LOGE("bssidPos is null!");
383 return;
384 }
385 bssidPos += strlen("bssid=");
386 char macAddr[WIFI_MAC_LENGTH + 1] = {0};
387 if (strncpy_s(macAddr, sizeof(macAddr), bssidPos, WIFI_MAC_LENGTH) != EOK) {
388 LOGE("strncpy_s failed!");
389 return;
390 }
391 const char *reaPos = strstr(buf, "reason=");
392 if (reaPos == NULL) {
393 LOGE("reaPos is null!");
394 return;
395 }
396 int reason = atoi(reaPos + strlen("reason="));
397 P2pHalCbP2pConnectFailed(macAddr, reason);
398 return;
399 }
400
DealP2pChannelSwitch(const char * buf)401 static void DealP2pChannelSwitch(const char *buf)
402 {
403 if (buf == NULL) {
404 return;
405 }
406 if (strstr(buf, "dfs=") != NULL) {
407 LOGE("return ap channel switch!");
408 return;
409 }
410 const char *freqPos = strstr(buf, "freq=");
411 if (freqPos == NULL) {
412 LOGE("freqPos is null!");
413 return;
414 }
415 int freq = atoi(freqPos + strlen("freq="));
416 LOGI("DealP2pChannelSwitch freq=%{public}d", freq);
417 P2pHalCbP2pChannelSwitch(freq);
418 return;
419 }
420
DealGroupFormationFailureEvent(const char * buf)421 static void DealGroupFormationFailureEvent(const char *buf)
422 {
423 if (buf == NULL) {
424 return;
425 }
426 char reason[WIFI_P2P_GROUP_IFNAME_LENGTH + 1] = {0};
427 char *reapos = strstr(buf, "reason=");
428 if (reapos != NULL) {
429 if (strncpy_s(reason, sizeof(reason), reapos + strlen("reason="), WIFI_P2P_GROUP_IFNAME_LENGTH) != EOK) {
430 return;
431 }
432 }
433 P2pHalCbGroupFormationFailure(reason);
434 return;
435 }
436
DealProvDiscPbcReqEvent(const char * buf,unsigned long length)437 static void DealProvDiscPbcReqEvent(const char *buf, unsigned long length)
438 {
439 if (buf == NULL || length < strlen(P2P_EVENT_PROV_DISC_PBC_REQ) + WIFI_MAC_LENGTH) {
440 return;
441 }
442 char macAddr[WIFI_MAC_LENGTH + 1] = {0};
443 const char *pos = buf + strlen(P2P_EVENT_PROV_DISC_PBC_REQ);
444 if (strncpy_s(macAddr, sizeof(macAddr), pos, WIFI_MAC_LENGTH) != EOK) {
445 return;
446 }
447 P2pHalCbProvisionDiscoveryPbcRequest(macAddr);
448 return;
449 }
450
DealProDiscPbcRespEvent(const char * buf,unsigned long length)451 static void DealProDiscPbcRespEvent(const char *buf, unsigned long length)
452 {
453 if (buf == NULL || length < strlen(P2P_EVENT_PROV_DISC_PBC_RESP) + WIFI_MAC_LENGTH) {
454 return;
455 }
456 char macAddr[WIFI_MAC_LENGTH + 1] = {0};
457 const char *pos = buf + strlen(P2P_EVENT_PROV_DISC_PBC_RESP);
458 if (strncpy_s(macAddr, sizeof(macAddr), pos, WIFI_MAC_LENGTH) != EOK) {
459 return;
460 }
461 P2pHalCbProvisionDiscoveryPbcResponse(macAddr);
462 return;
463 }
464
DealProDiscEnterPinEvent(const char * buf,unsigned long length)465 static void DealProDiscEnterPinEvent(const char *buf, unsigned long length)
466 {
467 if (buf == NULL || length < strlen(P2P_EVENT_PROV_DISC_ENTER_PIN) + WIFI_MAC_LENGTH) {
468 return;
469 }
470 char macAddr[WIFI_MAC_LENGTH + 1] = {0};
471 const char *pos = buf + strlen(P2P_EVENT_PROV_DISC_ENTER_PIN);
472 if (strncpy_s(macAddr, sizeof(macAddr), pos, WIFI_MAC_LENGTH) != EOK) {
473 return;
474 }
475 P2pHalCbProvisionDiscoveryEnterPin(macAddr);
476 return;
477 }
478
DealProvDiscShowPinEvent(const char * buf,unsigned long length)479 static void DealProvDiscShowPinEvent(const char *buf, unsigned long length)
480 {
481 if (buf == NULL || length < strlen(P2P_EVENT_PROV_DISC_SHOW_PIN) + WIFI_MAC_LENGTH + 1 + WIFI_PIN_CODE_LENGTH) {
482 return;
483 }
484 const char *p = buf + strlen(P2P_EVENT_PROV_DISC_SHOW_PIN);
485 char macAddr[WIFI_MAC_LENGTH + 1] = {0};
486 char pinCode[WIFI_PIN_CODE_LENGTH + 1] = {0};
487 if (strncpy_s(macAddr, sizeof(macAddr), p, WIFI_MAC_LENGTH) != EOK) {
488 return;
489 }
490 p += WIFI_MAC_LENGTH + 1;
491 if (strncpy_s(pinCode, sizeof(pinCode), p, WIFI_PIN_CODE_LENGTH) != EOK) {
492 return;
493 }
494 P2pHalCbProvisionDiscoveryShowPin(macAddr, pinCode);
495 return;
496 }
497
DealP2pServDiscReqEvent(char * buf)498 static void DealP2pServDiscReqEvent(char *buf)
499 {
500 if (buf == NULL) {
501 return;
502 }
503 P2pServDiscReqInfo info;
504 if (memset_s(&info, sizeof(info), 0, sizeof(info)) != EOK) {
505 return;
506 }
507 char *savedPtr = NULL;
508 char *token = strtok_r(buf, " ", &savedPtr);
509 int index = 0;
510 while (token != NULL && index <= P2P_SERVICE_DISC_REQ_FIVE) {
511 if (index == P2P_SERVICE_DISC_REQ_ONE) {
512 info.freq = atoi(token);
513 } else if (index == P2P_SERVICE_DISC_REQ_TWO) {
514 if (strncpy_s(info.mac, sizeof(info.mac), token, strlen(token)) != EOK) {
515 free(info.tlvs);
516 info.tlvs = NULL;
517 return;
518 }
519 } else if (index == P2P_SERVICE_DISC_REQ_THREE) {
520 info.dialogToken = atoi(token);
521 } else if (index == P2P_SERVICE_DISC_REQ_FOUR) {
522 info.updateIndic = atoi(token);
523 } else if (index == P2P_SERVICE_DISC_REQ_FIVE) {
524 unsigned len = strlen(token) + 1;
525 if (info.tlvs != NULL || len > WPA_CMD_BUF_LEN) {
526 free(info.tlvs);
527 info.tlvs = NULL;
528 }
529 info.tlvs = (char *)calloc(len, sizeof(char));
530 if (info.tlvs == NULL || strncpy_s(info.tlvs, len, token, len - 1) != EOK) {
531 free(info.tlvs);
532 info.tlvs = NULL;
533 return;
534 }
535 }
536 token = strtok_r(NULL, " ", &savedPtr);
537 index++;
538 }
539 P2pHalCbServDiscReq(&info);
540 free(info.tlvs);
541 info.tlvs = NULL;
542 return;
543 }
544
DealP2pInterfaceCreated(const char * buf)545 static void DealP2pInterfaceCreated(const char *buf)
546 {
547 int type;
548 char ifName[WIFI_IFACE_NAME_MAXLEN] = {0};
549 if (strncmp(buf, "GO ", strlen("GO ")) == 0) {
550 type = 1;
551 } else if (strncmp(buf, "GC ", strlen("GC ")) == 0) {
552 type = 0;
553 } else {
554 LOGE("p2p interface created invalid msg %{public}s", buf);
555 return;
556 }
557
558 const char *pos = buf + strlen("GO "); // GO and GC have same length
559 if (strlen(pos) >= WIFI_IFACE_NAME_MAXLEN || strlen(pos) == 0) {
560 LOGE("p2p interface created invalid ifname len %{public}zu", strlen(pos));
561 return;
562 }
563 if (strncpy_s(ifName, sizeof(ifName), pos, strlen(pos)) != EOK) {
564 return;
565 }
566 P2pHalCbP2pIfaceCreated(ifName, type);
567 }
568
DealWpaP2pCallBackSubFun(char * p)569 static int DealWpaP2pCallBackSubFun(char *p)
570 {
571 if (p == NULL) {
572 return -1;
573 }
574 if (strncmp(p, P2P_EVENT_DEVICE_FOUND, strlen(P2P_EVENT_DEVICE_FOUND)) == 0) {
575 DealP2pFindInfo(p + strlen(P2P_EVENT_DEVICE_FOUND));
576 } else if (strncmp(p, P2P_EVENT_DEVICE_LOST, strlen(P2P_EVENT_DEVICE_LOST)) == 0) {
577 DealDeviceLostEvent(p);
578 } else if (strncmp(p, P2P_EVENT_GO_NEG_REQUEST, strlen(P2P_EVENT_GO_NEG_REQUEST)) == 0) {
579 DealP2pGoNegRequest(p + strlen(P2P_EVENT_GO_NEG_REQUEST));
580 } else if (strncmp(p, P2P_EVENT_GO_NEG_SUCCESS, strlen(P2P_EVENT_GO_NEG_SUCCESS)) == 0) {
581 P2pHalCbGoNegotiationSuccess();
582 } else if (strncmp(p, P2P_EVENT_GO_NEG_FAILURE, strlen(P2P_EVENT_GO_NEG_FAILURE)) == 0) {
583 DealP2pGoNegotiationFailure(p);
584 } else if (strncmp(p, P2P_EVENT_INVITATION_RECEIVED, strlen(P2P_EVENT_INVITATION_RECEIVED)) == 0) {
585 DealInvitationReceived(p, 0);
586 } else if (strncmp(p, P2P_EVENT_INVITATION_ACCEPTED, strlen(P2P_EVENT_INVITATION_ACCEPTED)) == 0) {
587 DealInvitationReceived(p, 1);
588 } else if (strncmp(p, P2P_EVENT_INVITATION_RESULT, strlen(P2P_EVENT_INVITATION_RESULT)) == 0) {
589 DealInvitationResultEvent(p);
590 } else if (strncmp(p, P2P_EVENT_GROUP_FORMATION_SUCCESS, strlen(P2P_EVENT_GROUP_FORMATION_SUCCESS)) == 0) {
591 P2pHalCbGroupFormationSuccess();
592 } else if (strncmp(p, P2P_EVENT_GROUP_FORMATION_FAILURE, strlen(P2P_EVENT_GROUP_FORMATION_FAILURE)) == 0) {
593 DealGroupFormationFailureEvent(p);
594 } else if (strncmp(p, P2P_EVENT_GROUP_STARTED, strlen(P2P_EVENT_GROUP_STARTED)) == 0) {
595 DealGroupStartInfo(p);
596 } else if (strncmp(p, P2P_EVENT_GROUP_REMOVED, strlen(P2P_EVENT_GROUP_REMOVED)) == 0) {
597 DealP2pGroupRemove(p + strlen(P2P_EVENT_GROUP_REMOVED));
598 } else if (strncmp(p, P2P_INTERFACE_CREATED, strlen(P2P_INTERFACE_CREATED)) == 0) {
599 DealP2pInterfaceCreated(p + strlen(P2P_INTERFACE_CREATED));
600 } else if (strncmp(p, CTRL_EVENT_DISCONNECTED, strlen(CTRL_EVENT_DISCONNECTED)) == 0) {
601 DealP2pConnectFailed(p);
602 } else if (strncmp(p, CTRL_EVENT_CHANNEL_SWITCH, strlen(CTRL_EVENT_CHANNEL_SWITCH)) == 0) {
603 DealP2pChannelSwitch(p);
604 } else {
605 return 1;
606 }
607 return 0;
608 }
609
WpaP2pCallBackFunc(char * p)610 static int WpaP2pCallBackFunc(char *p)
611 {
612 if (p == NULL) {
613 LOGI("recv notify message is NULL");
614 return -1;
615 }
616 LOGD("wpa p2p callback p :%{private}s!", p);
617 if (strncmp(p, P2P_EVENT_PROV_DISC_PBC_REQ, strlen(P2P_EVENT_PROV_DISC_PBC_REQ)) == 0) {
618 DealProvDiscPbcReqEvent(p, strlen(p));
619 } else if (strncmp(p, P2P_EVENT_PROV_DISC_PBC_RESP, strlen(P2P_EVENT_PROV_DISC_PBC_RESP)) == 0) {
620 DealProDiscPbcRespEvent(p, strlen(p));
621 } else if (strncmp(p, P2P_EVENT_PROV_DISC_ENTER_PIN, strlen(P2P_EVENT_PROV_DISC_ENTER_PIN)) == 0) {
622 DealProDiscEnterPinEvent(p, strlen(p));
623 } else if (strncmp(p, P2P_EVENT_PROV_DISC_SHOW_PIN, strlen(P2P_EVENT_PROV_DISC_SHOW_PIN)) == 0) {
624 DealProvDiscShowPinEvent(p, strlen(p));
625 } else if (strncmp(p, P2P_EVENT_FIND_STOPPED, strlen(P2P_EVENT_FIND_STOPPED)) == 0) {
626 P2pHalCbFindStopped();
627 } else if (strncmp(p, P2P_EVENT_SERV_DISC_RESP, strlen(P2P_EVENT_SERV_DISC_RESP)) == 0) {
628 DealServiceDiscRespEvent(p);
629 } else if (strncmp(p, P2P_EVENT_PROV_DISC_FAILURE, strlen(P2P_EVENT_PROV_DISC_FAILURE)) == 0) {
630 P2pHalCbProvisionDiscoveryFailure();
631 } else if (strncmp(p, AP_STA_DISCONNECTED, strlen(AP_STA_DISCONNECTED)) == 0) {
632 DealP2pConnectChanged(p + strlen(AP_STA_DISCONNECTED), 0);
633 } else if (strncmp(p, AP_STA_CONNECTED, strlen(AP_STA_CONNECTED)) == 0) {
634 DealP2pConnectChanged(p + strlen(AP_STA_CONNECTED), 1);
635 } else if (strncmp(p, P2P_EVENT_SERV_DISC_REQ, strlen(P2P_EVENT_SERV_DISC_REQ)) == 0) {
636 DealP2pServDiscReqEvent(p);
637 } else {
638 if (DealWpaP2pCallBackSubFun(p) != 0) {
639 return 1;
640 }
641 }
642 return 0;
643 }
ParseAuthReject(const char * p)644 static void ParseAuthReject(const char *p)
645 {
646 char *connectionStatus = strstr(p, "status_code=");
647 if (connectionStatus != NULL) {
648 connectionStatus += strlen("status_code=");
649 int status = atoi(connectionStatus);
650 if (status == CONNECTION_PWD_WRONG_STATUS) {
651 WifiHalCbNotifyWrongKey(1);
652 } else if (status == CONNECTION_FULL_STATUS) {
653 WifiHalCbNotifyConnectionFull(status);
654 } else if (status == CONNECTION_REJECT_STATUS ||
655 status == WLAN_STATUS_AUTH_TIMEOUT ||
656 status == MAC_AUTH_RSP2_TIMEOUT ||
657 status == MAC_AUTH_RSP4_TIMEOUT ||
658 status == MAC_ASSOC_RSP_TIMEOUT) {
659 WifiHalCbNotifyConnectionReject(status);
660 }
661 }
662 }
663
ParseAssocReject(const char * p)664 static void ParseAssocReject(const char *p)
665 {
666 char *connectionStatus = strstr(p, "status_code=");
667 if (connectionStatus != NULL) {
668 connectionStatus += strlen("status_code=");
669 int status = atoi(connectionStatus);
670 if (status == CONNECTION_FULL_STATUS) {
671 WifiHalCbNotifyConnectionFull(status);
672 } else if (status == CONNECTION_REJECT_STATUS ||
673 status == WLAN_STATUS_AUTH_TIMEOUT ||
674 status == MAC_AUTH_RSP2_TIMEOUT ||
675 status == MAC_AUTH_RSP4_TIMEOUT ||
676 status == MAC_ASSOC_RSP_TIMEOUT ||
677 status == CONNECTION_PWD_WRONG_STATUS) {
678 WifiHalCbNotifyConnectionReject(status);
679 }
680 }
681 }
682
WpaCallBackFuncTwo(const char * p)683 static void WpaCallBackFuncTwo(const char *p)
684 {
685 if (p == NULL) {
686 LOGI("recv notify message is NULL");
687 return;
688 }
689 if (strncmp(p, WPA_EVENT_STATE_CHANGE, strlen(WPA_EVENT_STATE_CHANGE)) == 0) { /* wpa-state change */
690 char *pstate = strstr(p, "state=");
691 if (pstate != NULL) {
692 pstate += strlen("state=");
693 WifiHalCbNotifyWpaStateChange(atoi(pstate));
694 }
695 } else if (strncmp(p, WPA_EVENT_TEMP_DISABLED, strlen(WPA_EVENT_TEMP_DISABLED)) == 0) { /* Wrong Key */
696 if (strstr(p, "reason=WRONG_KEY") != NULL || strstr(p, "reason=AUTH_FAILED") != NULL) {
697 WifiHalCbNotifyWrongKey(1);
698 }
699 } else if (strncmp(p, WPS_EVENT_PBC_OVERLAP, strlen(WPS_EVENT_PBC_OVERLAP)) == 0) { /* wps_pbc_overlap */
700 WifiHalCbNotifyWpsOverlap(1);
701 } else if (strncmp(p, WPS_EVENT_TIMEOUT, strlen(WPS_EVENT_TIMEOUT)) == 0) {
702 WifiHalCbNotifyWpsTimeOut(1);
703 } else if (strncmp(p, WPA_EVENT_AUTH_REJECT, strlen(WPA_EVENT_AUTH_REJECT)) == 0) { /* connection full */
704 ParseAuthReject(p);
705 } else if (strncmp(p, WPA_EVENT_ASSOC_REJECT, strlen(WPA_EVENT_ASSOC_REJECT)) == 0) {
706 ParseAssocReject(p);
707 } else if (strncmp(p, WPA_EVENT_ASSOCIATING, strlen(WPA_EVENT_ASSOCIATING)) == 0) {
708 char *pBssid = strstr(p, WPA_EVENT_ASSOCIATING);
709 if (pBssid == NULL) {
710 return;
711 }
712 pBssid += strlen(WPA_EVENT_ASSOCIATING);
713 WifiHalCbNotifyConnectChanged(WPA_CB_ASSOCIATING, -1, pBssid);
714 } else if (strncmp(p, WPA_EVENT_ASSOCIATED, strlen(WPA_EVENT_ASSOCIATED)) == 0) {
715 char *pBssid = strstr(p, WPA_EVENT_ASSOCIATED);
716 if (pBssid == NULL) {
717 return;
718 }
719 pBssid += strlen(WPA_EVENT_ASSOCIATED);
720 WifiHalCbNotifyConnectChanged(WPA_CB_ASSOCIATED, -1, pBssid);
721 }
722 return;
723 }
724
WpaCallBackFunc(const char * p)725 static void WpaCallBackFunc(const char *p)
726 {
727 if (p == NULL) {
728 LOGI("recv notify message is NULL");
729 return;
730 }
731 if (strncmp(p, WPA_EVENT_SCAN_RESULTS, strlen(WPA_EVENT_SCAN_RESULTS)) == 0) {
732 WifiHalCbNotifyScanEnd(STA_CB_SCAN_OVER_OK);
733 } else if (strncmp(p, WPA_EVENT_SCAN_FAILED, strlen(WPA_EVENT_SCAN_FAILED)) == 0) {
734 WifiHalCbNotifyScanEnd(STA_CB_SCAN_FAILED);
735 } else if (strncmp(p, WPA_EVENT_CONNECTED, strlen(WPA_EVENT_CONNECTED)) == 0) { /* Connection notification */
736 char *pid = strstr(p, "id=");
737 char *pMacPos = strstr(p, "Connection to ");
738 if (pid == NULL || pMacPos == NULL) {
739 return;
740 }
741 pid += strlen("id=");
742 pMacPos += strlen("Connection to ");
743 int id = atoi(pid);
744 if (id < 0) {
745 id = -1;
746 }
747 WifiHalCbNotifyConnectChanged(WPA_CB_CONNECTED, id, pMacPos);
748 } else if (strncmp(p, WPA_EVENT_DISCONNECTED, strlen(WPA_EVENT_DISCONNECTED)) == 0) { /* Disconnection */
749 char *pBssid = strstr(p, "bssid=");
750 if (pBssid == NULL) {
751 return;
752 }
753 pBssid += strlen("bssid=");
754 char *reasonPos = strstr(p, "reason=");
755 int reasonCode = -1;
756 if (reasonPos != NULL) {
757 reasonPos += strlen("reason=");
758 int ret = sscanf_s(reasonPos, "%d", &reasonCode);
759 if (ret < 0) {
760 LOGE("reasonCode failed!");
761 return;
762 }
763 }
764 WifiHalCbNotifyDisConnectReason(reasonCode, pBssid);
765 WifiHalCbNotifyConnectChanged(WPA_CB_DISCONNECTED, reasonCode, pBssid);
766 /* bssid changed event */
767 } else if (strncmp(p, WPA_EVENT_BSSID_CHANGED, strlen(WPA_EVENT_BSSID_CHANGED)) == 0) {
768 LOGI("Reveive WPA_EVENT_BSSID_CHANGED notify event");
769 char *pBssid = strstr(p, "BSSID=");
770 if (pBssid == NULL) {
771 LOGE("NO bssid find!");
772 return;
773 }
774 pBssid += strlen("BSSID=");
775 char *pReason = strstr(p, "REASON=");
776 if (pReason == NULL) {
777 LOGE("NO reason find!");
778 return;
779 }
780 pReason += strlen("REASON=");
781 WifiHalCbNotifyBssidChanged(pReason, pBssid);
782 } else {
783 WpaCallBackFuncTwo(p);
784 }
785 }
786
MyWpaCtrlPending(struct wpa_ctrl * ctrl)787 static int MyWpaCtrlPending(struct wpa_ctrl *ctrl)
788 {
789 if (ctrl == NULL) {
790 return -1;
791 }
792 struct pollfd pfd;
793 if (memset_s(&pfd, sizeof(pfd), 0, sizeof(pfd)) != EOK) {
794 return -1;
795 }
796 pfd.fd = wpa_ctrl_get_fd(ctrl);
797 pfd.events = POLLIN;
798 int ret = poll(&pfd, 1, 100); /* 100 ms */
799 if (ret < 0) {
800 LOGE("poll failed! errno = %{public}d", errno);
801 if (errno == EINTR) {
802 return 0;
803 }
804 return -1;
805 }
806 if (ret == 0) {
807 return 0;
808 }
809 return 1;
810 }
811
StopWpaSuppilicant(ModuleInfo * p)812 static void StopWpaSuppilicant(ModuleInfo *p)
813 {
814 if (p == NULL) {
815 return;
816 }
817 LOGI("p->referenceCount = %{public}d.", p->referenceCount);
818 if (p->referenceCount > 1) {
819 if (P2pStop() != WIFI_HAL_SUCCESS) {
820 LOGE("P2p stop failed.");
821 }
822 if (Stop() != WIFI_HAL_SUCCESS) {
823 LOGE("Sta stop failed.");
824 }
825 } else {
826 if (Stop() != WIFI_HAL_SUCCESS) {
827 LOGE("Sta stop failed.");
828 }
829 }
830 }
831
StopWpaSoftAp(ModuleInfo * p)832 static void StopWpaSoftAp(ModuleInfo *p)
833 {
834 if (p == NULL) {
835 return;
836 }
837
838 int apCount = p->referenceCount;
839 int stopCount = 0;
840 while (stopCount < apCount) {
841 if (StopSoftAp(stopCount) != WIFI_HAL_SUCCESS) {
842 LOGE("Ap instance %{public}d stop failed.", stopCount);
843 }
844 stopCount += 1;
845 }
846 }
847
RecoverWifiProcess(void * arg)848 static void *RecoverWifiProcess(void *arg)
849 {
850 ModuleInfo *p = NULL;
851 p = GetStartedModule();
852 if (p == NULL) {
853 LOGI("No wpa process need to recover.");
854 return NULL;
855 }
856
857 if (strcmp(p->szModuleName, WPA_SUPPLICANT_NAME) == 0) {
858 StopWpaSuppilicant(p);
859 } else if (strcmp(p->szModuleName, WPA_HOSTAPD_NAME) == 0) {
860 StopWpaSoftAp(p);
861 }
862
863 exit(0);
864 return NULL;
865 }
866
RecoverWifiThread(void)867 static void RecoverWifiThread(void)
868 {
869 LOGI("wpa process stoped, ready to recover it!");
870 pthread_t tid;
871 if (pthread_create(&tid, NULL, RecoverWifiProcess, NULL) != 0) {
872 LOGE("create wpa restart thread failed!");
873 }
874 pthread_detach(tid);
875 }
876
WpaReceiveCallback(void * arg)877 static void *WpaReceiveCallback(void *arg)
878 {
879 if (arg == NULL) {
880 return NULL;
881 }
882 char staIface[] = "IFNAME=wlan";
883 char p2pIface[] = "IFNAME=p2p";
884 char chbaIface[] = "IFNAME=chba";
885 WifiWpaInterface *pWpa = arg;
886 char *buf = (char *)calloc(REPLY_BUF_LENGTH, sizeof(char));
887 if (buf == NULL) {
888 LOGE("In wpa deal receive message thread, failed to calloc buff!");
889 return NULL;
890 }
891 while (pWpa->threadRunFlag) {
892 int ret = MyWpaCtrlPending(pWpa->wpaCtrl.pRecv);
893 if (ret < 0) {
894 LOGE("thread get event message failed!");
895 break;
896 } else if (ret == 0) {
897 continue;
898 }
899 if (memset_s(buf, REPLY_BUF_LENGTH, 0, REPLY_BUF_LENGTH) != EOK) {
900 LOGE("thread clear buffer cache failed!");
901 break;
902 }
903 size_t len = REPLY_BUF_LENGTH - 1;
904 ret = wpa_ctrl_recv(pWpa->wpaCtrl.pRecv, buf, &len);
905 if (ret < 0) {
906 LOGE("thread read event message failed!");
907 break;
908 }
909 if (len <= 0) {
910 continue;
911 }
912 LOGD("wpa recv buf: %{public}s!", buf);
913 /* Message format: IFNAME=wlan0 <priority>EventType params... */
914 char *p = strchr(buf, '>');
915 if (p == NULL) {
916 p = buf;
917 } else {
918 p++;
919 }
920 if (strncmp(p, WPA_EVENT_TERMINATING, strlen(WPA_EVENT_TERMINATING)) == 0) {
921 LOGI("=====================WPA_EVENT_TERMINATING=======================");
922 RecoverWifiThread();
923 break;
924 }
925 char *iface = strstr(buf, "IFNAME=");
926 if (iface == NULL) {
927 /* if 'IFNAME=' is not reported */
928 if (strstr(p, "chba0") != NULL) {
929 HalCallbackNotify(p);
930 continue;
931 }
932 if (WpaP2pCallBackFunc(p) == 0) {
933 continue;
934 }
935 WpaCallBackFunc(p);
936 continue;
937 }
938 if (strncmp(iface, p2pIface, strlen(p2pIface)) == 0) {
939 if (WpaP2pCallBackFunc(p) == 0) {
940 continue;
941 }
942 }
943 if (strncmp(iface, staIface, strlen(staIface)) == 0) {
944 WpaCallBackFunc(p);
945 }
946 if (strncmp(iface, chbaIface, strlen(chbaIface)) == 0) {
947 HalCallbackNotify(p);
948 }
949 }
950 free(buf);
951 buf = NULL;
952 LOGI("=====================thread exit=======================");
953 return NULL;
954 }
955
WpaCliConnect(WifiWpaInterface * p)956 static int WpaCliConnect(WifiWpaInterface *p)
957 {
958 LOGI("Wpa connect start.");
959 if (p == NULL) {
960 LOGE("Wpa connect parameter error.");
961 return -1;
962 }
963 if (p->wpaCtrl.pSend != NULL) {
964 LOGE("Wpa is already connected.");
965 return 0;
966 }
967 int count = WPA_TRY_CONNECT_TIMES;
968 while (count-- > 0) {
969 int ret = InitWpaCtrl(&p->wpaCtrl, WPA_CTRL_OPEN_IFNAME);
970 if (ret == 0) {
971 LOGI("Global wpa interface connect successfully!");
972 break;
973 } else {
974 LOGE("Init wpaCtrl failed: %{public}d", ret);
975 }
976 usleep(WPA_TRY_CONNECT_SLEEP_TIME);
977 }
978 if (count <= 0) {
979 return -1;
980 }
981 p->threadRunFlag = 1;
982 if (pthread_create(&p->tid, NULL, WpaReceiveCallback, p) != 0) {
983 p->threadRunFlag = 0;
984 ReleaseWpaCtrl(&p->wpaCtrl);
985 LOGE("Create monitor thread failed!");
986 return -1;
987 }
988 pthread_setname_np(p->tid, "WpaCBThread");
989 LOGI("Wpa connect finish.");
990 return 0;
991 }
992
WpaCliClose(WifiWpaInterface * p)993 static void WpaCliClose(WifiWpaInterface *p)
994 {
995 if (p->tid != 0) {
996 p->threadRunFlag = 0;
997 pthread_join(p->tid, NULL);
998 p->tid = 0;
999 }
1000 ReleaseWpaCtrl(&p->wpaCtrl);
1001 return;
1002 }
1003
WpaCliAddIface(WifiWpaInterface * p,const AddInterfaceArgv * argv,bool isWpaAdd)1004 static int WpaCliAddIface(WifiWpaInterface *p, const AddInterfaceArgv *argv, bool isWpaAdd)
1005 {
1006 if (p == NULL || argv == NULL) {
1007 return -1;
1008 }
1009 WpaIfaceInfo *info = p->ifaces;
1010 while (info != NULL) {
1011 if (strcmp(info->name, argv->name) == 0) {
1012 return 0;
1013 }
1014 info = info->next;
1015 }
1016 info = (WpaIfaceInfo *)calloc(1, sizeof(WpaIfaceInfo));
1017 if (info == NULL) {
1018 return -1;
1019 }
1020 StrSafeCopy(info->name, sizeof(info->name), argv->name);
1021 char cmd[WPA_CMD_BUF_LEN] = {0};
1022 char buf[WPA_CMD_REPLY_BUF_SMALL_LEN] = {0};
1023 LOGI("Add interface start.");
1024 if (isWpaAdd && (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "INTERFACE_ADD %s\t%s",
1025 argv->name, argv->confName) < 0 || WpaCliCmd(cmd, buf, sizeof(buf)) != 0)) {
1026 free(info);
1027 info = NULL;
1028 LOGI("WpaCliAddIface failed, cmd: %{public}s, buf: %{public}s", cmd, buf);
1029 return -1;
1030 }
1031 LOGI("Add interface finish, cmd: %{public}s, buf: %{public}s", cmd, buf);
1032 info->next = p->ifaces;
1033 p->ifaces = info;
1034 return 0;
1035 }
1036
WpaCliRemoveIface(WifiWpaInterface * p,const char * name)1037 static int WpaCliRemoveIface(WifiWpaInterface *p, const char *name)
1038 {
1039 if (p == NULL || name == NULL) {
1040 return -1;
1041 }
1042 LOGI("Remove interface: %{public}s", name);
1043 WpaIfaceInfo *prev = NULL;
1044 WpaIfaceInfo *info = p->ifaces;
1045 while (info != NULL) {
1046 if (strcmp(info->name, name) == 0) {
1047 break;
1048 }
1049 prev = info;
1050 info = info->next;
1051 }
1052 if (info == NULL) {
1053 return 0;
1054 }
1055 char cmd[WPA_CMD_BUF_LEN] = {0};
1056 char buf[WPA_CMD_REPLY_BUF_SMALL_LEN] = {0};
1057 if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "INTERFACE_REMOVE %s", name) < 0 ||
1058 WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
1059 return -1;
1060 }
1061 if (prev == NULL) {
1062 p->ifaces = info->next;
1063 } else {
1064 prev->next = info->next;
1065 }
1066 free(info);
1067 info = NULL;
1068 return 0;
1069 }
1070
WpaCliWpaTerminate(void)1071 static int WpaCliWpaTerminate(void)
1072 {
1073 LOGI("Enter WpaCliWpaTerminate");
1074 char cmd[WPA_CMD_BUF_LEN] = {0};
1075 char buf[WPA_CMD_REPLY_BUF_SMALL_LEN] = {0};
1076 if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "TERMINATE") < 0) {
1077 LOGE("WpaCliWpaTerminate, snprintf err");
1078 return -1;
1079 }
1080 return WpaCliCmd(cmd, buf, sizeof(buf));
1081 }
1082
GetWifiWapGlobalInterface(void)1083 WifiWpaInterface *GetWifiWapGlobalInterface(void)
1084 {
1085 if (g_wpaInterface != NULL) {
1086 return g_wpaInterface;
1087 }
1088 g_wpaInterface = (WifiWpaInterface *)calloc(1, sizeof(WifiWpaInterface));
1089 if (g_wpaInterface == NULL) {
1090 LOGE("Failed to create wpa interface!");
1091 return NULL;
1092 }
1093 g_wpaInterface->wpaCliConnect = WpaCliConnect;
1094 g_wpaInterface->wpaCliClose = WpaCliClose;
1095 g_wpaInterface->wpaCliAddIface = WpaCliAddIface;
1096 g_wpaInterface->wpaCliRemoveIface = WpaCliRemoveIface;
1097 g_wpaInterface->wpaCliTerminate = WpaCliWpaTerminate;
1098 return g_wpaInterface;
1099 }
1100
ReleaseWpaGlobalInterface(void)1101 void ReleaseWpaGlobalInterface(void)
1102 {
1103 if (g_wpaInterface == NULL) {
1104 return;
1105 }
1106 WpaIfaceInfo *p = g_wpaInterface->ifaces;
1107 while (p != NULL) {
1108 WpaIfaceInfo *q = p->next;
1109 free(p);
1110 p = q;
1111 }
1112 WpaCliClose(g_wpaInterface);
1113 free(g_wpaInterface);
1114 g_wpaInterface = NULL;
1115 }
1116
GetWpaCtrl(void)1117 WpaCtrl *GetWpaCtrl(void)
1118 {
1119 if (g_wpaInterface == NULL) {
1120 return NULL;
1121 }
1122 return &g_wpaInterface->wpaCtrl;
1123 }
1124