1 /*
2  * Copyright (C) 2024 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 "wpa_supplicant_hal.h"
17 #include <poll.h>
18 #include <pthread.h>
19 #include <stdbool.h>
20 #include <hdf_log.h>
21 #include "hdi_wpa_common.h"
22 #include "securec.h"
23 #include "utils/common.h"
24 #include "wpa_hdi_util.h"
25 
26 #undef LOG_TAG
27 #define LOG_TAG "HdiWpaStaHal"
28 
29 #define FAIL_BUSY 2
30 
31 #define COLUMN_INDEX_ZERO 0
32 #define COLUMN_INDEX_ONE 1
33 #define COLUMN_INDEX_TWO 2
34 #define COLUMN_INDEX_THREE 3
35 #define COLUMN_INDEX_FOUR 4
36 #define COLUMN_INDEX_FIVE 5
37 
38 #define FAIL_PBC_OVERLAP_RETUEN 3
39 #define CMD_BUFFER_SIZE 2148
40 #define MAX_NAME_LEN 12
41 #define REPLY_BUF_LENGTH (4096 * 10)
42 #define REPLY_BUF_SMALL_LENGTH 64
43 #define CMD_FREQ_MAX_LEN 8
44 #define STA_NO_LEN 2
45 #define FREQ_MAX_SIZE 100
46 #define CMD_BUFFER_MIN_SIZE 15
47 
48 const int WPA_QUOTATION_MARKS_FLAG_YES = 0;
49 const int WPA_QUOTATION_MARKS_FLAG_NO = 1;
50 
51 const unsigned int HT_OPER_EID = 61;
52 const unsigned int VHT_OPER_EID = 192;
53 const unsigned int EXT_EXIST_EID = 255;
54 const unsigned int EXT_HE_OPER_EID = 36;
55 const unsigned int HE_OPER_BASIC_LEN = 6;
56 const unsigned int VHT_OPER_INFO_EXTST_MASK = 0x40;
57 const unsigned int GHZ_HE_INFO_EXIST_MASK_6 = 0x02;
58 const unsigned int GHZ_HE_WIDTH_MASK_6 = 0x03;
59 const unsigned int BSS_EXIST_MASK = 0x80;
60 const unsigned int VHT_OPER_INFO_BEGIN_INDEX = 6;
61 const unsigned int VHT_INFO_SIZE = 3;
62 const unsigned int HT_INFO_SIZE = 3;
63 const unsigned int UINT8_MASK = 0xFF;
64 const unsigned int UNSPECIFIED = -1;
65 const unsigned int MAX_INFO_ELEMS_SIZE = 256;
66 const unsigned int SUPP_RATES_SIZE = 8;
67 const unsigned int EXT_SUPP_RATES_SIZE = 4;
68 const unsigned int SUPPORTED_RATES_EID = 1;
69 const unsigned int ERP_EID = 42;
70 const unsigned int EXT_SUPPORTED_RATES_EID = 50;
71 
72 const unsigned int BAND_5_GHZ = 2;
73 const unsigned int BAND_6_GHZ = 8;
74 const unsigned int CHAN_WIDTH_20MHZ = 0;
75 const unsigned int CHAN_WIDTH_40MHZ = 1;
76 const unsigned int CHAN_WIDTH_80MHZ = 2;
77 const unsigned int CHAN_WIDTH_160MHZ = 3;
78 const unsigned int CHAN_WIDTH_80MHZ_MHZ = 4;
79 
80 WifiWpaStaInterface *g_wpaStaInterface = NULL;
81 
82 static WpaSsidField g_wpaHalSsidFields[] = {
83     {DEVICE_CONFIG_SSID, "ssid", WPA_QUOTATION_MARKS_FLAG_YES},
84     {DEVICE_CONFIG_PSK, "psk", WPA_QUOTATION_MARKS_FLAG_YES},
85     {DEVICE_CONFIG_KEYMGMT, "key_mgmt", WPA_QUOTATION_MARKS_FLAG_NO},
86     {DEVICE_CONFIG_PRIORITY, "priority", WPA_QUOTATION_MARKS_FLAG_NO},
87     {DEVICE_CONFIG_SCAN_SSID, "scan_ssid", WPA_QUOTATION_MARKS_FLAG_NO},
88     {DEVICE_CONFIG_EAP, "eap", WPA_QUOTATION_MARKS_FLAG_NO},
89     {DEVICE_CONFIG_IDENTITY, "identity", WPA_QUOTATION_MARKS_FLAG_YES},
90     {DEVICE_CONFIG_PASSWORD, "password", WPA_QUOTATION_MARKS_FLAG_YES},
91     {DEVICE_CONFIG_BSSID, "bssid", WPA_QUOTATION_MARKS_FLAG_NO},
92     {DEVICE_CONFIG_AUTH_ALGORITHMS, "auth_alg", WPA_QUOTATION_MARKS_FLAG_NO},
93     {DEVICE_CONFIG_WEP_KEY_IDX, "wep_tx_keyidx", WPA_QUOTATION_MARKS_FLAG_NO},
94     {DEVICE_CONFIG_WEP_KEY_0, "wep_key0", WPA_QUOTATION_MARKS_FLAG_NO},
95     {DEVICE_CONFIG_WEP_KEY_1, "wep_key1", WPA_QUOTATION_MARKS_FLAG_NO},
96     {DEVICE_CONFIG_WEP_KEY_2, "wep_key2", WPA_QUOTATION_MARKS_FLAG_NO},
97     {DEVICE_CONFIG_WEP_KEY_3, "wep_key3", WPA_QUOTATION_MARKS_FLAG_NO},
98     {DEVICE_CONFIG_EAP_CLIENT_CERT, "client_cert", WPA_QUOTATION_MARKS_FLAG_YES},
99     {DEVICE_CONFIG_EAP_PRIVATE_KEY, "private_key", WPA_QUOTATION_MARKS_FLAG_YES},
100     {DEVICE_CONFIG_EAP_PHASE2METHOD, "phase2", WPA_QUOTATION_MARKS_FLAG_YES},
101     {DEVICE_CONFIG_IEEE80211W, "ieee80211w", WPA_QUOTATION_MARKS_FLAG_NO},
102     {DEVICE_CONFIG_ALLOW_PROTOCOLS, "proto", WPA_QUOTATION_MARKS_FLAG_NO},
103     {DEVICE_CONFIG_GROUP_CIPHERS, "group", WPA_QUOTATION_MARKS_FLAG_NO},
104     {DEVICE_CONFIG_PAIRWISE_CIPHERS, "pairwise", WPA_QUOTATION_MARKS_FLAG_NO},
105     {DEVICE_CONFIG_SAE_PASSWD, "sae_password", WPA_QUOTATION_MARKS_FLAG_YES},
106     {DEVICE_CONFIG_EAP_CA_CERT, "ca_cert", WPA_QUOTATION_MARKS_FLAG_YES},
107     {DEVICE_CONFIG_EAP_CERT_PWD, "private_key_passwd", WPA_QUOTATION_MARKS_FLAG_YES},
108     {DEVICE_CONFIG_WAPI_CA_CERT, "wapi_ca_cert", WPA_QUOTATION_MARKS_FLAG_YES},
109     {DEVICE_CONFIG_WAPI_USER_CERT, "wapi_user_sel_cert", WPA_QUOTATION_MARKS_FLAG_YES},
110     {DEVICE_CONFIG_WAPI_PSK_KEY_TYPE, "psk_key_type", WPA_QUOTATION_MARKS_FLAG_NO},
111     {DEVICE_CONFIG_WAPI_PSK, "wapi_psk", WPA_QUOTATION_MARKS_FLAG_YES},
112 };
113 
WpaCliCmdStatus(WifiWpaStaInterface * this,const char * ifName,struct WpaHalCmdStatus * pcmd)114 static int WpaCliCmdStatus(WifiWpaStaInterface *this, const char*ifName, struct WpaHalCmdStatus *pcmd)
115 {
116     if (this == NULL || pcmd == NULL) {
117         return -1;
118     }
119     char cmd[CMD_BUFFER_SIZE] = {0};
120     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s STATUS", ifName == NULL ? this->ifname : ifName) < 0) {
121         HDF_LOGE("snprintf error");
122         return -1;
123     }
124     char buf[REPLY_BUF_LENGTH] = {0};
125     if (WpaCliCmd(cmd, buf, REPLY_BUF_LENGTH) != 0) {
126         return -1;
127     }
128     char *savedPtr = NULL;
129     char *key = strtok_r(buf, "=", &savedPtr);
130     while (key != NULL) {
131         char *value = strtok_r(NULL, "\n", &savedPtr);
132         if (strcmp(key, "bssid") == 0) {
133             if (strcpy_s(pcmd->bssid, sizeof(pcmd->bssid), value) != EOK) {
134                 HDF_LOGE("%{public}s strcpy failed", __func__);
135             }
136         } else if (strcmp(key, "freq") == 0) {
137             pcmd->freq = atoi(value);
138         } else if (strcmp(key, "ssid") == 0) {
139             if (strcpy_s(pcmd->ssid, sizeof(pcmd->ssid), value) != EOK) {
140                 HDF_LOGE("%{public}s strcpy failed", __func__);
141             }
142             printf_decode((u8 *)pcmd->ssid, sizeof(pcmd->ssid), pcmd->ssid);
143         } else if (strcmp(key, "id") == 0) {
144             pcmd->id = atoi(value);
145         } else if (strcmp(key, "key_mgmt") == 0) {
146             if (strcpy_s(pcmd->keyMgmt, sizeof(pcmd->keyMgmt), value) != EOK) {
147                 HDF_LOGE("%{public}s strcpy failed", __func__);
148             }
149         } else if (strcmp(key, "address") == 0) {
150             if (strcpy_s(pcmd->address, sizeof(pcmd->address), value) != EOK) {
151                 HDF_LOGE("%{public}s strcpy failed", __func__);
152             }
153         }
154 
155         key = strtok_r(NULL, "=", &savedPtr);
156     }
157     if (strcmp(pcmd->address, "") == 0) {
158         return -1;
159     }
160     if (strcmp(pcmd->bssid, "") == 0) {
161         return 1;
162     }
163     return 0;
164 }
165 
WpaCliCmdAddNetworks(WifiWpaStaInterface * this)166 static int WpaCliCmdAddNetworks(WifiWpaStaInterface *this)
167 {
168     if (this == NULL) {
169         return -1;
170     }
171     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
172     char cmd[CMD_BUFFER_SIZE] = {0};
173     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s ADD_NETWORK", this->ifname) < 0) {
174         HDF_LOGE("snprintf error");
175         return -1;
176     }
177     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
178         return -1;
179     }
180     return atoi(buf);
181 }
182 
WpaCliCmdReconnect(WifiWpaStaInterface * this)183 static int WpaCliCmdReconnect(WifiWpaStaInterface *this)
184 {
185     if (this == NULL) {
186         return -1;
187     }
188     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
189     char cmd[CMD_BUFFER_SIZE] = {0};
190     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s RECONNECT", this->ifname) < 0) {
191         HDF_LOGE("snprintf error");
192         return -1;
193     }
194     return WpaCliCmd(cmd, buf, sizeof(buf));
195 }
196 
WpaCliCmdReassociate(WifiWpaStaInterface * this)197 static int WpaCliCmdReassociate(WifiWpaStaInterface *this)
198 {
199     if (this == NULL) {
200         return -1;
201     }
202     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
203     char cmd[CMD_BUFFER_SIZE] = {0};
204     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s REASSOCIATE", this->ifname) < 0) {
205         HDF_LOGE("snprintf error");
206         return -1;
207     }
208     return WpaCliCmd(cmd, buf, sizeof(buf));
209 }
210 
WpaCliCmdDisconnect(WifiWpaStaInterface * this)211 static int WpaCliCmdDisconnect(WifiWpaStaInterface *this)
212 {
213     if (this == NULL) {
214         return -1;
215     }
216     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
217     char cmd[CMD_BUFFER_SIZE] = {0};
218     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s DISCONNECT", this->ifname) < 0) {
219         HDF_LOGE("snprintf error");
220         return -1;
221     }
222     return WpaCliCmd(cmd, buf, sizeof(buf));
223 }
224 
WpaCliCmdSaveConfig(WifiWpaStaInterface * this)225 static int WpaCliCmdSaveConfig(WifiWpaStaInterface *this)
226 {
227     if (this == NULL) {
228         return -1;
229     }
230     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
231     char cmd[CMD_BUFFER_SIZE] = {0};
232     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s SAVE_CONFIG", this->ifname) < 0) {
233         HDF_LOGE("snprintf error");
234         return -1;
235     }
236     return WpaCliCmd(cmd, buf, sizeof(buf));
237 }
238 
WpaCliCmdSetNetwork(WifiWpaStaInterface * this,const struct WpaSetNetworkArgv * argv)239 static int WpaCliCmdSetNetwork(WifiWpaStaInterface *this, const struct WpaSetNetworkArgv *argv)
240 {
241     if (this == NULL || argv == NULL) {
242         return -1;
243     }
244     int pos = -1;
245     for (int i = 0; i < (int)(sizeof(g_wpaHalSsidFields) / sizeof(g_wpaHalSsidFields[0])); ++i) {
246         if (g_wpaHalSsidFields[i].field == argv->param) {
247             pos = i;
248             break;
249         }
250     }
251     if (pos < 0) {
252         HDF_LOGE("%{public}s unsupported param: %{public}d", __func__, argv->param);
253         return -1;
254     }
255     char cmd[CMD_BUFFER_SIZE] = {0};
256     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
257     int res;
258 
259     res = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s SET_NETWORK %d %s %s", this->ifname,
260             argv->id, g_wpaHalSsidFields[pos].fieldName, argv->value);
261     HDF_LOGI("%{public}s cmd= %{private}s", __func__, cmd);
262     if (res < 0) {
263         HDF_LOGE("%{public}s Internal error, set request message failed!", __func__);
264         return -1;
265     }
266     return WpaCliCmd(cmd, buf, sizeof(buf));
267 }
268 
WpaCliCmdEnableNetwork(WifiWpaStaInterface * this,int networkId)269 static int WpaCliCmdEnableNetwork(WifiWpaStaInterface *this, int networkId)
270 {
271     if (this == NULL) {
272         return -1;
273     }
274     char cmd[CMD_BUFFER_SIZE] = {0};
275     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
276     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s ENABLE_NETWORK %d", this->ifname, networkId) < 0) {
277         HDF_LOGE("snprintf err");
278         return -1;
279     }
280     return WpaCliCmd(cmd, buf, sizeof(buf));
281 }
282 
WpaCliCmdSelectNetwork(WifiWpaStaInterface * this,int networkId)283 static int WpaCliCmdSelectNetwork(WifiWpaStaInterface *this, int networkId)
284 {
285     if (this == NULL) {
286         return -1;
287     }
288     char cmd[CMD_BUFFER_SIZE] = {0};
289     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
290     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s SELECT_NETWORK %d", this->ifname, networkId) < 0) {
291         HDF_LOGE("snprintf err");
292         return -1;
293     }
294     return WpaCliCmd(cmd, buf, sizeof(buf));
295 }
296 
WpaCliCmdDisableNetwork(WifiWpaStaInterface * this,int networkId)297 static int WpaCliCmdDisableNetwork(WifiWpaStaInterface *this, int networkId)
298 {
299     if (this == NULL) {
300         return -1;
301     }
302     char cmd[CMD_BUFFER_SIZE] = {0};
303     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
304     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s DISABLE_NETWORK %d", this->ifname, networkId) < 0) {
305         HDF_LOGE("snprintf err");
306         return -1;
307     }
308     return WpaCliCmd(cmd, buf, sizeof(buf));
309 }
310 
WpaCliCmdRemoveNetwork(WifiWpaStaInterface * this,int networkId)311 static int WpaCliCmdRemoveNetwork(WifiWpaStaInterface *this, int networkId)
312 {
313     if (this == NULL) {
314         return -1;
315     }
316     char cmd[CMD_BUFFER_SIZE] = {0};
317     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
318     int res = 0;
319     if (networkId == -1) {
320         res = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s REMOVE_NETWORK all", this->ifname);
321     } else if (networkId >= 0) {
322         res = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s REMOVE_NETWORK %d", this->ifname, networkId);
323     } else {
324         return -1;
325     }
326     if (res < 0) {
327         HDF_LOGE("snprintf err");
328         return -1;
329     }
330     return WpaCliCmd(cmd, buf, sizeof(buf));
331 }
332 
WpaCliCmdGetNetwork(WifiWpaStaInterface * this,const struct WpaGetNetworkArgv * argv,char * pcmd,unsigned size)333 static int WpaCliCmdGetNetwork(
334     WifiWpaStaInterface *this, const struct WpaGetNetworkArgv *argv, char *pcmd, unsigned size)
335 {
336     if (this == NULL || argv == NULL || pcmd == NULL) {
337         return -1;
338     }
339     char cmd[CMD_BUFFER_SIZE] = {0};
340     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s GET_NETWORK %d %s", this->ifname, argv->id,
341         argv->param) < 0) {
342         HDF_LOGE("snprintf err");
343         return -1;
344     }
345     char *buf = (char *)calloc(REPLY_BUF_LENGTH, sizeof(char));
346     if (buf == NULL) {
347         return -1;
348     }
349     if (WpaCliCmd(cmd, buf, REPLY_BUF_LENGTH) != 0) {
350         free(buf);
351         return -1;
352     }
353     if (strncpy_s(pcmd, size, buf, strlen(buf)) != EOK) {
354         HDF_LOGE("copy set get_network result failed!");
355         free(buf);
356         return -1;
357     }
358     free(buf);
359     return 0;
360 }
361 
WpaCliCmdWpsPbc(WifiWpaStaInterface * this,const struct WpaWpsPbcArgv * wpspbc)362 static int WpaCliCmdWpsPbc(WifiWpaStaInterface *this, const struct WpaWpsPbcArgv *wpspbc)
363 {
364     if (this == NULL) {
365         return -1;
366     }
367     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
368     char cmd[CMD_BUFFER_SIZE] = {0};
369     int pos = 0;
370     int res = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s WPS_PBC", this->ifname);
371     if (res < 0) {
372         HDF_LOGE("snprintf err");
373         return -1;
374     }
375     pos += res;
376     if (wpspbc != NULL) {
377         res = 0; /* reset res value */
378         if (wpspbc->anyFlag == 1) {
379             res = snprintf_s(cmd + pos, sizeof(cmd) - pos, sizeof(cmd) - pos - 1, " %s", "any");
380         } else if (strlen(wpspbc->bssid) > 0) {
381             res = snprintf_s(cmd + pos, sizeof(cmd) - pos, sizeof(cmd) - pos - 1, " %s", wpspbc->bssid);
382         }
383         if (res < 0) {
384             HDF_LOGE("snprintf err");
385             return -1;
386         }
387         pos += res;
388         if (wpspbc->multiAp > 0) { /* The value of ap needs to be determined. The value is greater than 0. */
389             res = snprintf_s(
390                 cmd + pos, sizeof(cmd) - pos, sizeof(cmd) - pos - 1, " multi_ap=%d", wpspbc->multiAp);
391             if (res < 0) {
392                 HDF_LOGE("snprintf err");
393                 return -1;
394             }
395         }
396     }
397     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
398         HDF_LOGE("wps_pbc return failed!");
399         return -1;
400     }
401     if (strncmp(buf, "FAIL-PBC-OVERLAP", strlen("FAIL-PBC-OVERLAP")) == 0) {
402         HDF_LOGE("wps_pbc success, but result err: buf =%{public}s", buf);
403         return FAIL_PBC_OVERLAP_RETUEN; /* Add a new enumerated value. */
404     }
405     return 0;
406 }
407 
WpaCliCmdWpsPin(WifiWpaStaInterface * this,const struct WpaWpsPinArgv * wpspin,int * pincode)408 static int WpaCliCmdWpsPin(WifiWpaStaInterface *this, const struct WpaWpsPinArgv *wpspin, int *pincode)
409 {
410     if (this == NULL || wpspin == NULL || pincode == NULL) {
411         return -1;
412     }
413     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
414     char cmd[CMD_BUFFER_SIZE] = {0};
415     int pos = 0;
416     int res = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s WPS_PIN", this->ifname);
417     if (res < 0) {
418         HDF_LOGE("snprintf err");
419         return -1;
420     }
421     pos += res;
422     if (strlen(wpspin->bssid) > 0) {
423         res = snprintf_s(cmd + pos, sizeof(cmd) - pos, sizeof(cmd) - pos - 1, " %s", wpspin->bssid);
424     } else {
425         res = snprintf_s(cmd + pos, sizeof(cmd) - pos, sizeof(cmd) - pos - 1, " any");
426     }
427     if (res < 0) {
428         HDF_LOGE("snprintf err");
429         return -1;
430     }
431     pos += res;
432     if (strlen(wpspin->pinCode) > 0) {
433         res = snprintf_s(cmd + pos, sizeof(cmd) - pos, sizeof(cmd) - pos - 1, " %s", wpspin->pinCode);
434         if (res < 0) {
435             HDF_LOGE("snprintf err");
436             return -1;
437         }
438     }
439     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
440         HDF_LOGE("wps_pin return failed!");
441         return -1;
442     }
443     *pincode = atoi(buf);
444     return 0;
445 }
446 
WpaCliCmdWpsCancel(WifiWpaStaInterface * this)447 static int WpaCliCmdWpsCancel(WifiWpaStaInterface *this)
448 {
449     if (this == NULL) {
450         return -1;
451     }
452     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
453     char cmd[CMD_BUFFER_SIZE] = {0};
454     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s WPS_CANCEL", this->ifname) < 0) {
455         HDF_LOGE("snprintf err");
456         return -1;
457     }
458     return WpaCliCmd(cmd, buf, sizeof(buf));
459 }
460 
WpaCliCmdPowerSave(WifiWpaStaInterface * this,int enable)461 static int WpaCliCmdPowerSave(WifiWpaStaInterface *this, int enable)
462 {
463     if (this == NULL) {
464         return -1;
465     }
466     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
467     char cmd[CMD_BUFFER_SIZE] = {0};
468     int ret;
469     if (enable) {
470         ret = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s SET PS 1", this->ifname);
471     } else {
472         ret = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s SET PS 0", this->ifname);
473     }
474     if (ret < 0) {
475         HDF_LOGE("snprintf err");
476         return -1;
477     }
478     return WpaCliCmd(cmd, buf, sizeof(buf));
479 }
480 
WpaCliCmdSetRoamConfig(WifiWpaStaInterface * this,const char * bssid)481 static int WpaCliCmdSetRoamConfig(WifiWpaStaInterface *this, const char *bssid)
482 {
483     if (this == NULL || bssid == NULL) {
484         return -1;
485     }
486     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
487     char cmd[CMD_BUFFER_SIZE] = {0};
488     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s SET bssid %s", this->ifname, bssid) < 0) {
489         HDF_LOGE("snprintf err");
490         return -1;
491     }
492     return WpaCliCmd(cmd, buf, sizeof(buf));
493 }
494 
WpaCliCmdSetCountryCode(WifiWpaStaInterface * this,const char * countryCode)495 static int WpaCliCmdSetCountryCode(WifiWpaStaInterface *this, const char *countryCode)
496 {
497     if (this == NULL || countryCode == NULL) {
498         return -1;
499     }
500     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
501     char cmd[CMD_BUFFER_SIZE] = {0};
502     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s DRIVER COUNTRY %s", this->ifname, countryCode) < 0) {
503         HDF_LOGE("snprintf err");
504         return -1;
505     }
506     return WpaCliCmd(cmd, buf, sizeof(buf));
507 }
508 
WpaCliCmdGetCountryCode(WifiWpaStaInterface * this,char * countryCode,int codeSize)509 static int WpaCliCmdGetCountryCode(WifiWpaStaInterface *this, char *countryCode, int codeSize)
510 {
511     if (this == NULL || countryCode == NULL) {
512         return -1;
513     }
514     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
515     char cmd[CMD_BUFFER_SIZE] = {0};
516     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s GET country", this->ifname) < 0) {
517         HDF_LOGE("snprintf err");
518         return -1;
519     }
520     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
521         HDF_LOGE("get countrycode failed");
522         return -1;
523     }
524     if (strncpy_s(countryCode, codeSize, buf, strlen(buf)) != EOK) {
525         HDF_LOGE("copy set country code failed!");
526         return -1;
527     }
528     return 0;
529 }
530 
WpaCliCmdGetConnectionCapabilities(WifiWpaStaInterface * this,struct ConnectionCapabilities * connectionCap)531 static int WpaCliCmdGetConnectionCapabilities(WifiWpaStaInterface *this, struct ConnectionCapabilities *connectionCap)
532 {
533     if (this == NULL || connectionCap == NULL) {
534         return -1;
535     }
536     char buf[REPLY_BUF_LENGTH] = {0};
537     char cmd[CMD_BUFFER_SIZE] = {0};
538     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s GET_CONNECTION_CAPABILITY", this->ifname) < 0) {
539         HDF_LOGE("snprintf err");
540         return -1;
541     }
542 
543     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
544         HDF_LOGE("WpaCliCmd GET_CONNECTION_CAPABILITY failed");
545         return -1;
546     }
547     char *savedPtr = NULL;
548     char *key = strtok_r(buf, "=", &savedPtr);
549     while (key != NULL) {
550         char *value = strtok_r(NULL, "\n", &savedPtr);
551         if (strcmp(key, "technology") == 0) {
552             connectionCap->technology = atoi(value);
553         } else if (strcmp(key, "channelBandwidth") == 0) {
554             connectionCap->channelBandwidth = atoi(value);
555         }  else if (strcmp(key, "maxNumberTxSpatialStreams") == 0) {
556             connectionCap->maxNumberTxSpatialStreams = atoi(value);
557         }  else if (strcmp(key, "maxNumberRxSpatialStreams") == 0) {
558             connectionCap->maxNumberRxSpatialStreams = atoi(value);
559         }  else if (strcmp(key, "legacyMode") == 0) {
560             connectionCap->legacyMode = atoi(value);
561         }
562         key = strtok_r(NULL, "=", &savedPtr);
563     }
564     HDF_LOGI("WpaCliCmdGetConnectionCapabilities technology =%d channelBandwidth = %d", connectionCap->technology,
565         connectionCap->channelBandwidth);
566     return 0;
567 }
568 
WpaCliCmdGetRequirePmf(WifiWpaStaInterface * this,int * enable)569 static int WpaCliCmdGetRequirePmf(WifiWpaStaInterface *this, int *enable)
570 {
571     if (this == NULL || enable == NULL) {
572         return -1;
573     }
574     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
575     char cmd[CMD_BUFFER_SIZE] = {0};
576     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s GET_REQUIRE_PMF", this->ifname) < 0) {
577         HDF_LOGE("snprintf err");
578         return -1;
579     }
580 
581     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
582         HDF_LOGE("WpaCliCmd GET_REQUIRE_PMF failed");
583         return -1;
584     }
585     char *savedPtr = NULL;
586     char *key = strtok_r(buf, "=", &savedPtr);
587     while (key != NULL) {
588         char *value = strtok_r(NULL, "\n", &savedPtr);
589         if (strcmp(key, "require_pmf") == 0) {
590             *enable = atoi(value);
591         }
592         key = strtok_r(NULL, "=", &savedPtr);
593     }
594     HDF_LOGI("WpaCliCmdGetRequirePmf enable =%d ", *enable);
595     return 0;
596 }
597 
WpaCliCmdWepKeyTxKeyIdx(WifiWpaStaInterface * this,int * keyIdx)598 static int WpaCliCmdWepKeyTxKeyIdx(WifiWpaStaInterface *this, int *keyIdx)
599 {
600     if (this == NULL || keyIdx == NULL) {
601         return -1;
602     }
603     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
604     char cmd[CMD_BUFFER_SIZE] = {0};
605     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s GET_WEP_KEY_IDX", this->ifname) < 0) {
606         HDF_LOGE("snprintf err");
607         return -1;
608     }
609 
610     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
611         HDF_LOGE("WpaCliCmd GET_WEP_KEY_IDX failed");
612         return -1;
613     }
614     char *savedPtr = NULL;
615     char *key = strtok_r(buf, "=", &savedPtr);
616     while (key != NULL) {
617         char *value = strtok_r(NULL, "\n", &savedPtr);
618         if (strcmp(key, "wep_tx_keyidx") == 0) {
619             *keyIdx = atoi(value);
620         }
621         key = strtok_r(NULL, "=", &savedPtr);
622     }
623     HDF_LOGI("WpaCliCmdWepKeyTxKeyIdx keyIdx =%d ", *keyIdx);
624     return 0;
625 }
626 
WpaCliCmdWepKey(WifiWpaStaInterface * this,int keyIdx,unsigned char * wepKey,unsigned int * wepKeyLen)627 static int WpaCliCmdWepKey(WifiWpaStaInterface *this, int keyIdx, unsigned char *wepKey, unsigned int *wepKeyLen)
628 {
629     if (this == NULL || wepKey == NULL || wepKeyLen == NULL) {
630         return -1;
631     }
632     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
633     char cmd[CMD_BUFFER_SIZE] = {0};
634     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s GET_WEP_KEY GET_WEP_KEY_IDX %d",
635 		this->ifname, keyIdx) < 0) {
636         HDF_LOGE("snprintf err");
637         return -1;
638     }
639 
640     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
641         HDF_LOGE("WpaCliCmd WepKey failed");
642         return -1;
643     }
644     char *savedPtr = NULL;
645     char *key = strtok_r(buf, "=", &savedPtr);
646     while (key != NULL) {
647         char *value = strtok_r(NULL, "\n", &savedPtr);
648         if (strcmp(key, "wep_key") == 0) {
649             if (strncpy_s((char *)wepKey, strlen(value), value, strlen(value)) != 0) {
650                 HDF_LOGE("copy wep_key failed!");
651                 return -1;
652             }
653             *wepKeyLen = strlen(value);
654         }
655         key = strtok_r(NULL, "=", &savedPtr);
656     }
657     HDF_LOGI("WpaCliCmdWepKey wepKey =%{private}s", wepKey);
658     return 0;
659 }
660 
WpaCliCmdGetPsk(WifiWpaStaInterface * this,unsigned char * psk,unsigned int * pskLen)661 static int WpaCliCmdGetPsk(WifiWpaStaInterface *this, unsigned char *psk, unsigned int *pskLen)
662 {
663     if (this == NULL || psk == NULL || pskLen == NULL) {
664         return -1;
665     }
666     char buf[REPLY_BUF_LENGTH] = {0};
667     char cmd[CMD_BUFFER_SIZE] = {0};
668     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s GET_PSK", this->ifname) < 0) {
669         HDF_LOGE("snprintf err");
670         return -1;
671     }
672 
673     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
674         HDF_LOGE("WpaCliCmd GET_PSK failed");
675         return -1;
676     }
677     char *savedPtr = NULL;
678     char *key = strtok_r(buf, "=", &savedPtr);
679     while (key != NULL) {
680         char *value = strtok_r(NULL, "\n", &savedPtr);
681         if (strcmp(key, "psk") == 0) {
682             if (strncpy_s((char *)psk, strlen(value), value, strlen(value)) != 0) {
683                 HDF_LOGE("copy psk failed!");
684                 return -1;
685             }
686             *pskLen = strlen(value);
687         }
688         key = strtok_r(NULL, "=", &savedPtr);
689     }
690     HDF_LOGI("WpaCliCmdGetPsk psk =%{private}s", psk);
691     return 0;
692 }
693 
WpaCliCmdGetPskPassphrase(WifiWpaStaInterface * this,char * psk,unsigned int pskLen)694 static int WpaCliCmdGetPskPassphrase(WifiWpaStaInterface *this, char *psk, unsigned int pskLen)
695 {
696     if (this == NULL || psk == NULL) {
697         return -1;
698     }
699     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
700     char cmd[CMD_BUFFER_SIZE] = {0};
701     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s GET_PSK_PASSPHRASE", this->ifname) < 0) {
702         HDF_LOGE("snprintf err");
703         return -1;
704     }
705 
706     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
707         HDF_LOGE("WpaCliCmd GET_PSK_PASSPHRASE failed");
708         return -1;
709     }
710     char *savedPtr = NULL;
711     char *key = strtok_r(buf, "=", &savedPtr);
712     while (key != NULL) {
713         char *value = strtok_r(NULL, "\n", &savedPtr);
714         if (strcmp(key, "passphrase") == 0) {
715             if (strncpy_s((char *)psk, (int)pskLen, value, strlen(value)) != 0) {
716                 HDF_LOGE("copy passphrase failed!");
717                 return -1;
718             }
719         }
720         key = strtok_r(NULL, "=", &savedPtr);
721     }
722     HDF_LOGI("WpaCliCmdGetPskPassphrase psk = %{private}s", psk);
723     return 0;
724 }
725 
WpaCliCmdGetScanSsid(WifiWpaStaInterface * this,int * scanSsid)726 static int WpaCliCmdGetScanSsid(WifiWpaStaInterface *this, int *scanSsid)
727 {
728     if (this == NULL || scanSsid == NULL) {
729         return -1;
730     }
731     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
732     char cmd[CMD_BUFFER_SIZE] = {0};
733     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s GET_SCAN_SSID", this->ifname) < 0) {
734         HDF_LOGE("snprintf err");
735         return -1;
736     }
737 
738     if (WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
739         HDF_LOGE("WpaCliCmd GET_SCAN_SSID failed");
740         return -1;
741     }
742     char *savedPtr = NULL;
743     char *key = strtok_r(buf, "=", &savedPtr);
744     while (key != NULL) {
745         char *value = strtok_r(NULL, "\n", &savedPtr);
746         if (strcmp(key, "scan_ssid") == 0) {
747             *scanSsid = atoi(value);
748         }
749         key = strtok_r(NULL, "=", &savedPtr);
750     }
751     HDF_LOGI("WpaCliCmdGetScanSsid scanSsid =%d ", *scanSsid);
752     return 0;
753 }
754 
WpaCliCmdSetAutoConnect(WifiWpaStaInterface * this,int enable)755 static int WpaCliCmdSetAutoConnect(WifiWpaStaInterface *this, int enable)
756 {
757     if (this == NULL) {
758         return -1;
759     }
760     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
761     char cmd[CMD_BUFFER_SIZE] = {0};
762     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s STA_AUTOCONNECT %d", this->ifname, enable) < 0) {
763         HDF_LOGE("snprintf err");
764         return -1;
765     }
766     return WpaCliCmd(cmd, buf, sizeof(buf));
767 }
768 
WpaCliCmdWpaBlockListClear(WifiWpaStaInterface * this)769 static int WpaCliCmdWpaBlockListClear(WifiWpaStaInterface *this)
770 {
771     if (this == NULL) {
772         return -1;
773     }
774     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
775     char cmd[CMD_BUFFER_SIZE] = {0};
776     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s BL%cCKLIST clear", this->ifname, 'A') < 0) {
777         HDF_LOGE("snprintf err");
778         return -1;
779     }
780     return WpaCliCmd(cmd, buf, sizeof(buf));
781 }
782 
ListNetworkProcess(WifiNetworkInfo * pcmd,char * tmpBuf,int bufLeng)783 static void ListNetworkProcess(WifiNetworkInfo *pcmd, char *tmpBuf, int bufLeng)
784 {
785     int start = 0; /* start pos */
786     int end = 0;   /* end pos */
787     int i = 0;
788     while (end < bufLeng) {
789         if (tmpBuf[end] != '\t') {
790             ++end;
791             continue;
792         }
793         tmpBuf[end] = '\0';
794         if (i == COLUMN_INDEX_ZERO) {
795             pcmd->id = atoi(tmpBuf);
796         } else if (i == COLUMN_INDEX_ONE) {
797             if (strcpy_s(pcmd->ssid, sizeof(pcmd->ssid), tmpBuf + start) != EOK) {
798                 break;
799             }
800             printf_decode((u8 *)pcmd->ssid, sizeof(pcmd->ssid), pcmd->ssid);
801         } else if (i == COLUMN_INDEX_TWO) {
802             if (strcpy_s(pcmd->bssid, sizeof(pcmd->bssid), tmpBuf + start) != EOK) {
803                 break;
804             }
805             start = end + 1;
806             if (strcpy_s(pcmd->flags, sizeof(pcmd->flags), tmpBuf + start) != EOK) {
807                 break;
808             }
809             break;
810         }
811         ++i;
812         end++;
813         start = end;
814     }
815     return;
816 }
817 
WpaCliCmdListNetworks(WifiWpaStaInterface * this,WifiNetworkInfo * pcmd,int * size)818 static int WpaCliCmdListNetworks(WifiWpaStaInterface *this, WifiNetworkInfo *pcmd, int *size)
819 {
820     if (this == NULL || pcmd == NULL || size == NULL || *size <= 0) {
821         return -1;
822     }
823     char cmd[CMD_BUFFER_SIZE] = {0};
824     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s LIST_NETWORKS", this->ifname) < 0) {
825         HDF_LOGE("snprintf err");
826         return -1;
827     }
828     char *buf = (char *)calloc(REPLY_BUF_LENGTH, sizeof(char));
829     if (buf == NULL) {
830         return -1;
831     }
832     if (WpaCliCmd(cmd, buf, REPLY_BUF_LENGTH) != 0) {
833         free(buf);
834         return -1;
835     }
836     char *savedPtr = NULL;
837     strtok_r(buf, "\n", &savedPtr); /* skip first line */
838     char *token = strtok_r(NULL, "\n", &savedPtr);
839     int j = 0;
840 
841     while (token != NULL) {
842         if (j >= *size) {
843             *size = j;
844             HDF_LOGW("list_networks full!");
845             free(buf);
846             return 0;
847         }
848         int length = strlen(token);
849         if (length <= 0) {
850             break;
851         }
852         ListNetworkProcess(pcmd + j, token, length);
853         token = strtok_r(NULL, "\n", &savedPtr);
854         j++;
855     }
856     *size = j;
857     if (*size <= 0) {
858         HDF_LOGW("list_networks empty!");
859     }
860     free(buf);
861     return 0;
862 }
863 
AssignCmdLen(WifiWpaStaInterface * this,const ScanSettings * settings)864 static unsigned AssignCmdLen(WifiWpaStaInterface *this, const ScanSettings *settings)
865 {
866     if (settings->scanStyle == SCAN_TYPE_PNO) {
867         unsigned exceptedLen = strlen("IFNAME=") + strlen(this->ifname) + 1 + strlen("set pno x");
868         if (settings->isStartPnoScan) {
869             HDF_LOGI("AssignCmdLen, startPnoScan, freqSize=%{public}d", settings->freqSize);
870             if (settings->freqSize > 0) {
871                 exceptedLen += strlen(" freq=") + (CMD_FREQ_MAX_LEN + 1) * settings->freqSize;
872             }
873         }
874         return exceptedLen;
875     }
876     unsigned exceptedLen = strlen("IFNAME=") + strlen(this->ifname) + 1 + strlen("SCAN");
877     HDF_LOGI("AssignCmdLen, startScan, freSize=%{public}d, hiddenSsidSize=%{public}d",
878         settings->freqSize, settings->hiddenSsidSize);
879     if (settings->freqSize > 0) {
880         exceptedLen += strlen(" freq=") + (CMD_FREQ_MAX_LEN + 1) * settings->freqSize;
881     }
882     for (int i = 0; i < settings->hiddenSsidSize; ++i) {
883         unsigned ssidLen = strlen(settings->hiddenSsid[i]);
884         exceptedLen += strlen(" ssid ") + (ssidLen << 1);
885     }
886     return exceptedLen;
887 }
888 
ConcatScanSetting(const ScanSettings * settings,char * buff,int len)889 static int ConcatScanSetting(const ScanSettings *settings, char *buff, int len)
890 {
891     if (settings == NULL || (settings->scanStyle == SCAN_TYPE_PNO && !settings->isStartPnoScan)) {
892         return 0;
893     }
894     int pos = 0;
895     int res;
896     int i;
897     if (settings->freqSize < 0 || settings->freqSize > FREQ_MAX_SIZE) {
898         HDF_LOGE("invalid parameter");
899         return 0;
900     }
901     for (i = 0; i < settings->freqSize; ++i) {
902         if (i == 0) {
903             res = snprintf_s(buff + pos, len - pos, len - pos - 1, "%s", " freq=");
904             if (res < 0) {
905                 HDF_LOGE("snprintf error");
906                 return -1;
907             }
908             pos += res;
909         }
910         if (i != (settings->freqSize - 1)) {
911             res = snprintf_s(buff + pos, len - pos, len - pos - 1, "%d,", settings->freqs[i]);
912         } else {
913             res = snprintf_s(buff + pos, len - pos, len - pos - 1, "%d;", settings->freqs[i]);
914         }
915         if (res < 0) {
916             HDF_LOGE("snprintf error");
917             return -1;
918         }
919         pos += res;
920     }
921     for (i = 0; (i < settings->hiddenSsidSize) && (settings->scanStyle != SCAN_TYPE_PNO); ++i) {
922         res = snprintf_s(buff + pos, len - pos, len - pos - 1, " ssid ");
923         if (res < 0) {
924             HDF_LOGE("snprintf error");
925             return -1;
926         }
927         pos += res;
928         char *p = settings->hiddenSsid[i];
929         while (*p) {
930             res = snprintf_s(buff + pos, len - pos, len - pos - 1, "%02x", *p);
931             if (res < 0) {
932                 HDF_LOGE("snprintf error");
933                 return -1;
934             }
935             pos += res;
936             p++;
937         }
938     }
939     return 0;
940 }
941 
WpaCliCmdBssFlush(WifiWpaStaInterface * this)942 static int WpaCliCmdBssFlush(WifiWpaStaInterface *this)
943 {
944     if (this == NULL) {
945         return -1;
946     }
947     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
948     char cmd[CMD_BUFFER_SIZE] = {0};
949     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s BSS_FLUSH 0", this->ifname) < 0) {
950         HDF_LOGE("snprintf err");
951         return -1;
952     }
953     return WpaCliCmd(cmd, buf, sizeof(buf));
954 }
955 
WpaCliCmdScan(WifiWpaStaInterface * this,const ScanSettings * settings)956 static int WpaCliCmdScan(WifiWpaStaInterface *this, const ScanSettings *settings)
957 {
958     if (this == NULL) {
959         HDF_LOGE("WpaCliCmdScan, this is NULL!");
960         return -1;
961     }
962 
963     /* Invalidate expired scan results */
964     WpaCliCmdBssFlush(this);
965     unsigned len = CMD_BUFFER_SIZE;
966     unsigned expectedLen = 0;
967     if (settings != NULL) {
968         expectedLen = AssignCmdLen(this, settings);
969     }
970     if (expectedLen < CMD_BUFFER_MIN_SIZE || expectedLen > CMD_BUFFER_SIZE) {
971         HDF_LOGE("invalid parameter");
972         return -1;
973     }
974     if (expectedLen >= len) {
975         len = expectedLen + 1;
976     }
977     char *pcmd = (char *)calloc(len, sizeof(char));
978     if (pcmd == NULL) {
979         HDF_LOGE("WpaCliCmdScan, pcmd is NULL!");
980         return -1;
981     }
982     int pos = 0;
983     int res = 0;
984     if (settings != NULL) {
985         if (settings->scanStyle == SCAN_TYPE_PNO && settings->isStartPnoScan) {
986             res = snprintf_s(pcmd, len, len - 1, "IFNAME=%s SET PNO 1", this->ifname);
987         } else if (settings->scanStyle == SCAN_TYPE_PNO && !settings->isStartPnoScan) {
988             res = snprintf_s(pcmd, len, len - 1, "IFNAME=%s SET PNO 0", this->ifname);
989         } else {
990             res = snprintf_s(pcmd, len, len - 1, "IFNAME=%s SCAN", this->ifname);
991         }
992     }
993     if (res < 0) {
994         HDF_LOGE("WpaCliCmdScan, snprintf_s error!");
995         free(pcmd);
996         return -1;
997     }
998     pos += res;
999     if (settings != NULL && ConcatScanSetting(settings, pcmd + pos, len - pos) < 0) {
1000         HDF_LOGE("ConcatScanSetting return failed!");
1001         free(pcmd);
1002         return -1;
1003     }
1004     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
1005     if (WpaCliCmd(pcmd, buf, sizeof(buf)) != 0) {
1006         free(pcmd);
1007         return -1;
1008     }
1009     free(pcmd);
1010     if (strncmp(buf, "FAIL-BUSY", strlen("FAIL-BUSY")) == 0) {
1011         HDF_LOGE("WpaCliCmdScan, WpaCliCmd return FAIL-BUSY!");
1012         return FAIL_BUSY;
1013     }
1014     return 0;
1015 }
1016 
ConvertChanToFreqMhz(int channel,int band)1017 static int ConvertChanToFreqMhz(int channel, int band)
1018 {
1019     int band24Ghz = 1;
1020     int channelTimes = 5;
1021 
1022     if (band == band24Ghz) {
1023         int bandFirstChNum24 = 1;
1024         int bandLastChNum24 = 14;
1025         int bandStartFreqMhz24 = 2412;
1026         int bandSpecial = 2484;
1027         int channelSpecial = 14;
1028         if (channel == channelSpecial) {
1029             return bandSpecial;
1030         } else if (channel >= bandFirstChNum24 && channel <= bandLastChNum24) {
1031             return ((channel - bandFirstChNum24) * channelTimes) + bandStartFreqMhz24;
1032         } else {
1033             return UNSPECIFIED;
1034         }
1035     }
1036     if (band == BAND_5_GHZ) {
1037         int bandFirstChMum5 = 32;
1038         int bandLastChMum5 = 173;
1039         int bandStartFreqMhz5 = 5160;
1040         if (channel >= bandFirstChMum5 && channel <= bandLastChMum5) {
1041             return ((channel - bandFirstChMum5) * channelTimes) + bandStartFreqMhz5;
1042         } else {
1043             return UNSPECIFIED;
1044         }
1045     }
1046     if (band == BAND_6_GHZ) {
1047         int bandFirstChMum6 = 1;
1048         int bandLastChMum6 = 233;
1049         int bandStartFreqMhz6 = 5955;
1050         int bandCla2Freq136ChMhz6 = 5935;
1051         int channelType = 2;
1052         if (channel >= bandFirstChMum6 && channel <= bandLastChMum6) {
1053             if (channel == channelType) {
1054                 return bandCla2Freq136ChMhz6;
1055             }
1056             return ((channel - bandFirstChMum6) * channelTimes) + bandStartFreqMhz6;
1057         } else {
1058             return UNSPECIFIED;
1059         }
1060     }
1061     return UNSPECIFIED;
1062 }
1063 
GetHeChanWidth(int heChannelWidth,int centerSegFreq0,int centerSegFreq1)1064 static int GetHeChanWidth(int heChannelWidth, int centerSegFreq0, int centerSegFreq1)
1065 {
1066     int channelWidth = 2;
1067     int segFreqValue = 8;
1068     if (heChannelWidth == 0) {
1069         return CHAN_WIDTH_20MHZ;
1070     } else if (heChannelWidth == 1) {
1071         return CHAN_WIDTH_40MHZ;
1072     } else if (heChannelWidth == channelWidth) {
1073         return CHAN_WIDTH_80MHZ;
1074     } else if (abs(centerSegFreq1 - centerSegFreq0) == segFreqValue) {
1075         return CHAN_WIDTH_160MHZ;
1076     } else {
1077         return CHAN_WIDTH_80MHZ_MHZ;
1078     }
1079 }
1080 
GetHeCentFreq(int centerSegFreq)1081 static int GetHeCentFreq(int centerSegFreq)
1082 {
1083     if (centerSegFreq == 0) {
1084         return 0;
1085     }
1086     return ConvertChanToFreqMhz(centerSegFreq, BAND_6_GHZ);
1087 }
1088 
GetHtChanWidth(int secondOffsetChannel)1089 static int GetHtChanWidth(int secondOffsetChannel)
1090 {
1091     if (secondOffsetChannel != 0) {
1092         return CHAN_WIDTH_40MHZ;
1093     } else {
1094         return CHAN_WIDTH_20MHZ;
1095     }
1096 }
1097 
GetHtCentFreq0(int primaryFrequency,int secondOffsetChannel)1098 static int GetHtCentFreq0(int primaryFrequency, int secondOffsetChannel)
1099 {
1100     if (secondOffsetChannel != 0) {
1101         int freqValue = 10;
1102         int offsetChannle = 3;
1103         if (secondOffsetChannel == 1) {
1104             return primaryFrequency + freqValue;
1105         } else if (secondOffsetChannel == offsetChannle) {
1106             return primaryFrequency - freqValue;
1107         } else {
1108             HDF_LOGE("error on get centFreq0");
1109             return 0;
1110         }
1111     } else {
1112         return primaryFrequency;
1113     }
1114 }
1115 
GetVhtChanWidth(int channelType,int centerFrequencyIndex1,int centerFrequencyIndex2)1116 static int GetVhtChanWidth(int channelType, int centerFrequencyIndex1, int centerFrequencyIndex2)
1117 {
1118     int freqValue = 8;
1119     if (channelType == 0) {
1120         return UNSPECIFIED;
1121     } else if (centerFrequencyIndex2 == 0) {
1122         return CHAN_WIDTH_80MHZ;
1123     } else if (abs(centerFrequencyIndex1 - centerFrequencyIndex2) == freqValue) {
1124         return CHAN_WIDTH_160MHZ;
1125     } else {
1126         return CHAN_WIDTH_80MHZ_MHZ;
1127     }
1128 }
1129 
GetVhtCentFreq(int channelType,int centerFrequencyIndex)1130 static int GetVhtCentFreq(int channelType, int centerFrequencyIndex)
1131 {
1132     if (centerFrequencyIndex == 0 || channelType == 0) {
1133         return 0;
1134     } else {
1135         return ConvertChanToFreqMhz(centerFrequencyIndex, BAND_5_GHZ);
1136     }
1137 }
1138 
HexStringToString(const char * str,char * out)1139 static int HexStringToString(const char *str, char *out)
1140 {
1141     unsigned len = strlen(str);
1142     if ((len & 1) != 0) {
1143         return -1;
1144     }
1145     const int hexShiftNum = 4;
1146     for (unsigned i = 0, j = 0; i + 1 < len; ++i) {
1147         int8_t high = IsValidHexCharAndConvert(str[i]);
1148         int8_t low = IsValidHexCharAndConvert(str[++i]);
1149         if (high < 0 || low < 0) {
1150             return -1;
1151         }
1152         char tmp = ((high << hexShiftNum) | (low & 0x0F));
1153         out[j] = tmp;
1154         ++j;
1155     }
1156     return 0;
1157 }
1158 
GetChanWidthCenterFreqVht(ScanInfo * pcmd,ScanInfoElem * infoElem)1159 static bool GetChanWidthCenterFreqVht(ScanInfo *pcmd, ScanInfoElem* infoElem)
1160 {
1161     if ((pcmd == NULL) || (infoElem == NULL)) {
1162         HDF_LOGE("pcmd or infoElem is NULL.");
1163         return false;
1164     }
1165     if ((infoElem->content == NULL) || ((unsigned int)infoElem->size < VHT_INFO_SIZE)) {
1166         return false;
1167     }
1168     int channelType = infoElem->content[COLUMN_INDEX_ZERO] & UINT8_MASK;
1169     int centerFrequencyIndex1 = infoElem->content[COLUMN_INDEX_ONE] & UINT8_MASK;
1170     int centerFrequencyIndex2 = infoElem->content[COLUMN_INDEX_TWO] & UINT8_MASK;
1171     pcmd->isVhtInfoExist = 1;
1172     pcmd->channelWidth = GetVhtChanWidth(channelType, centerFrequencyIndex1, centerFrequencyIndex2);
1173     if ((unsigned int)pcmd->channelWidth == UNSPECIFIED) {
1174         return false;
1175     }
1176     pcmd->centerFrequency0 = GetVhtCentFreq(channelType, centerFrequencyIndex1);
1177     pcmd->centerFrequency1 = GetVhtCentFreq(channelType, centerFrequencyIndex2);
1178     return true;
1179 }
1180 
GetChanWidthCenterFreqHe(ScanInfo * pcmd,ScanInfoElem * infoElem)1181 static bool GetChanWidthCenterFreqHe(ScanInfo *pcmd, ScanInfoElem* infoElem)
1182 {
1183     if ((pcmd == NULL) || (infoElem == NULL)) {
1184         HDF_LOGE("pcmd or iesNeedParse is NULL.");
1185         return false;
1186     }
1187     if ((infoElem->content == NULL) || ((unsigned int)infoElem->size < (HE_OPER_BASIC_LEN + 1))) {
1188         return false;
1189     }
1190     if (infoElem->content[0] != EXT_HE_OPER_EID) {
1191         return false;
1192     }
1193     char* content = infoElem->content + 1;
1194     bool isVhtInfoExist = (content[COLUMN_INDEX_ONE] & VHT_OPER_INFO_EXTST_MASK) != 0;
1195     bool is6GhzInfoExist = (content[COLUMN_INDEX_TWO] & GHZ_HE_INFO_EXIST_MASK_6) != 0;
1196     bool coHostedBssPresent = (content[COLUMN_INDEX_ONE] & BSS_EXIST_MASK) != 0;
1197     int expectedLen = HE_OPER_BASIC_LEN + (isVhtInfoExist ? COLUMN_INDEX_THREE : 0) +
1198         (coHostedBssPresent ? 1 : 0) + (is6GhzInfoExist ? COLUMN_INDEX_FIVE : 0);
1199     pcmd->isHeInfoExist = 1;
1200     if (infoElem->size < expectedLen) {
1201         return false;
1202     }
1203     if (is6GhzInfoExist) {
1204         int startIndx = VHT_OPER_INFO_BEGIN_INDEX + (isVhtInfoExist ? COLUMN_INDEX_THREE : 0) +
1205             (coHostedBssPresent ? 1 : 0);
1206         int heChannelWidth = content[startIndx + 1] & GHZ_HE_WIDTH_MASK_6;
1207         int centerSegFreq0 = content[startIndx + COLUMN_INDEX_TWO] & UINT8_MASK;
1208         int centerSegFreq1 = content[startIndx + COLUMN_INDEX_THREE] & UINT8_MASK;
1209         pcmd->channelWidth = GetHeChanWidth(heChannelWidth, centerSegFreq0, centerSegFreq1);
1210         pcmd->centerFrequency0 = GetHeCentFreq(centerSegFreq0);
1211         pcmd->centerFrequency1 = GetHeCentFreq(centerSegFreq1);
1212         return true;
1213     }
1214     if (isVhtInfoExist) {
1215         struct ScanInfoElem vhtInformation = {0};
1216         vhtInformation.id = VHT_OPER_EID;
1217         vhtInformation.size = VHT_INFO_SIZE;
1218         vhtInformation.content = content + VHT_OPER_INFO_BEGIN_INDEX;
1219         return GetChanWidthCenterFreqVht(pcmd, &vhtInformation);
1220     }
1221     return false;
1222 }
1223 
GetChanWidthCenterFreqHt(ScanInfo * pcmd,ScanInfoElem * infoElem)1224 static bool GetChanWidthCenterFreqHt(ScanInfo *pcmd, ScanInfoElem* infoElem)
1225 {
1226     const int offsetBit = 0x3;
1227     if ((pcmd == NULL) || (infoElem == NULL)) {
1228         HDF_LOGE("pcmd or infoElem is NULL.");
1229         return false;
1230     }
1231     if ((infoElem->content == NULL) || ((unsigned int)infoElem->size < HT_INFO_SIZE)) {
1232         return false;
1233     }
1234     int secondOffsetChannel = infoElem->content[1] & offsetBit;
1235     pcmd->channelWidth = GetHtChanWidth(secondOffsetChannel);
1236     pcmd->centerFrequency0 = GetHtCentFreq0(pcmd->freq, secondOffsetChannel);
1237     pcmd->isHtInfoExist = 1;
1238     return true;
1239 }
1240 
GetChanMaxRates(ScanInfo * pcmd,ScanInfoElem * infoElem)1241 static bool GetChanMaxRates(ScanInfo *pcmd, ScanInfoElem* infoElem)
1242 {
1243     if ((pcmd == NULL) || (infoElem == NULL)) {
1244         HDF_LOGE("pcmd or infoElem is NULL.");
1245         return false;
1246     }
1247     if ((infoElem->content == NULL) || ((unsigned int)infoElem->size < SUPP_RATES_SIZE)) {
1248         return false;
1249     }
1250     int maxIndex = infoElem->size - 1;
1251     int maxRates = infoElem->content[maxIndex] & UINT8_MASK;
1252     pcmd->maxRates = maxRates;
1253     return true;
1254 }
1255 
GetChanExtMaxRates(ScanInfo * pcmd,ScanInfoElem * infoElem)1256 static bool GetChanExtMaxRates(ScanInfo *pcmd, ScanInfoElem* infoElem)
1257 {
1258     if ((pcmd == NULL) || (infoElem == NULL)) {
1259         HDF_LOGE("pcmd or infoElem is NULL.");
1260         return false;
1261     }
1262     if ((infoElem->content == NULL) || ((unsigned int)infoElem->size < EXT_SUPP_RATES_SIZE)) {
1263         return false;
1264     }
1265     int maxIndex = infoElem->size - 1;
1266     int maxRates = infoElem->content[maxIndex] & UINT8_MASK;
1267     pcmd->extMaxRates = maxRates;
1268     return true;
1269 }
1270 
GetChanWidthCenterFreq(ScanInfo * pcmd,struct NeedParseIe * iesNeedParse)1271 static void GetChanWidthCenterFreq(ScanInfo *pcmd, struct NeedParseIe* iesNeedParse)
1272 {
1273     if ((pcmd == NULL) || (iesNeedParse == NULL)) {
1274         HDF_LOGE("pcmd or iesNeedParse is NULL.");
1275         return;
1276     }
1277 
1278     if ((iesNeedParse->ieExtern != NULL) && GetChanWidthCenterFreqHe(pcmd, iesNeedParse->ieExtern)) {
1279         return;
1280     }
1281     if ((iesNeedParse->ieVhtOper != NULL) && GetChanWidthCenterFreqVht(pcmd, iesNeedParse->ieVhtOper)) {
1282         return;
1283     }
1284     if ((iesNeedParse->ieHtOper != NULL) && GetChanWidthCenterFreqHt(pcmd, iesNeedParse->ieHtOper)) {
1285         return;
1286     }
1287     if ((iesNeedParse->ieMaxRate != NULL) && GetChanMaxRates(pcmd, iesNeedParse->ieMaxRate)) {
1288         HDF_LOGE("pcmd maxRates is %{public}d.", pcmd->maxRates);
1289         return;
1290     }
1291     if ((iesNeedParse->ieExtMaxRate != NULL) && GetChanExtMaxRates(pcmd, iesNeedParse->ieExtMaxRate)) {
1292         HDF_LOGE("pcmd extMaxRates is %{public}d.", pcmd->extMaxRates);
1293         return;
1294     }
1295     if (iesNeedParse->ieErp != NULL) {
1296         HDF_LOGE("pcmd isErpExist is true.");
1297         pcmd->isErpExist = 1;
1298         return;
1299     }
1300     HDF_LOGE("GetChanWidthCenterFreq fail.");
1301     return;
1302 }
1303 
RecordIeNeedParse(unsigned int id,ScanInfoElem * ie,struct NeedParseIe * iesNeedParse)1304 static void RecordIeNeedParse(unsigned int id, ScanInfoElem* ie, struct NeedParseIe* iesNeedParse)
1305 {
1306     if (iesNeedParse == NULL) {
1307         return;
1308     }
1309     switch (id) {
1310         case EXT_EXIST_EID:
1311             iesNeedParse->ieExtern = ie;
1312             break;
1313         case VHT_OPER_EID:
1314             iesNeedParse->ieVhtOper = ie;
1315             break;
1316         case HT_OPER_EID:
1317             iesNeedParse->ieHtOper = ie;
1318             break;
1319         case SUPPORTED_RATES_EID:
1320             iesNeedParse->ieMaxRate = ie;
1321             break;
1322         case ERP_EID:
1323             iesNeedParse->ieErp = ie;
1324             break;
1325         case EXT_SUPPORTED_RATES_EID:
1326             iesNeedParse->ieExtMaxRate = ie;
1327             break;
1328         default:
1329             break;
1330     }
1331 }
1332 
GetInfoElems(int length,int end,char * srcBuf,ScanInfo * pcmd)1333 static void GetInfoElems(int length, int end, char *srcBuf, ScanInfo *pcmd)
1334 {
1335     int len;
1336     int start = end + 1;
1337     int last = end + 1;
1338     int lenValue = 2;
1339     int lastLength = 3;
1340     int remainingLength = length - start;
1341     int infoElemsSize = 0;
1342     struct NeedParseIe iesNeedParse = {NULL};
1343     ScanInfoElem* infoElemsTemp = (ScanInfoElem *)calloc(MAX_INFO_ELEMS_SIZE, sizeof(ScanInfoElem));
1344     if (infoElemsTemp == NULL) {
1345         return;
1346     }
1347     while (remainingLength > 1 && start < length) {
1348         if (srcBuf[start] == '[') {
1349             ++start;
1350             infoElemsTemp[infoElemsSize].id = atoi(srcBuf + start);
1351         }
1352         if (srcBuf[start] != ' ') {
1353             ++start;
1354         }
1355         if (srcBuf[last] != ']') {
1356             ++last;
1357             continue;
1358         }
1359         len = last - start - 1;
1360         infoElemsTemp[infoElemsSize].size = len / lenValue;
1361         infoElemsTemp[infoElemsSize].content = (char *)calloc(len / lenValue + 1, sizeof(char));
1362         if (infoElemsTemp[infoElemsSize].content == NULL) {
1363             break;
1364         }
1365         ++start;
1366         srcBuf[last] = '\0';
1367         HexStringToString(srcBuf + start, infoElemsTemp[infoElemsSize].content);
1368         if ((length - last) > lastLength) { // make sure there is no useless character
1369             last = last + 1;
1370         }
1371         start = last;
1372         remainingLength = length - last;
1373         RecordIeNeedParse(infoElemsTemp[infoElemsSize].id, &infoElemsTemp[infoElemsSize], &iesNeedParse);
1374         ++infoElemsSize;
1375     }
1376     GetChanWidthCenterFreq(pcmd, &iesNeedParse);
1377 
1378     // clear old infoElems first
1379     if (pcmd->infoElems != NULL) {
1380         for (int i = 0; i < pcmd->ieSize; i++) {
1381             if (pcmd->infoElems[i].content != NULL) {
1382                 free(pcmd->infoElems[i].content);
1383                 pcmd->infoElems[i].content = NULL;
1384             }
1385         }
1386         free(pcmd->infoElems);
1387         pcmd->infoElems = NULL;
1388     }
1389     pcmd->infoElems = infoElemsTemp;
1390     pcmd->ieSize = infoElemsSize;
1391     return;
1392 }
1393 
DelScanInfoLine(ScanInfo * pcmd,char * srcBuf,int length)1394 int DelScanInfoLine(ScanInfo *pcmd, char *srcBuf, int length)
1395 {
1396     int columnIndex = 0;
1397     int start = 0;
1398     int end = 0;
1399     int fail = 0;
1400     while (end < length) {
1401         if (srcBuf[end] != '\t') {
1402             ++end;
1403             continue;
1404         }
1405         srcBuf[end] = '\0';
1406         if (columnIndex == COLUMN_INDEX_ZERO) {
1407             if (strcpy_s(pcmd->bssid, sizeof(pcmd->bssid), srcBuf + start) != EOK) {
1408                 fail = 1;
1409                 break;
1410             }
1411         } else if (columnIndex == COLUMN_INDEX_ONE) {
1412             pcmd->freq = atoi(srcBuf + start);
1413         } else if (columnIndex == COLUMN_INDEX_TWO) {
1414             pcmd->siglv = atoi(srcBuf + start);
1415         } else if (columnIndex == COLUMN_INDEX_THREE) {
1416             if (strcpy_s(pcmd->flags, sizeof(pcmd->flags), srcBuf + start) != EOK) {
1417                 fail = 1;
1418                 break;
1419             }
1420         } else if (columnIndex == COLUMN_INDEX_FOUR) {
1421             if (strcpy_s(pcmd->ssid, sizeof(pcmd->ssid), srcBuf + start) != EOK) {
1422                 fail = 1;
1423                 break;
1424             }
1425             printf_decode((u8 *)pcmd->ssid, sizeof(pcmd->ssid), pcmd->ssid);
1426             GetInfoElems(length, end, srcBuf, pcmd);
1427             start = length;
1428             break;
1429         }
1430         ++columnIndex;
1431         ++end;
1432         start = end;
1433     }
1434     if (fail == 0 && start < length) {
1435         if (strcpy_s(pcmd->flags, sizeof(pcmd->flags), srcBuf + start) != EOK) {
1436             fail = 1;
1437         }
1438     }
1439     return fail;
1440 }
1441 
WpaCliCmdScanInfo(WifiWpaStaInterface * this,unsigned char * resultBuf,unsigned int * resultBufLen)1442 static int WpaCliCmdScanInfo(WifiWpaStaInterface *this, unsigned char *resultBuf,
1443     unsigned int *resultBufLen)
1444 {
1445     HDF_LOGI("enter WpaCliCmdScanInfo2");
1446     if (this == NULL || resultBuf == NULL || resultBufLen == NULL) {
1447         return -1;
1448     }
1449     char cmd[CMD_BUFFER_SIZE] = {0};
1450     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s SCAN_RESULTS", this->ifname) < 0) {
1451         HDF_LOGE("snprintf err");
1452         return -1;
1453     }
1454     if (WpaCliCmd(cmd, (char*)resultBuf, REPLY_BUF_LENGTH) != 0) {
1455         HDF_LOGE("WpaCliCmd SCAN_RESULTS fail");
1456         return -1;
1457     }
1458     *resultBufLen = strlen((char*)resultBuf);
1459     HDF_LOGI("WpaCliCmdScanInfo2, resultBufLen = %{public}d", *resultBufLen);
1460     return 0;
1461 }
1462 
WpaCliCmdGetSignalInfo(WifiWpaStaInterface * this,WpaSignalInfo * info)1463 static int WpaCliCmdGetSignalInfo(WifiWpaStaInterface *this, WpaSignalInfo *info)
1464 {
1465     if (this == NULL || info == NULL) {
1466         return -1;
1467     }
1468     char cmd[CMD_BUFFER_SIZE] = {0};
1469     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s SIGNAL_POLL", this->ifname) < 0) {
1470         HDF_LOGE("snprintf err");
1471         return -1;
1472     }
1473     char *buf = (char *)calloc(REPLY_BUF_LENGTH, sizeof(char));
1474     if (buf == NULL) {
1475         return -1;
1476     }
1477     if (WpaCliCmd(cmd, buf, REPLY_BUF_LENGTH) != 0) {
1478         free(buf);
1479         return -1;
1480     }
1481     char *savedPtr = NULL;
1482     char *token = strtok_r(buf, "=", &savedPtr);
1483     while (token != NULL) {
1484         if (strcmp(token, "RSSI") == 0) {
1485             token = strtok_r(NULL, "\n", &savedPtr);
1486             info->signal = atoi(token);
1487         } else if (strcmp(token, "LINKSPEED") == 0) {
1488             token = strtok_r(NULL, "\n", &savedPtr);
1489             info->txrate = atoi(token);
1490         } else if (strcmp(token, "NOISE") == 0) {
1491             token = strtok_r(NULL, "\n", &savedPtr);
1492             info->noise = atoi(token);
1493         } else if (strcmp(token, "FREQUENCY") == 0) {
1494             token = strtok_r(NULL, "\n", &savedPtr);
1495             info->frequency = atoi(token);
1496         } else {
1497             strtok_r(NULL, "\n", &savedPtr);
1498         }
1499         token = strtok_r(NULL, "=", &savedPtr);
1500     }
1501     free(buf);
1502     return 0;
1503 }
1504 
1505 /* mode: 0 - enabled, 1 - disabled. */
WpaCliCmdWpaSetPowerMode(WifiWpaStaInterface * this,bool mode)1506 static int WpaCliCmdWpaSetPowerMode(WifiWpaStaInterface *this, bool mode)
1507 {
1508     HDF_LOGI("Enter WpaCliCmdWpaSetPowerMode, mode:%{public}d.", mode);
1509     if (this == NULL) {
1510         HDF_LOGE("WpaCliCmdWpaSetPowerMode, this is NULL.");
1511         return -1;
1512     }
1513     char cmd[CMD_BUFFER_SIZE] = {0};
1514     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
1515     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s DRIVER POWERMODE %d",
1516         this->ifname, mode) < 0) {
1517         HDF_LOGE("WpaCliCmdWpaSetPowerMode, snprintf_s err");
1518         return -1;
1519     }
1520     return WpaCliCmd(cmd, buf, sizeof(buf));
1521 }
1522 
WpaCliCmdWpaSetSuspendMode(WifiWpaStaInterface * this,bool mode)1523 static int WpaCliCmdWpaSetSuspendMode(WifiWpaStaInterface *this, bool mode)
1524 {
1525     HDF_LOGI("Enter WpaCliCmdWpaSetSuspendMode, mode:%{public}d.", mode);
1526     if (this == NULL) {
1527         HDF_LOGE("WpaCliCmdWpaSetSuspendMode, this is NULL.");
1528         return -1;
1529     }
1530     char cmd[CMD_BUFFER_SIZE] = {0};
1531     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
1532     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s DRIVER SETSUSPENDMODE %d",
1533         this->ifname, mode) < 0) {
1534         HDF_LOGE("WpaCliCmdWpaSetSuspendMode, snprintf_s err");
1535         return -1;
1536     }
1537     return WpaCliCmd(cmd, buf, sizeof(buf));
1538 }
1539 
WpaCliCmdStaShellCmd(WifiWpaStaInterface * this,const char * params)1540 static int WpaCliCmdStaShellCmd(WifiWpaStaInterface *this, const char *params)
1541 {
1542     if (this == NULL || params == NULL) {
1543         return -1;
1544     }
1545     char cmd[CMD_BUFFER_SIZE] = {0};
1546     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
1547     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s STA_SHELL %s",
1548         this->ifname, params) < 0) {
1549         HDF_LOGE("WpaCliCmdStaShellCmd, snprintf_s err");
1550         return -1;
1551     }
1552     return WpaCliCmd(cmd, buf, sizeof(buf));
1553 }
1554 
GetWifiStaInterface(const char * name)1555 WifiWpaStaInterface *GetWifiStaInterface(const char *name)
1556 {
1557     WifiWpaStaInterface *p = g_wpaStaInterface;
1558     char staNo[STA_NO_LEN + 1] = {0};
1559     while (p != NULL) {
1560         if (strcmp(p->ifname, name) == 0) {
1561             return p;
1562         }
1563         p = p->next;
1564     }
1565     p = (WifiWpaStaInterface *)calloc(1, sizeof(WifiWpaStaInterface));
1566     if (p == NULL) {
1567         return NULL;
1568     }
1569     if (strncpy_s(p->ifname, sizeof(p->ifname), name, sizeof(p->ifname)) != EOK) {
1570         HDF_LOGE("GetWifiStaInterface, strncpy ifname err");
1571         free(p);
1572         p = NULL;
1573         return NULL;
1574     }
1575     if (strncpy_s(staNo, sizeof(staNo), name + strlen("wlan"), STA_NO_LEN) != EOK) {
1576         HDF_LOGE("GetWifiStaInterface, strncpy stano err");
1577         free(p);
1578         p = NULL;
1579         return NULL;
1580     }
1581     p->staNo =  atoi(staNo);
1582     p->wpaCliCmdStatus = WpaCliCmdStatus;
1583     p->wpaCliCmdAddNetworks = WpaCliCmdAddNetworks;
1584     p->wpaCliCmdReconnect = WpaCliCmdReconnect;
1585     p->wpaCliCmdReassociate = WpaCliCmdReassociate;
1586     p->wpaCliCmdDisconnect = WpaCliCmdDisconnect;
1587     p->wpaCliCmdSaveConfig = WpaCliCmdSaveConfig;
1588     p->wpaCliCmdSetNetwork = WpaCliCmdSetNetwork;
1589     p->wpaCliCmdEnableNetwork = WpaCliCmdEnableNetwork;
1590     p->wpaCliCmdSelectNetwork = WpaCliCmdSelectNetwork;
1591     p->wpaCliCmdDisableNetwork = WpaCliCmdDisableNetwork;
1592     p->wpaCliCmdRemoveNetwork = WpaCliCmdRemoveNetwork;
1593     p->wpaCliCmdGetNetwork = WpaCliCmdGetNetwork;
1594     p->wpaCliCmdWpsPbc = WpaCliCmdWpsPbc;
1595     p->wpaCliCmdWpsPin = WpaCliCmdWpsPin;
1596     p->wpaCliCmdWpsCancel = WpaCliCmdWpsCancel;
1597     p->wpaCliCmdPowerSave = WpaCliCmdPowerSave;
1598     p->wpaCliCmdSetRoamConfig = WpaCliCmdSetRoamConfig;
1599     p->wpaCliCmdSetCountryCode = WpaCliCmdSetCountryCode;
1600     p->wpaCliCmdGetCountryCode = WpaCliCmdGetCountryCode;
1601     p->wpaCliCmdSetAutoConnect = WpaCliCmdSetAutoConnect;
1602     p->wpaCliCmdWpaBlockListClear = WpaCliCmdWpaBlockListClear;
1603     p->wpaCliCmdListNetworks = WpaCliCmdListNetworks;
1604     p->wpaCliCmdScan = WpaCliCmdScan;
1605     p->wpaCliCmdScanInfo = WpaCliCmdScanInfo;
1606     p->wpaCliCmdGetSignalInfo = WpaCliCmdGetSignalInfo;
1607     p->wpaCliCmdWpaSetSuspendMode = WpaCliCmdWpaSetSuspendMode;
1608     p->wpaCliCmdWpaSetPowerMode = WpaCliCmdWpaSetPowerMode;
1609     p->wpaCliCmdGetScanSsid = WpaCliCmdGetScanSsid;
1610     p->wpaCliCmdGetPskPassphrase = WpaCliCmdGetPskPassphrase;
1611     p->wpaCliCmdGetPsk = WpaCliCmdGetPsk;
1612     p->wpaCliCmdWepKey = WpaCliCmdWepKey;
1613     p->wpaCliCmdWepKeyTxKeyIdx = WpaCliCmdWepKeyTxKeyIdx;
1614     p->wpaCliCmdGetRequirePmf = WpaCliCmdGetRequirePmf;
1615     p->wpaCliCmdGetConnectionCapabilities = WpaCliCmdGetConnectionCapabilities;
1616     p->wpaCliCmdStaShellCmd = WpaCliCmdStaShellCmd;
1617     p->next = g_wpaStaInterface;
1618     g_wpaStaInterface = p;
1619 
1620     return p;
1621 }
1622 
ReleaseWifiStaInterface(int staNo)1623 void ReleaseWifiStaInterface(int staNo)
1624 {
1625     char name[MAX_NAME_LEN] = {0};
1626     if (snprintf_s(name, sizeof(name), sizeof(name) - 1, "wlan%d", staNo) < 0) {
1627         HDF_LOGE("snprintf error");
1628         return;
1629     }
1630     WifiWpaStaInterface *p = g_wpaStaInterface;
1631     WifiWpaStaInterface *prev = NULL;
1632     while (p != NULL) {
1633         if (strcmp(p->ifname, name) == 0) {
1634             break;
1635         }
1636         prev = p;
1637         p = p->next;
1638     }
1639     if (p == NULL) {
1640         return;
1641     }
1642     if (prev == NULL) {
1643         g_wpaStaInterface = p->next;
1644     } else {
1645         prev->next = p->next;
1646     }
1647     free(p);
1648     return;
1649 }
1650 
TraversalWifiStaInterface(void)1651 WifiWpaStaInterface *TraversalWifiStaInterface(void)
1652 {
1653     return g_wpaStaInterface;
1654 }
1655 
GetStaInterfaceNo(const char * ifName)1656 int GetStaInterfaceNo(const char *ifName)
1657 {
1658     WifiWpaStaInterface *p = g_wpaStaInterface;
1659     while (p != NULL) {
1660         if (strcmp(p->ifname, ifName) == 0) {
1661             return p->staNo;
1662         }
1663         p = p->next;
1664     }
1665     return -1;
1666 }
1667