• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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  * Description: wifi softap APIs
15  */
16 
17 #include "utils/common.h"
18 #include "wifi_api.h"
19 #include "utils/eloop.h"
20 #include "wpa_supplicant_i.h"
21 #include "wpa_cli_rtos.h"
22 #include "common/ieee802_11_common.h"
23 #include "config_ssid.h"
24 #include "driver_soc.h"
25 #include "securec.h"
26 
27 static int g_softap_pairwise = 0;
28 
is_hex_char(char ch)29 static int is_hex_char(char ch)
30 {
31 	if (((ch >= '0') && (ch <= '9')) ||
32 		((ch >= 'A') && (ch <= 'F')) ||
33 		((ch >= 'a') && (ch <= 'f'))) {
34 		return EXT_WIFI_OK;
35 	}
36 	return EXT_WIFI_FAIL;
37 }
38 
39 
is_hex_string(const char * data,size_t len)40 int is_hex_string(const char *data, size_t len)
41 {
42 	size_t i;
43 	if ((data == NULL) || (len == 0))
44 		return EXT_WIFI_FAIL;
45 	for (i = 0; i < len; i++) {
46 		if (is_hex_char(data[i]) == EXT_WIFI_FAIL)
47 			return EXT_WIFI_FAIL;
48 	}
49 	return EXT_WIFI_OK;
50 }
51 
52 
softap_start_precheck(void)53 static int softap_start_precheck(void)
54 {
55 	int i;
56 	unsigned int int_save;
57 	unsigned int ret = (unsigned int)(los_count_wifi_dev_in_use() >= WPA_DOUBLE_IFACE_WIFI_DEV_NUM);
58 
59 	os_intlock(&int_save);
60 	for (i = 0; i < WPA_MAX_WIFI_DEV_NUM; i++) {
61 		if (g_wifi_dev[i] != NULL)
62 			ret |= (unsigned int)(g_wifi_dev[i]->iftype > EXT_WIFI_IFTYPE_STATION);
63 	}
64 	ret |= (unsigned int)(g_mesh_flag == WPA_FLAG_ON);
65 	os_intrestore(int_save);
66 	return ret ? EXT_WIFI_FAIL : EXT_WIFI_OK;
67 }
68 
wifi_softap_check_wep_key(wifi_softap_config * hconf)69 static int wifi_softap_check_wep_key(wifi_softap_config *hconf)
70 {
71     /* check wep key len and ssid len */
72     if ((os_strlen((char *)hconf->key) != WPA_WEP40_KEY_LEN) &&
73         (os_strlen((char *)hconf->key) != WPA_WEP104_KEY_LEN) &&
74         (os_strlen((char *)hconf->key) != WPA_WEP40_HEX_KEY_LEN) &&
75         (os_strlen((char *)hconf->key) != WPA_WEP104_HEX_KEY_LEN)) {
76         wpa_error_log0(MSG_ERROR, "Invalid wep ssid or wep key length! \n");
77         return EXT_WIFI_FAIL;
78     }
79 
80     /* check wep hex key */
81     if (((os_strlen((char *)hconf->key) == WPA_WEP40_HEX_KEY_LEN) &&
82         (is_hex_string((char *)hconf->key, WPA_WEP40_HEX_KEY_LEN) == EXT_WIFI_FAIL))) {
83         wpa_error_log0(MSG_ERROR, "Invalid wep40 HEX passphrase character");
84         return EXT_WIFI_FAIL;
85     } else if (((os_strlen((char *)hconf->key) == WPA_WEP104_HEX_KEY_LEN) &&
86         (is_hex_string((char *)hconf->key, WPA_WEP104_HEX_KEY_LEN) == EXT_WIFI_FAIL))) {
87         wpa_error_log0(MSG_ERROR, "Invalid wep104 HEX passphrase character");
88         return EXT_WIFI_FAIL;
89     }
90     return EXT_WIFI_OK;
91 }
92 
wifi_softap_check_key_config(wifi_softap_config * hconf)93 static int wifi_softap_check_key_config(wifi_softap_config *hconf)
94 {
95     /* check ssid length */
96     if (os_strlen((char *)hconf->ssid) > WPA_MAX_ESSID_LEN) {
97         wpa_error_log0(MSG_ERROR, "Invalid ssid length! \n");
98         return EXT_WIFI_FAIL;
99     }
100 
101     /* check WEP key length */
102     if (hconf->authmode == EXT_WIFI_SECURITY_WEP || hconf->authmode == EXT_WIFI_SECURITY_WEP_OPEN) {
103         if (wifi_softap_check_wep_key(hconf) == EXT_WIFI_FAIL) {
104             wpa_error_log0(MSG_ERROR, "Invalid wep passphrase character");
105             return EXT_WIFI_FAIL;
106         }
107     } else if ((wifi_is_need_psk(hconf->authmode) == 1) && ((os_strlen((char *)hconf->key) < WPA_MIN_KEY_LEN) ||
108         (os_strlen((char *)hconf->key) > WPA_MAX_KEY_LEN))) {
109         /* check other authmode key length expect OPEN and OWE */
110         wpa_error_log0(MSG_ERROR, "Invalid key length! \n");
111         return EXT_WIFI_FAIL;
112     }
113 
114     /* check HEX key */
115     if ((os_strlen((char *)hconf->key) == WPA_MAX_KEY_LEN) &&
116         (is_hex_string((char *)hconf->key, WPA_MAX_KEY_LEN) == EXT_WIFI_FAIL)) {
117         wpa_error_log0(MSG_ERROR, "Invalid passphrase character");
118         return EXT_WIFI_FAIL;
119     }
120 
121     return EXT_WIFI_OK;
122 }
123 
wifi_softap_set_security(wifi_softap_config * hconf)124 static int wifi_softap_set_security(wifi_softap_config *hconf)
125 {
126     switch (hconf->authmode) {
127         case EXT_WIFI_SECURITY_OPEN:
128             hconf->auth_algs = 0;
129             hconf->wpa_key_mgmt = (int)WPA_KEY_MGMT_NONE;
130             break;
131 #ifdef CONFIG_OWE
132         case EXT_WIFI_SECURITY_OWE:
133             hconf->wpa_key_mgmt = (int)WPA_KEY_MGMT_OWE;
134             hconf->wpa = 2; /* 2: RSN */
135             hconf->wpa_pairwise = (int)WPA_CIPHER_CCMP;
136             break;
137 #endif /* CONFIG_OWE  */
138         case EXT_WIFI_SECURITY_WEP:
139             hconf->auth_algs = 2;   /* 2表示WEP SHARED加密 */
140             hconf->wep_idx = 0; /* 配置第一个密钥 */
141             break;
142         case EXT_WIFI_SECURITY_WEP_OPEN:
143             hconf->auth_algs = 1;   /* 1表示WEP OPEN加密 */
144             hconf->wep_idx = 0; /* 配置第一个密钥 */
145             break;
146         case EXT_WIFI_SECURITY_WPA2PSK:
147             hconf->wpa_key_mgmt = (int)WPA_KEY_MGMT_PSK;
148             hconf->wpa = 2; /* 2: WPA2-PSK */
149             if (hconf->wpa_pairwise == 0)
150                 hconf->wpa_pairwise = (int)WPA_CIPHER_CCMP;
151             break;
152         case EXT_WIFI_SECURITY_WPAPSK_WPA2PSK_MIX:
153             hconf->wpa_key_mgmt = (int)WPA_KEY_MGMT_PSK;
154             hconf->wpa = 3; /* 3: WPA2-PSK|WPA-PSK */
155             if (hconf->wpa_pairwise == 0)
156                 hconf->wpa_pairwise = (int)WPA_CIPHER_CCMP;
157             break;
158 #ifdef CONFIG_HOSTAPD_WPA3
159         case EXT_WIFI_SECURITY_SAE:
160             hconf->wpa_key_mgmt = (int)WPA_KEY_MGMT_SAE;
161             hconf->wpa = 2; /* 2: RSN */
162             hconf->wpa_pairwise = (int)WPA_CIPHER_CCMP;
163             break;
164         case EXT_WIFI_SECURITY_WPA3_WPA2_PSK_MIX:
165             hconf->wpa_key_mgmt = (int)(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK);
166             hconf->wpa = 2; /* 2: RSN */
167             hconf->wpa_pairwise = (int)WPA_CIPHER_CCMP;
168             break;
169 #endif /* CONFIG_HOSTAPD_WPA3  */
170         default:
171             wpa_error_log1(MSG_ERROR, "error, Unsupported authmode: %d \n", (int)hconf->authmode);
172             hconf->auth_algs = 0;
173             hconf->wpa_key_mgmt = (int)WPA_KEY_MGMT_NONE;
174             return EXT_WIFI_FAIL;
175     }
176     return EXT_WIFI_OK;
177 }
178 
179 #if defined(CONFIG_HOSTAPD_WPA3) || defined(CONFIG_OWE)
wifi_pmf_set(wifi_softap_config * hconf)180 static void wifi_pmf_set(wifi_softap_config *hconf)
181 {
182     if ((hconf->authmode == EXT_WIFI_SECURITY_SAE) || (hconf->authmode == EXT_WIFI_SECURITY_OWE))
183         g_ap_opt_set.ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
184     else if (hconf->authmode == EXT_WIFI_SECURITY_WPA3_WPA2_PSK_MIX)
185         g_ap_opt_set.ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
186 }
187 #endif /* defined(CONFIG_HOSTAPD_WPA3) || defined(CONFIG_OWE) */
188 
189 #ifdef CONFIG_HOSTAPD_WPA3
wifi_sae_pwe_set(wifi_softap_config * hconf)190 static void wifi_sae_pwe_set(wifi_softap_config *hconf)
191 {
192     if (hconf->authmode == EXT_WIFI_SECURITY_SAE) {
193 		if (g_ap_opt_set.sae_pwe == WIFI_SAE_PWE_UNSPECIFIED) {
194 			g_ap_opt_set.sae_pwe = WIFI_SAE_PWE_BOTH;
195 		}
196 	} else {
197 		if (g_ap_opt_set.sae_pwe == WIFI_SAE_PWE_UNSPECIFIED) {
198 			g_ap_opt_set.sae_pwe = WIFI_SAE_PWE_HUNT_AND_PECK;
199 		}
200 	}
201 }
202 
203 #endif /* CONFIG_HOSTAPD_WPA3 */
204 
wifi_softap_set_config(wifi_softap_config * hconf)205 static int wifi_softap_set_config(wifi_softap_config *hconf)
206 {
207 	char *res = NULL;
208 	char tmp_ssid[EXT_WIFI_MAX_SSID_LEN + 1 + 2] = { 0 }; /* 1: string terminator; 2: two Double quotes */
209 	size_t len  = 0;
210 	int ret;
211 	errno_t rc;
212 
213 	if (hconf == NULL) {
214 		wpa_error_log0(MSG_ERROR, " ---> ### los_softap_set_config error: the hconf is NULL . \n\r");
215 		return EXT_WIFI_FAIL;
216 	}
217 	if (wifi_channel_check((unsigned char)hconf->channel_num) == EXT_WIFI_FAIL) {
218 		wpa_error_log0(MSG_ERROR, "Invalid channel_num! \n");
219 		return EXT_WIFI_FAIL;
220 	}
221 
222 	ret = snprintf_s(tmp_ssid, sizeof(tmp_ssid), sizeof(tmp_ssid) - 1, "\"%s\"", hconf->ssid);
223 	if (ret < 0)
224 		return EXT_WIFI_FAIL;
225 	rc = memset_s(hconf->ssid, sizeof(hconf->ssid), 0, sizeof(hconf->ssid));
226 	if (rc != EOK) {
227 		wpa_error_log0(MSG_ERROR, "los_softap_set_config: memset_s failed");
228 		return EXT_WIFI_FAIL;
229 	}
230 
231 	res = wpa_config_parse_string(tmp_ssid, &len);
232 	if ((res != NULL) && (len <= SSID_MAX_LEN)) {
233 		rc = memcpy_s(hconf->ssid, (size_t)sizeof(hconf->ssid), res, len);
234 		if (rc != EOK) {
235 			wpa_error_log0(MSG_ERROR, "los_softap_set_config: memcpy_s failed");
236 			ret = EXT_WIFI_FAIL;
237 			goto AP_CONFIG_PRE_CHECK_OUT;
238 		}
239 	} else {
240 		wpa_error_log0(MSG_ERROR, "los_softap_config_pre_check: wpa_config_parse_string failed");
241 		ret = EXT_WIFI_FAIL;
242 		goto AP_CONFIG_PRE_CHECK_OUT;
243 	}
244 #if defined(CONFIG_HOSTAPD_WPA3) || defined(CONFIG_OWE)
245 	wifi_pmf_set(hconf);
246 #endif /* defined(CONFIG_HOSTAPD_WPA3) || defined(CONFIG_OWE) */
247 #ifdef CONFIG_HOSTAPD_WPA3
248 #ifndef CONFIG_SAE_NO_PW_ID
249 	wifi_sae_pwe_set(hconf);
250 #endif /* CONFIG_SAE_NO_PW_ID */
251 #endif /* CONFIG_HOSTAPD_WPA3 */
252     if ((wifi_softap_check_key_config(hconf) != EXT_WIFI_OK) || (wifi_softap_set_security(hconf) != EXT_WIFI_OK)) {
253         ret = EXT_WIFI_FAIL;
254         goto AP_CONFIG_PRE_CHECK_OUT;
255     }
256     ret = EXT_WIFI_OK;
257 
258 AP_CONFIG_PRE_CHECK_OUT:
259 	if (res != NULL) {
260 		os_free(res);
261 	}
262 	return ret;
263 }
264 
wifi_softap_start(wifi_softap_config * hconf,char * ifname,int * len)265 static int wifi_softap_start(wifi_softap_config *hconf, char *ifname, int *len)
266 {
267 	struct ext_wifi_dev *wifi_dev = NULL;
268 	errno_t rc;
269 
270 	if (softap_start_precheck() != EXT_WIFI_OK) {
271 		wpa_error_log0(MSG_ERROR, "wifi_softap_start: precheck fail!");
272 		return EXT_WIFI_FAIL;
273 	}
274 
275 	if (wifi_softap_set_config(hconf) != EXT_WIFI_OK) {
276 		wpa_error_log0(MSG_ERROR, "wifi_softap_start: set_config fail!");
277 		return EXT_WIFI_FAIL;
278 	}
279 
280     /* Softap协议模式默认使用11ax */
281     if (g_ap_opt_set.hw_mode == WIFI_MODE_UNDEFINE) {
282         g_ap_opt_set.hw_mode = WIFI_MODE_11B_G_N_AX;
283     }
284 
285 	(void)memcpy_s(&g_global_conf, sizeof(struct hostapd_conf), hconf, sizeof(struct hostapd_conf));
286 	wifi_dev = wifi_dev_creat(EXT_WIFI_IFTYPE_AP, g_ap_opt_set.hw_mode);
287 	if (wifi_dev == NULL) {
288 		wpa_error_log0(MSG_ERROR, "wifi_softap_start: wifi_dev_creat failed.");
289 		return EXT_WIFI_FAIL;
290 	}
291 	if ((los_set_wifi_dev(wifi_dev) != EXT_WIFI_OK) || (*len < wifi_dev->ifname_len + 1))
292 		goto WIFI_AP_ERROR;
293 	rc = memcpy_s(ifname, (size_t)(*len), wifi_dev->ifname, (size_t)wifi_dev->ifname_len);
294 	if (rc != EOK) {
295 		wpa_error_log0(MSG_ERROR, "wifi_softap_start: memcpy_s failed");
296 		goto WIFI_AP_ERROR;
297 	}
298 	ifname[wifi_dev->ifname_len] = '\0';
299 	*len = wifi_dev->ifname_len;
300 	if (wifi_wpa_start(wifi_dev) == EXT_WIFI_OK) {
301 		return EXT_WIFI_OK;
302 	}
303 WIFI_AP_ERROR:
304 	(void)wal_deinit_drv_wlan_netdev(wifi_dev->ifname);
305 	los_free_wifi_dev(wifi_dev);
306 	return EXT_WIFI_FAIL;
307 }
308 
wifi_softap_config_check(const ext_wifi_softap_config * conf,const char * ifname,const int * len)309 static int wifi_softap_config_check(const ext_wifi_softap_config *conf, const char *ifname, const int *len)
310 {
311 	if ((conf == NULL) || (ifname == NULL) || (len == NULL)) {
312 		wpa_error_log0(MSG_ERROR, "wifi_softap_config_check: invalid param");
313 		return EXT_WIFI_FAIL;
314 	}
315 
316 	if (strnlen(conf->ssid, EXT_WIFI_MAX_SSID_LEN + 1) > EXT_WIFI_MAX_SSID_LEN) {
317 		wpa_error_log0(MSG_ERROR, "wifi_softap_config_check: invalid ssid length.");
318 		return EXT_WIFI_FAIL;
319 	}
320 
321 	if (conf->channel_num > WPA_24G_CHANNEL_NUMS) {
322 		wpa_error_log0(MSG_ERROR, "wifi_softap_config_check: invalid channel number!.");
323 		return EXT_WIFI_FAIL;
324 	}
325 
326 	if ((conf->ssid_hidden < 0) || (conf->ssid_hidden > 1)) {
327 		wpa_error_log0(MSG_ERROR, "wifi_softap_config_check: invalid ignore_broadcast_ssid.");
328 		return EXT_WIFI_FAIL;
329 	}
330 
331 	if (strnlen(conf->key, EXT_WIFI_AP_KEY_LEN + 1) > EXT_WIFI_AP_KEY_LEN) {
332 		wpa_error_log0(MSG_ERROR, "wifi_softap_config_check: invalid key.");
333 		return EXT_WIFI_FAIL;
334 	}
335 #ifdef CONFIG_HOSTAPD_WPA3
336 	if ((conf->authmode >= EXT_WIFI_SECURITY_UNKNOWN) || (conf->authmode == EXT_WIFI_SECURITY_WPA) ||
337 		(conf->authmode == EXT_WIFI_SECURITY_WPA2)) {
338 		wpa_error_log0(MSG_ERROR, "wifi_softap_config_check Invalid authmode.");
339 		return EXT_WIFI_FAIL;
340 	}
341 	/* The length of the password is 8 ~ 63 in wpa3 or wpa2/wpa3 encryption */
342 	if ((conf->authmode == EXT_WIFI_SECURITY_SAE) ||
343 	    (conf->authmode == EXT_WIFI_SECURITY_WPA3_WPA2_PSK_MIX)) {
344 		if ((strlen(conf->key) < WPA_MIN_KEY_LEN) || (strlen(conf->key) > WPA_MAX_KEY_LEN - 1)) {
345 			wpa_error_log0(MSG_ERROR, "wifi_softap_config_check Invalid key len.");
346 			return EXT_WIFI_FAIL;
347 		}
348 		if ((conf->pairwise != EXT_WIFI_PAIRWISE_AES) && (conf->pairwise != EXT_WIFI_PARIWISE_UNKNOWN)) {
349 			wpa_error_log0(MSG_ERROR, "wifi_softap_config_check Invalid pairwise.");
350 			return EXT_WIFI_FAIL;
351 		}
352 	}
353 #else
354 	if (conf->authmode > EXT_WIFI_SECURITY_WPAPSK_WPA2PSK_MIX) {
355 		wpa_error_log0(MSG_ERROR, "wifi_softap_config_check Invalid authmode.");
356 		return EXT_WIFI_FAIL;
357 	}
358 #endif /* CONFIG_HOSTAPD_WPA3 */
359 	return EXT_WIFI_OK;
360 }
361 
uapi_wifi_softap_set_pairwise(int pairwise)362 int uapi_wifi_softap_set_pairwise(int pairwise)
363 {
364     if (pairwise > WPA_CIPHER_GTK_NOT_USED) {
365         wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_set_pairwise: invalid pairwise options.");
366         return EXT_WIFI_FAIL;
367     }
368 
369     g_softap_pairwise = pairwise;
370     return EXT_WIFI_OK;
371 }
372 
uapi_wifi_softap_start(ext_wifi_softap_config * conf,char * ifname,int * len)373 int uapi_wifi_softap_start(ext_wifi_softap_config *conf, char *ifname, int *len)
374 {
375 	struct hostapd_conf hapd_conf = { 0 };
376 	errno_t rc;
377 
378 	if (wifi_softap_config_check(conf, ifname, len) == EXT_WIFI_FAIL)
379 		return EXT_WIFI_FAIL;
380 
381 	if (try_set_lock_flag() == EXT_WIFI_FAIL) {
382 		wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_start: wifi dev start or stop is running.");
383 		return EXT_WIFI_FAIL;
384 	}
385 
386 	rc = strcpy_s(hapd_conf.driver, MAX_DRIVER_NAME_LEN, "soc");
387 	if (rc != EOK)
388 		goto WIFI_AP_FAIL;
389 
390 	hapd_conf.channel_num = conf->channel_num;
391 	rc = memcpy_s(hapd_conf.ssid, (size_t)sizeof(hapd_conf.ssid), conf->ssid, (size_t)(strlen(conf->ssid) + 1));
392 	if (rc != EOK)
393 		goto WIFI_AP_FAIL;
394 	hapd_conf.ignore_broadcast_ssid = conf->ssid_hidden;
395 	hapd_conf.authmode = conf->authmode;
396 
397     if (wifi_is_need_psk(conf->authmode) == 1) {
398 		rc = memcpy_s((char *)hapd_conf.key, (size_t)sizeof(hapd_conf.key), conf->key, (size_t)(strlen(conf->key) + 1));
399 		if (rc != EOK)
400 			goto WIFI_AP_FAIL;
401 	}
402 
403 	if (g_softap_pairwise != 0) {
404         hapd_conf.wpa_pairwise = (int)g_softap_pairwise;
405     } else if ((hapd_conf.authmode == EXT_WIFI_SECURITY_WPA2PSK) ||
406 	    (hapd_conf.authmode == EXT_WIFI_SECURITY_WPAPSK_WPA2PSK_MIX)) { // pairwise
407 		if (conf->pairwise == EXT_WIFI_PAIRWISE_TKIP)
408 			hapd_conf.wpa_pairwise = (int)WPA_CIPHER_TKIP;
409 		else if ((conf->pairwise == EXT_WIFI_PAIRWISE_AES) || (conf->pairwise == EXT_WIFI_PARIWISE_UNKNOWN))
410 			hapd_conf.wpa_pairwise = (int)WPA_CIPHER_CCMP;
411 		else if (conf->pairwise == EXT_WIFI_PAIRWISE_TKIP_AES_MIX)
412 			hapd_conf.wpa_pairwise = (int)(WPA_CIPHER_TKIP | WPA_CIPHER_CCMP);
413 		else if (conf->pairwise == EXT_WIFI_PAIRWISE_CCMP256)
414 			hapd_conf.wpa_pairwise = (int)(WPA_CIPHER_CCMP_256);
415 		else {
416 			wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_start: invalid encryption.");
417 			goto WIFI_AP_FAIL;
418 		}
419 	}
420 	if (wifi_softap_start(&hapd_conf, ifname, len) != EXT_WIFI_OK) {
421 		wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_start: softap start failed.");
422 		goto WIFI_AP_FAIL;
423 	}
424 	(void)memset_s(&hapd_conf, sizeof(hapd_conf), 0, sizeof(hapd_conf));
425 	clr_lock_flag();
426 	return EXT_WIFI_OK;
427 WIFI_AP_FAIL:
428 	(void)memset_s(&hapd_conf, sizeof(hapd_conf), 0, sizeof(hapd_conf));
429 	clr_lock_flag();
430 	return EXT_WIFI_FAIL;
431 }
432 
uapi_wifi_softap_stop(void)433 int uapi_wifi_softap_stop(void)
434 {
435 	errno_t rc;
436 	int ret;
437 	unsigned int ret_val;
438 	struct ext_wifi_dev *wifi_dev  = NULL;
439 	char ifname[WIFI_IFNAME_MAX_SIZE + 1] = {0};
440 
441 	if (try_set_lock_flag() == EXT_WIFI_FAIL) {
442 		wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_start: wifi dev start or stop is running.");
443 		return EXT_WIFI_FAIL;
444 	}
445 
446 	wifi_dev = los_get_wifi_dev_by_iftype(EXT_WIFI_IFTYPE_AP);
447 	if (wifi_dev == NULL) {
448 		wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_stop: get wifi dev failed\n");
449 		goto WIFI_AP_STOP_EXIT;
450 	}
451 	g_ap_sta_info = NULL;
452 	g_softap_pairwise = 0;
453 	(void)memset_s(&g_global_conf, sizeof(g_global_conf), 0, sizeof(g_global_conf));
454 	rc = memset_s(&g_ap_opt_set, sizeof(struct wifi_ap_opt_set), 0, sizeof(struct wifi_ap_opt_set));
455 	if (rc != EOK)
456 		goto WIFI_AP_STOP_EXIT;
457 	rc = memcpy_s(ifname, (size_t)WIFI_IFNAME_MAX_SIZE, wifi_dev->ifname, (size_t)wifi_dev->ifname_len);
458 	if (rc != EOK)
459 		goto WIFI_AP_STOP_EXIT;
460 	(void)os_event_clear(g_softap_event, ~WPA_EVENT_AP_STOP_OK);
461 	wpa_error_log0(MSG_ERROR, "os_event_clear WPA_EVENT_AP_STOP_OK");
462 
463 	if (wpa_cli_terminate(NULL, ELOOP_TASK_HOSTAPD) != EXT_WIFI_OK) {
464 		wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_stop: wpa_cli_terminate failed");
465 		goto WIFI_AP_STOP_EXIT;
466 	}
467 	(void)os_event_read(g_softap_event, WPA_EVENT_AP_STOP_OK, &ret_val,
468 	                    WIFI_WAITMODE_OR | WIFI_WAITMODE_CLR, WIFI_WAIT_FOREVER);
469 	if (ret_val == WPA_EVENT_AP_STOP_OK)
470 		wpa_error_log0(MSG_ERROR, "os_event_read WPA_EVENT_AP_STOP_OK success");
471 	else
472 		wpa_error_log1(MSG_ERROR, "os_event_read WPA_EVENT_AP_STOP_OK failed ret_val = %x", ret_val);
473 
474 	ret = wal_deinit_drv_wlan_netdev(ifname);
475 	if (ret != EXT_SUCC)
476 		wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_stop: wal_deinit_drv_wlan_netdev failed!");
477 
478 	clr_lock_flag();
479 	return ret;
480 WIFI_AP_STOP_EXIT:
481 	clr_lock_flag();
482 	return EXT_WIFI_FAIL;
483 }
484 
uapi_wifi_softap_deauth_sta(const unsigned char * addr,unsigned char addr_len)485 int uapi_wifi_softap_deauth_sta(const unsigned char *addr, unsigned char addr_len)
486 {
487 	struct hostapd_data *hapd      = NULL;
488 	struct ext_wifi_dev *wifi_dev = NULL;
489 	char addr_txt[EXT_WIFI_TXT_ADDR_LEN + 1] = { 0 };
490 	int ret;
491 	unsigned int ret_val;
492 
493 	if ((addr_len != ETH_ALEN) || (addr == NULL)) {
494 		wpa_error_log0(MSG_ERROR, "Invalid addr.");
495 		return EXT_WIFI_FAIL;
496 	}
497 
498 	wifi_dev = wifi_dev_get(EXT_WIFI_IFTYPE_AP);
499 	if ((wifi_dev == NULL) || (wifi_dev->priv == NULL)) {
500 		wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_deauth_sta: get wifi dev failed.");
501 		return EXT_WIFI_FAIL;
502 	}
503 
504 	hapd = wifi_dev->priv;
505 	if (hapd == NULL) {
506 		wpa_error_log0(MSG_ERROR, "hapd get fail.");
507 		return EXT_WIFI_FAIL;
508 	}
509 	ret = snprintf_s(addr_txt, sizeof(addr_txt), sizeof(addr_txt) - 1, MACSTR, MAC2STR(addr));
510 	if (ret < 0) {
511 		wpa_error_log0(MSG_ERROR, "uapi_wifi_mesh_connect snprintf_s faild");
512 		return EXT_WIFI_FAIL;
513 	}
514 	(void)os_event_clear(g_softap_event, ~WPA_EVENT_AP_DEAUTH_FLAG);
515 	if (wpa_cli_ap_deauth((struct wpa_supplicant *)hapd, addr_txt, sizeof(addr_txt)) != EXT_WIFI_OK) {
516 		wpa_error_log0(MSG_ERROR, "wpa_cli_ap_deauth faild");
517 		return EXT_WIFI_FAIL;
518 	}
519 
520 	(void)os_event_read(g_softap_event, WPA_EVENT_AP_DEAUTH_FLAG, &ret_val,
521 	                    WIFI_WAITMODE_OR | WIFI_WAITMODE_CLR, WIFI_EVENT_DELAY_5S);
522 	if (ret_val != WPA_EVENT_AP_DEAUTH_OK) {
523 		wpa_error_log1(MSG_ERROR, "os_event_read WPA_EVENT_AP_DEAUTH_FLAG failed ret_val = %x", ret_val);
524 		return EXT_WIFI_FAIL;
525 	}
526 	return EXT_WIFI_OK;
527 }
528 
wifi_softap_set_cond_check(void)529 static int wifi_softap_set_cond_check(void)
530 {
531 	if (is_lock_flag_off() == EXT_WIFI_FAIL) {
532 		wpa_error_log0(MSG_ERROR, "wifi dev start or stop is running.");
533 		return EXT_WIFI_FAIL;
534 	}
535 #ifdef LOS_CONFIG_P2P
536 	if (is_ap_mesh_or_p2p_on() == EXT_WIFI_OK) {
537 		wpa_warning_log0(MSG_INFO, "ap or mesh is already in progress, set ap config failed.");
538 		return EXT_WIFI_FAIL;
539 	}
540 #endif
541 	return EXT_WIFI_OK;
542 }
543 
uapi_wifi_softap_set_protocol_mode(protocol_mode_enum hw_mode)544 int uapi_wifi_softap_set_protocol_mode(protocol_mode_enum hw_mode)
545 {
546 	if (wifi_softap_set_cond_check() == EXT_WIFI_FAIL)
547 		return EXT_WIFI_FAIL;
548 
549 	if (hw_mode > WIFI_MODE_11B_G_N_AX) {
550 		wpa_error_log0(MSG_ERROR, "physical mode value is error.");
551 		return EXT_WIFI_FAIL;
552 	}
553 	g_ap_opt_set.hw_mode = hw_mode;
554 	return EXT_WIFI_OK;
555 }
556 
uapi_wifi_softap_set_shortgi(int flag)557 int uapi_wifi_softap_set_shortgi(int flag)
558 {
559 	if (wifi_softap_set_cond_check() == EXT_WIFI_FAIL)
560 		return EXT_WIFI_FAIL;
561 
562 	if ((flag < WPA_FLAG_OFF) || (flag > WPA_FLAG_ON)) {
563 		wpa_error_log0(MSG_ERROR, "input flag error.");
564 		return EXT_WIFI_FAIL;
565 	}
566 	g_ap_opt_set.short_gi_off = !flag;
567 	return EXT_WIFI_OK;
568 }
569 
uapi_wifi_softap_set_beacon_period(int beacon_period)570 int uapi_wifi_softap_set_beacon_period(int beacon_period)
571 {
572 	if (wifi_softap_set_cond_check() == EXT_WIFI_FAIL)
573 		return EXT_WIFI_FAIL;
574 
575 	if ((beacon_period < WPA_AP_MIN_BEACON) || (beacon_period > WPA_AP_MAX_BEACON)) {
576 		wpa_error_log2(MSG_ERROR, "beacon value must be %d ~ %d.", WPA_AP_MIN_BEACON, WPA_AP_MAX_BEACON);
577 		return EXT_WIFI_FAIL;
578 	}
579 	g_ap_opt_set.beacon_period = beacon_period;
580 	return EXT_WIFI_OK;
581 }
582 
uapi_wifi_softap_set_dtim_period(int dtim_period)583 int uapi_wifi_softap_set_dtim_period(int dtim_period)
584 {
585 	if (wifi_softap_set_cond_check() == EXT_WIFI_FAIL)
586 		return EXT_WIFI_FAIL;
587 
588 	if ((dtim_period > WPA_AP_MAX_DTIM) || (dtim_period < WPA_AP_MIN_DTIM)) {
589 		wpa_error_log2(MSG_ERROR, "dtim_period must be %d ~ %d.", WPA_AP_MIN_DTIM, WPA_AP_MAX_DTIM);
590 		return EXT_WIFI_FAIL;
591 	}
592 	g_ap_opt_set.dtim_period = dtim_period;
593 	return EXT_WIFI_OK;
594 }
595 
uapi_wifi_softap_set_group_rekey(int wifi_group_rekey)596 int uapi_wifi_softap_set_group_rekey(int wifi_group_rekey)
597 {
598 	if (wifi_softap_set_cond_check() == EXT_WIFI_FAIL)
599 		return EXT_WIFI_FAIL;
600 
601 	if ((wifi_group_rekey > WPA_MAX_REKEY_TIME) || (wifi_group_rekey < WPA_MIN_REKEY_TIME)) {
602 		wpa_error_log2(MSG_ERROR, "group_rekey must be %d ~ %d.", WPA_MIN_REKEY_TIME, WPA_MAX_REKEY_TIME);
603 		return EXT_WIFI_FAIL;
604 	}
605 	g_ap_opt_set.wpa_group_rekey = wifi_group_rekey;
606 	return EXT_WIFI_OK;
607 }
608 
uapi_wifi_softap_get_protocol_mode(void)609 protocol_mode_enum uapi_wifi_softap_get_protocol_mode(void)
610 {
611 	if (is_lock_flag_off() == EXT_WIFI_FAIL) {
612 		wpa_error_log0(MSG_ERROR, "wifi dev start or stop is running.");
613 		return WIFI_MODE_UNDEFINE;
614 	}
615 	wpa_error_log1(MSG_ERROR, "softap phymode:%u.", (unsigned int)g_ap_opt_set.hw_mode);
616 	return g_ap_opt_set.hw_mode;
617 }
618 
uapi_wifi_softap_get_connected_sta(ext_wifi_ap_sta_info * sta_list,unsigned int * sta_num)619 int uapi_wifi_softap_get_connected_sta(ext_wifi_ap_sta_info *sta_list, unsigned int *sta_num)
620 {
621 	unsigned int ret_val;
622 	unsigned int int_save;
623 
624 	if ((sta_list == NULL) || (sta_num == NULL)) {
625 		wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_get_connected_sta: input params error.");
626 		return EXT_WIFI_FAIL;
627 	}
628 
629 	struct ext_wifi_dev *wifi_dev = wifi_dev_get(EXT_WIFI_IFTYPE_AP);
630 	if ((wifi_dev == NULL) || (wifi_dev->priv == NULL) || (g_ap_sta_info != NULL)) {
631 		wpa_error_log0(MSG_ERROR, "uapi_wifi_softap_get_connected_sta: softap may not start or busy.");
632 		return EXT_WIFI_FAIL;
633 	}
634 
635 	struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(wifi_dev->priv);
636 
637 	os_intlock(&int_save);
638 	g_ap_sta_info = sta_list;
639 	g_sta_num = *sta_num;
640 	os_intrestore(int_save);
641 
642 	(void)os_event_clear(g_softap_event, ~WPA_EVENT_AP_SHOW_STA_FLAG);
643 	(void)wpa_cli_show_sta(wpa_s);
644 	wpa_error_log0(MSG_ERROR, "os_event_read WPA_EVENT_AP_SHOW_STA_FLAG");
645 	(void)os_event_read(g_softap_event, WPA_EVENT_AP_SHOW_STA_FLAG, &ret_val,
646 	                    WIFI_WAITMODE_OR | WIFI_WAITMODE_CLR, WIFI_EVENT_DELAY_5S);
647 	g_ap_sta_info = NULL;
648 	if ((ret_val == WPA_EVENT_AP_SHOW_STA_ERROR) || (ret_val == WIFI_ERRNO_EVENT_READ_TIMEOUT)) {
649 		wpa_error_log1(MSG_ERROR, "os_event_read WPA_EVENT_AP_SHOW_STA_FLAG ret_val = %x", ret_val);
650 		*sta_num = 0;
651 		g_sta_num = 0;
652 		return EXT_WIFI_FAIL;
653 	}
654 	*sta_num = g_sta_num;
655 	g_sta_num = 0;
656 	return EXT_WIFI_OK;
657 }
658 
659