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