xref: /wlan-dirver/utils/sigma-dut/ap.c (revision a3af65b91db8d8c9054c485d92302fe8c29ec6ce)
1 /*
2  * Sigma Control API DUT (station/AP)
3  * Copyright (c) 2010-2011, Atheros Communications, Inc.
4  * Copyright (c) 2011-2017, Qualcomm Atheros, Inc.
5  * Copyright (c) 2018-2019, The Linux Foundation
6  * All Rights Reserved.
7  * Licensed under the Clear BSD license. See README for more details.
8  */
9 
10 #include "sigma_dut.h"
11 #include <sys/stat.h>
12 #include <sys/wait.h>
13 #include <sys/utsname.h>
14 #include <sys/ioctl.h>
15 #ifdef __linux__
16 #include <limits.h>
17 #include <dirent.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 #endif /* __linux__ */
22 #ifdef __QNXNTO__
23 #include <ifaddrs.h>
24 #include <net/if_dl.h>
25 #endif /* __QNXNTO__ */
26 #include "wpa_ctrl.h"
27 #include "wpa_helpers.h"
28 #ifdef ANDROID
29 #include <hardware_legacy/wifi.h>
30 #include <grp.h>
31 #include <pwd.h>
32 #endif /* ANDROID */
33 
34 /* Temporary files for ap_send_addba_req */
35 #define VI_QOS_TMP_FILE     "/tmp/vi-qos.tmp"
36 #define VI_QOS_FILE         "/tmp/vi-qos.txt"
37 #define VI_QOS_REFFILE      "/etc/vi-qos.txt"
38 
39 /* Configuration file name on Android */
40 #ifndef ANDROID_CONFIG_FILE
41 #define ANDROID_CONFIG_FILE		"/data/misc/wifi/hostapd.conf"
42 #endif /* ANDROID_CONFIG_FILE */
43 /* Maximum length of the line in the configuration file */
44 #define MAX_CONF_LINE_LEN  		(156)
45 
46 #ifndef SIGMA_DUT_HOSTAPD_PID_FILE
47 #define SIGMA_DUT_HOSTAPD_PID_FILE "/tmp/sigma_dut-ap-hostapd.pid"
48 #endif /* SIGMA_DUT_HOSTAPD_PID_FILE */
49 
50 /* The following is taken from Hotspot 2.0 testplan Appendix B.1 */
51 #define ANQP_VENUE_NAME_1 "02019c0002083d656e6757692d466920416c6c69616e63650a3239383920436f7070657220526f61640a53616e746120436c6172612c2043412039353035312c205553415b63686957692d4669e88194e79b9fe5ae9ee9aa8ce5aea40ae4ba8ce4b99de585abe4b99de5b9b4e5ba93e69f8fe8b7af0ae59ca3e5858be68b89e68b892c20e58aa0e588a9e7a68fe5b0bce4ba9a39353035312c20e7be8ee59bbd"
52 #define ANQP_VENUE_NAME_1_CHI "P\"\x63\x68\x69\x3a\x57\x69\x2d\x46\x69\xe8\x81\x94\xe7\x9b\x9f\xe5\xae\x9e\xe9\xaa\x8c\xe5\xae\xa4\\n\xe4\xba\x8c\xe4\xb9\x9d\xe5\x85\xab\xe4\xb9\x9d\xe5\xb9\xb4\xe5\xba\x93\xe6\x9f\x8f\xe8\xb7\xaf\\n\xe5\x9c\xa3\xe5\x85\x8b\xe6\x8b\x89\xe6\x8b\x89\x2c\x20\xe5\x8a\xa0\xe5\x88\xa9\xe7\xa6\x8f\xe5\xb0\xbc\xe4\xba\x9a\x39\x35\x30\x35\x31\x2c\x20\xe7\xbe\x8e\xe5\x9b\xbd\""
53 #define ANQP_IP_ADDR_TYPE_1 "060101000c"
54 #define ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "dddd2700506f9a11030011656e6757692d466920416c6c69616e63650e63686957692d4669e88194e79b9f"
55 #define ANQP_HS20_WAN_METRICS_1 "dddd1300506f9a11040001c40900008001000000000000"
56 #define ANQP_HS20_CONNECTION_CAPABILITY_1 "dddd3200506f9a1105000100000006140001061600000650000106bb010106bb060006c4130011f4010111c413001194110132000001"
57 #define QOS_MAP_SET_1 "53,2,22,6,8,15,0,7,255,255,16,31,32,39,255,255,40,47,255,255"
58 #define QOS_MAP_SET_2 "8,15,0,7,255,255,16,31,32,39,255,255,40,47,48,63"
59 
60 #define ADV_OF_CHARGE_1 \
61 "bc01000000d200454e475553443c3f786d6c2076657273696f6e3d22312e30222065" \
62 "6e636f64696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f77" \
63 "77772e77692d66692e6f72672f73706563696669636174696f6e732f686f7473706f7432646f" \
64 "74302f76312e302f616f637069223e3c4465736372697074696f6e3e57692d46692061636365" \
65 "737320666f72203120686f75722c207768696c6520796f752077616974206174207468652067" \
66 "6174652c2024302e39393c2f4465736372697074696f6e3e3c2f506c616e3ee3004652414341" \
67 "443c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f" \
68 "3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77692d66692e6f72672f737065" \
69 "63696669636174696f6e732f686f7473706f7432646f74302f76312e302f616f637069223e3c" \
70 "4465736372697074696f6e3e416363c3a8732057692d46692070656e64616e74203120686575" \
71 "72652c2070656e64616e742071756520766f757320617474656e64657a20c3a0206c6120706f" \
72 "7274652c20302c393920243c2f4465736372697074696f6e3e3c2f506c616e3ea101010000c7" \
73 "00454e475553443c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d2255" \
74 "54462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77692d66692e6f" \
75 "72672f73706563696669636174696f6e732f686f7473706f7432646f74302f76312e302f616f" \
76 "637069223e3c4465736372697074696f6e3e446f776e6c6f616420766964656f7320666f7220" \
77 "796f757220666c696768742c2024322e393920666f7220313047423c2f446573637269707469" \
78 "6f6e3e3c2f506c616e3ed3004652414341443c3f786d6c2076657273696f6e3d22312e302220" \
79 "656e636f64696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f" \
80 "7777772e77692d66692e6f72672f73706563696669636174696f6e732f686f7473706f743264" \
81 "6f74302f76312e302f616f637069223e3c4465736372697074696f6e3e54c3a96cc3a9636861" \
82 "7267657a2064657320766964c3a96f7320706f757220766f74726520766f6c2c20322c393920" \
83 "2420706f757220313020476f3c2f4465736372697074696f6e3e3c2f506c616e3ee40003002b" \
84 "736572766963652d70726f76696465722e636f6d3b66656465726174696f6e2e6578616d706c" \
85 "652e636f6db400454e475553443c3f786d6c2076657273696f6e3d22312e302220656e636f64" \
86 "696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77" \
87 "692d66692e6f72672f73706563696669636174696f6e732f686f7473706f7432646f74302f76" \
88 "312e302f616f637069223e3c4465736372697074696f6e3e46726565207769746820796f7572" \
89 "20737562736372697074696f6e213c2f4465736372697074696f6e3e3c2f506c616e3e"
90 
91 #define SAE_PK_KEY_1 \
92 	"MHcCAQEEIDNNDttjdQmLVyr1DOrWiapbMt15LDn4hnMLIXrBLAN+oAoGCCqGSM49AwEHoUQDQgAENAv4e3IlpYkqQjc/9KM4O4Athh6iY25wlT8Gdg+EhR7yoMR03nHri6QaaLogXxTsa9qGyXj1K9G8DEOyHMQCbg=="
93 #define SAE_PK_KEY_2 \
94 	"MHcCAQEEIF4LGkE30VdIeJe1ZVOo3TmkvT9RKRx30+yOx/9nhQY9oAoGCCqGSM49AwEHoUQDQgAE3PNzZH4m41vT5q6W7p5Q6B9owz5MHLwCUnpK84YRTVDLKKZXOPYxSHRh/O5Kz0OnVeOq1QfjEZRhNH79XhHCQQ=="
95 #define SAE_PK_KEY_P256 \
96 	"MHcCAQEEIAJIGlfnteonDb7rQyP/SGQjwzrZAnfrXIm4280VWajYoAoGCCqGSM49AwEHoUQDQgAEeRkstKQV+FSAMqBayqFknn2nAQsdsh/MhdX6tiHOTAFin/sUMFRMyspPtIu7YvlKdsexhI0jPVhaYZn1jKWhZg=="
97 #define SAE_PK_KEY_P384 \
98 	"MIGkAgEBBDB7iMoR2se0sWriXYCEsiLd8WFEblxWlCqb5kD7JgZfQjjylGwqOgIE7JShOOjE0Z2gBwYFK4EEACKhZANiAATntlmb7rlUopsaA/w5Uhut9jLlcY2sJdT6IzCdQ8uzuxk9Fgh+dwS25pd+lWC91rQ7kyjfZRpoePhwQasnjGRAl6rH2VWI/XtI5Q9iFXbhEaWEdKzWjetd6B5OPWy/BQg="
99 #define SAE_PK_KEY_P521 \
100 	"MIHcAgEBBEIBuNKSnOQY5ZVdBgWiXcL1Gr/W+VCw69nOte1gT4sqdVeV3grCl5HJxogVG2LFdtnEDLJrs0AtFoFN9nWnIuMu+ZWgBwYFK4EEACOhgYkDgYYABADuDQkFO2102xXwNnoGpBU+13kNuxZ/gwy8+G0UG75h6iiTqNWRaQIpSWgTmPNER7Ubb7etyXaoOTnsq4v4f9m8wgDt2LMZptHvUkHCq522rRK43ITmCayelbHWY1FhhAE1ETXRItSV8nLymjliEtjdfP45dsr25ySlkSaVCBNUFrAtfw=="
101 
102 /*
103  * MTU for Ethernet need to take into account 8-byte SNAP header
104  * to be added when encapsulating Ethernet frame into 802.11.
105  */
106 #ifndef IEEE80211_MAX_DATA_LEN_DMG
107 #define IEEE80211_MAX_DATA_LEN_DMG 7920
108 #endif /* IEEE80211_MAX_DATA_LEN_DMG */
109 #ifndef IEEE80211_SNAP_LEN_DMG
110 #define IEEE80211_SNAP_LEN_DMG 8
111 #endif /* IEEE80211_SNAP_LEN_DMG */
112 
113 extern char *sigma_wpas_ctrl;
114 extern char *sigma_hapd_ctrl;
115 extern char *ap_inet_addr;
116 extern char *ap_inet_mask;
117 extern char *sigma_radio_ifname[];
118 
119 static int ath_ap_start_hostapd(struct sigma_dut *dut);
120 static void ath_ap_set_params(struct sigma_dut *dut);
121 static int kill_process(struct sigma_dut *dut, char *proc_name,
122 			unsigned char is_proc_instance_one, int sig);
123 
124 
fwtest_cmd_wrapper(struct sigma_dut * dut,const char * arg,const char * ifname)125 static int fwtest_cmd_wrapper(struct sigma_dut *dut, const char *arg,
126 			       const char *ifname)
127 {
128 	int ret = -1;
129 
130 	if (strcmp(dut->device_driver, "ath11k") == 0)
131 		ret = run_system_wrapper(dut, "ath11k-fwtest -i %s %s",
132 					 ifname, arg);
133 
134 	return ret;
135 }
136 
137 
ap_ft_enabled(struct sigma_dut * dut)138 static int ap_ft_enabled(struct sigma_dut *dut)
139 {
140 	return dut->ap_ft_oa == 1 ||
141 		dut->ap_ft_ds == VALUE_ENABLED ||
142 		dut->ap_key_mgmt == AP_WPA2_FT_EAP ||
143 		dut->ap_key_mgmt == AP_WPA2_FT_PSK ||
144 		dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP ||
145 		(dut->ap_akm_values &
146 		 ((1 << AKM_FT_EAP) |
147 		  (1 << AKM_FT_PSK) |
148 		  (1 << AKM_FT_SAE) |
149 		  (1 << AKM_FT_SUITE_B) |
150 		  (1 << AKM_FT_FILS_SHA256) |
151 		  (1 << AKM_FT_FILS_SHA384)));
152 }
153 
154 
cmd_ap_ca_version(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)155 static enum sigma_cmd_result cmd_ap_ca_version(struct sigma_dut *dut,
156 					       struct sigma_conn *conn,
157 					       struct sigma_cmd *cmd)
158 {
159 	/* const char *name = get_param(cmd, "NAME"); */
160 	send_resp(dut, conn, SIGMA_COMPLETE, "version,1.0");
161 	return 0;
162 }
163 
164 
kill_hostapd_process_pid(struct sigma_dut * dut)165 static void kill_hostapd_process_pid(struct sigma_dut *dut)
166 {
167 	FILE *f;
168 	int pid, res;
169 	char path[100];
170 	int count;
171 
172 	f = fopen(SIGMA_DUT_HOSTAPD_PID_FILE, "r");
173 	if (!f)
174 		return;
175 	res = fscanf(f, "%d", &pid);
176 	fclose(f);
177 	if (res != 1)
178 		return;
179 	sigma_dut_print(dut, DUT_MSG_INFO, "Killing hostapd pid %d", pid);
180 	kill(pid, SIGTERM);
181 	snprintf(path, sizeof(path), "/proc/%d", pid);
182 	for (count = 0; count < 20 && file_exists(path); count++)
183 		usleep(100000);
184 }
185 
186 
get_hwaddr(const char * ifname,unsigned char * hwaddr)187 int get_hwaddr(const char *ifname, unsigned char *hwaddr)
188 {
189 #ifndef __QNXNTO__
190 	struct ifreq ifr;
191 	int s;
192 
193 	s = socket(AF_INET, SOCK_DGRAM, 0);
194 	if (s < 0)
195 		return -1;
196 	memset(&ifr, 0, sizeof(ifr));
197 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
198 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
199 		perror("ioctl");
200 		close(s);
201 		return -1;
202 	}
203 	close(s);
204 	memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
205 #else /* __QNXNTO__ */
206 	struct ifaddrs *ifaddrshead = NULL;
207 	int found = 0;
208 	struct ifaddrs *temp_ifap = NULL;
209 	struct sockaddr_dl *sdl = NULL;
210 
211 	if (getifaddrs(&ifaddrshead) != 0) {
212 		perror("getifaddrs failed");
213 		return -1;
214 	}
215 
216 	for (temp_ifap = ifaddrshead; ifaddrshead && !found;
217 	     ifaddrshead = ifaddrshead->ifa_next) {
218 		if (ifaddrshead->ifa_addr->sa_family == AF_LINK &&
219 		    strcmp(ifaddrshead->ifa_name, ifname) == 0) {
220 			found = 1;
221 			sdl = (struct sockaddr_dl *) ifaddrshead->ifa_addr;
222 			if (sdl)
223 				memcpy(hwaddr, LLADDR(sdl), sdl->sdl_alen);
224 		}
225 	}
226 
227 	if (temp_ifap)
228 		freeifaddrs(temp_ifap);
229 
230 	if (!found) {
231 		perror("Failed to get the interface");
232 		return -1;
233 	}
234 #endif /* __QNXNTO__ */
235 	return 0;
236 }
237 
238 
ath_ap_set_group_id(struct sigma_dut * dut,const char * ifname,const char * val)239 static void ath_ap_set_group_id(struct sigma_dut *dut, const char *ifname,
240 				const char *val)
241 {
242 	char buf[60];
243 
244 	snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 55 %d",
245 		 ifname, atoi(val));
246 	if (system(buf) != 0) {
247 		sigma_dut_print(dut, DUT_MSG_ERROR,
248 				"wifitool ap_group_id failed");
249 	}
250 }
251 
252 
ath_set_cts_width(struct sigma_dut * dut,const char * ifname,const char * val)253 void ath_set_cts_width(struct sigma_dut *dut, const char *ifname,
254 		       const char *val)
255 {
256 	char buf[60];
257 
258 	/* TODO: Enable support for other values */
259 	if (strcasecmp(val, "40") == 0) {
260 		snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 1",
261 			 ifname);
262 		if (system(buf) != 0) {
263 			sigma_dut_print(dut, DUT_MSG_ERROR,
264 					"wifitool cts_width failed");
265 		}
266 		snprintf(buf, sizeof(buf),
267 			 "athdiag --set --address=0x10024  --val=0xd90b8a14");
268 		if (system(buf) != 0) {
269 			sigma_dut_print(dut, DUT_MSG_ERROR,
270 					"disabling phy restart failed");
271 		}
272 	} else {
273 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported CTS_WIDTH");
274 	}
275 }
276 
277 
ath_config_dyn_bw_sig(struct sigma_dut * dut,const char * ifname,const char * val)278 void ath_config_dyn_bw_sig(struct sigma_dut *dut, const char *ifname,
279 			   const char *val)
280 {
281 	char buf[60];
282 
283 	if (strcasecmp(val, "enable") == 0) {
284 		dut->ap_dyn_bw_sig = VALUE_ENABLED;
285 		run_iwpriv(dut, ifname, "cwmenable 1");
286 
287 		snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 96 1",
288 			 ifname);
289 		if (system(buf) != 0) {
290 			sigma_dut_print(dut, DUT_MSG_ERROR,
291 					"disabling RTS from rate control logic failed");
292 		}
293 	} else if (strcasecmp(val, "disable") == 0) {
294 		dut->ap_dyn_bw_sig = VALUE_DISABLED;
295 		run_iwpriv(dut, ifname, "cwmenable 0");
296 	} else {
297 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported DYN_BW_SGL");
298 	}
299 }
300 
301 
wcn_config_ap_ldpc(struct sigma_dut * dut,const char * ifname)302 static void wcn_config_ap_ldpc(struct sigma_dut *dut, const char *ifname)
303 {
304 	if (dut->ap_ldpc == VALUE_NOT_SET)
305 		return;
306 	run_iwpriv(dut, ifname, "ldpc %d", dut->ap_ldpc != VALUE_DISABLED);
307 }
308 
309 
wcn_config_ap_fils_dscv(struct sigma_dut * dut,const char * ifname)310 static int wcn_config_ap_fils_dscv(struct sigma_dut *dut, const char *ifname)
311 {
312 #ifdef NL80211_SUPPORT
313 	uint8_t enable_fils_dscv = dut->ap_filsdscv == VALUE_ENABLED;
314 
315 	if (dut->ap_filsdscv == VALUE_NOT_SET)
316 		return 0;
317 
318 	return wcn_wifi_test_config_set_u8(
319 		dut, ifname,
320 		QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FILS_DISCOVERY_FRAMES_TX,
321 		enable_fils_dscv);
322 #else /* NL80211_SUPPORT */
323 	sigma_dut_print(dut, DUT_MSG_ERROR,
324 			"FILS Discovery frames configuration can't be set without NL80211_SUPPORT defined");
325 	if (dut->ap_filsdscv == VALUE_NOT_SET)
326 		return 0;
327 	return -1;
328 #endif /* NL80211_SUPPORT */
329 }
330 
331 
mac80211_config_rts_force(struct sigma_dut * dut,const char * ifname,const char * val)332 static void mac80211_config_rts_force(struct sigma_dut *dut, const char *ifname,
333 				      const char *val)
334 {
335 	char buf[60];
336 	char fname[128], path[128], *pos;
337 	ssize_t res;
338 
339 	res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
340 		       ifname);
341 	if (res < 0 || res >= sizeof(fname))
342 		return;
343 
344 	res = readlink(fname, path, sizeof(path));
345 	if (res < 0)
346 		return;
347 
348 	if (res >= (int) sizeof(path))
349 		res = sizeof(path) - 1;
350 	path[res] = '\0';
351 
352 	pos = strrchr(path, '/');
353 	if (!pos)
354 		pos = path;
355 	else
356 		pos++;
357 
358 	if (strcasecmp(val, "enable") == 0) {
359 		dut->ap_sig_rts = VALUE_ENABLED;
360 		res = snprintf(buf, sizeof(buf), "iw %s set rts 64", pos);
361 		if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
362 			sigma_dut_print(dut, DUT_MSG_ERROR,
363 					"iw set rts 64 failed");
364 		}
365 	} else if (strcasecmp(val, "disable") == 0) {
366 		dut->ap_sig_rts = VALUE_DISABLED;
367 		res = snprintf(buf, sizeof(buf), "iw %s set rts 2347", pos);
368 		if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
369 			sigma_dut_print(dut, DUT_MSG_ERROR,
370 					"iw rts 2347 failed");
371 		}
372 	} else {
373 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE");
374 	}
375 
376 }
377 
378 
ath_config_rts_force(struct sigma_dut * dut,const char * ifname,const char * val)379 static void ath_config_rts_force(struct sigma_dut *dut, const char *ifname,
380 				 const char *val)
381 {
382 	char buf[60];
383 
384 	if (strcasecmp(val, "enable") == 0) {
385 		dut->ap_sig_rts = VALUE_ENABLED;
386 		snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname);
387 		if (system(buf) != 0) {
388 			sigma_dut_print(dut, DUT_MSG_ERROR,
389 					"iwconfig rts 64 failed");
390 		}
391 		snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 100 1",
392 			 ifname);
393 		if (system(buf) != 0) {
394 			sigma_dut_print(dut, DUT_MSG_ERROR,
395 					"wifitool beeliner_fw_test 100 1 failed");
396 		}
397 	} else if (strcasecmp(val, "disable") == 0) {
398 		dut->ap_sig_rts = VALUE_DISABLED;
399 		snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname);
400 		if (system(buf) != 0) {
401 			sigma_dut_print(dut, DUT_MSG_ERROR,
402 					"iwconfig rts 2347 failed");
403 		}
404 	} else {
405 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE");
406 	}
407 }
408 
409 
ath_radio(struct sigma_dut * dut,const char * val)410 static void ath_radio(struct sigma_dut *dut, const char *val)
411 {
412 	if (strcasecmp(val, "on") == 0) {
413 		if (dut->ap_interface_5g == 1) {
414 			run_system(dut, "uci set wireless.wifi0.disabled=0");
415 		} else if (dut->ap_interface_2g == 1) {
416 			run_system(dut, "uci set wireless.wifi1.disabled=0");
417 		} else {
418 			run_system(dut, "uci set wireless.wifi0.disabled=0");
419 			run_system(dut, "uci set wireless.wifi1.disabled=0");
420 		}
421 		run_system(dut, "uci commit");
422 		run_system(dut, "wifi down");
423 		run_system(dut, "wifi up");
424 	} else if (strcasecmp(val, "off") == 0) {
425 		if (dut->ap_interface_5g == 1) {
426 			run_system(dut, "uci set wireless.wifi0.disabled=1");
427 		} else if (dut->ap_interface_2g == 1) {
428 			run_system(dut, "uci set wireless.wifi1.disabled=1");
429 		} else {
430 			run_system(dut, "uci set wireless.wifi0.disabled=1");
431 			run_system(dut, "uci set wireless.wifi1.disabled=1");
432 		}
433 		run_system(dut, "uci commit");
434 		run_system(dut, "wifi down");
435 		run_system(dut, "wifi up");
436 	}
437 }
438 
439 
deauth_disassoc(struct sigma_dut * dut,const char * ifname,const char * val)440 static void deauth_disassoc(struct sigma_dut *dut, const char *ifname,
441 			    const char *val)
442 {
443 	if (strcasecmp(val, "disable") == 0)
444 		run_iwpriv(dut, ifname, "stealthdown 1");
445 }
446 
447 
ath_set_txpower(struct sigma_dut * dut,const char * ifname,const char * val)448 static void ath_set_txpower(struct sigma_dut *dut, const char *ifname,
449 			    const char *val)
450 {
451 	char buf[60];
452 
453 	if (strcasecmp(val, "high") == 0)
454 		snprintf(buf, sizeof(buf), "iwconfig %s txpower 29", ifname);
455 	else if (strcasecmp(val, "low") == 0)
456 		snprintf(buf, sizeof(buf), "iwconfig %s txpower 1", ifname);
457 	else
458 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported txpower");
459 
460 	if (system(buf) != 0)
461 		sigma_dut_print(dut, DUT_MSG_ERROR, "setting txpower failed");
462 }
463 
464 
get_mode(const char * str)465 static enum ap_mode get_mode(const char *str)
466 {
467 	if (strcasecmp(str, "11a") == 0)
468 		return AP_11a;
469 	else if (strcasecmp(str, "11g") == 0)
470 		return AP_11g;
471 	else if (strcasecmp(str, "11b") == 0)
472 		return AP_11b;
473 	else if (strcasecmp(str, "11na") == 0)
474 		return AP_11na;
475 	else if (strcasecmp(str, "11ng") == 0)
476 		return AP_11ng;
477 	else if (strcasecmp(str, "11ac") == 0 || strcasecmp(str, "ac") == 0)
478 		return AP_11ac;
479 	else if (strcasecmp(str, "11ad") == 0)
480 		return AP_11ad;
481 	else if (strcasecmp(str, "11ax") == 0)
482 		return AP_11ax;
483 	else
484 		return AP_inval;
485 }
486 
487 
run_hostapd_cli(struct sigma_dut * dut,char * buf)488 static int run_hostapd_cli(struct sigma_dut *dut, char *buf)
489 {
490 	char command[1000];
491 	const char *bin;
492 	enum driver_type drv = get_driver_type(dut);
493 	char *sigma_hapd_file = sigma_hapd_ctrl;
494 
495 	if (file_exists("hostapd_cli"))
496 		bin = "./hostapd_cli";
497 	else if (file_exists("../../hostapd/hostapd_cli"))
498 		bin = "../../hostapd/hostapd_cli";
499 	else
500 		bin = "hostapd_cli";
501 
502 	if (drv == DRIVER_OPENWRT && sigma_hapd_ctrl == NULL) {
503 		sigma_hapd_file = "/var/run/hostapd-wifi0";
504 
505 		if (sigma_radio_ifname[0] &&
506 		    strcmp(sigma_radio_ifname[0], "wifi1") == 0)
507 			sigma_hapd_file = "/var/run/hostapd-wifi1";
508 		else if (sigma_radio_ifname[0] &&
509 			 strcmp(sigma_radio_ifname[0], "wifi2") == 0)
510 			sigma_hapd_file = "/var/run/hostapd-wifi2";
511 	}
512 
513 	if (sigma_hapd_file)
514 		snprintf(command, sizeof(command), "%s -p %s %s",
515 			 bin, sigma_hapd_file, buf);
516 	else
517 		snprintf(command, sizeof(command), "%s %s", bin, buf);
518 	return run_system(dut, command);
519 }
520 
521 
ath_set_lci_config(struct sigma_dut * dut,const char * val,struct sigma_cmd * cmd)522 static int ath_set_lci_config(struct sigma_dut *dut, const char *val,
523 			      struct sigma_cmd *cmd)
524 {
525 	FILE *f;
526 	int i;
527 
528 	f = fopen("/tmp/lci_cfg.txt", "w");
529 	if (!f) {
530 		sigma_dut_print(dut, DUT_MSG_ERROR,
531 				"Failed to open /tmp/lci_cfg.txt");
532 		return -1;
533 	}
534 
535 	for (i = 2; i < cmd->count; i++)
536 		fprintf(f, "%s = %s \n", cmd->params[i], cmd->values[i]);
537 	fprintf(f, "\n");
538 	fclose(f);
539 
540 	return 0;
541 }
542 
543 
set_ap_country_code(struct sigma_dut * dut)544 static void set_ap_country_code(struct sigma_dut *dut)
545 {
546 #if defined(ANDROID) || defined(LINUX_EMBEDDED)
547 	char buf[256];
548 
549 	if (dut->ap_countrycode[0]) {
550 		snprintf(buf, sizeof(buf), "DRIVER COUNTRY %s",
551 			 dut->ap_countrycode);
552 		if (wpa_command(get_station_ifname(dut), buf) < 0)
553 			sigma_dut_print(dut, DUT_MSG_ERROR,
554 					"Failed to set country code");
555 		else
556 			sigma_dut_print(dut, DUT_MSG_INFO,
557 					"Successfully set country code to %s",
558 					dut->ap_countrycode);
559 	}
560 #endif
561 }
562 
563 
set_vht_mcsmap_nss(struct sigma_dut * dut,int nss,int mcs)564 static void set_vht_mcsmap_nss(struct sigma_dut *dut, int nss, int mcs)
565 {
566 	switch (nss) {
567 	case 1:
568 		switch (mcs) {
569 		case 7:
570 			dut->ap_vhtmcs_map = 0xfffc;
571 			break;
572 		case 8:
573 			dut->ap_vhtmcs_map = 0xfffd;
574 			break;
575 		case 9:
576 			dut->ap_vhtmcs_map = 0xfffe;
577 			break;
578 		default:
579 			dut->ap_vhtmcs_map = 0xfffe;
580 			break;
581 		}
582 		break;
583 	case 2:
584 		switch (mcs) {
585 		case 7:
586 			dut->ap_vhtmcs_map = 0xfff0;
587 			break;
588 		case 8:
589 			dut->ap_vhtmcs_map = 0xfff5;
590 			break;
591 		case 9:
592 			dut->ap_vhtmcs_map = 0xfffa;
593 			break;
594 		default:
595 			dut->ap_vhtmcs_map = 0xfffa;
596 			break;
597 		}
598 		break;
599 	case 3:
600 		switch (mcs) {
601 		case 7:
602 			dut->ap_vhtmcs_map = 0xffc0;
603 			break;
604 		case 8:
605 			dut->ap_vhtmcs_map = 0xffd5;
606 			break;
607 		case 9:
608 			dut->ap_vhtmcs_map = 0xffea;
609 			break;
610 		default:
611 			dut->ap_vhtmcs_map = 0xffea;
612 			break;
613 		}
614 	default:
615 		dut->ap_vhtmcs_map = 0xffea;
616 		break;
617 	}
618 }
619 
620 
621 /* Get 2*nss bitmask */
622 /* We are trying to pack 2-bit MCS values per NSS in a 16-bit wide field.
623  * IEEE P802.11ax/D5.0, 9.4.2.247.4 supported HE-MCS And NSS Set field
624  * defines the following format for the 16 bit value. */
625 
626 #define HE_GET_MCS_NSS_PACK_MASK(nss) ((1 << ((nss) << 1)) - 1)
627 
he_reset_mcs_values_for_unsupported_ss(uint8_t * mcsnssmap,uint8_t nss)628 static void he_reset_mcs_values_for_unsupported_ss(uint8_t *mcsnssmap,
629 						   uint8_t nss)
630 {
631 	uint8_t nssmask;
632 
633 	if (nss <= 4) {
634 		nssmask = ~HE_GET_MCS_NSS_PACK_MASK(nss);
635 		mcsnssmap[0] |= nssmask;
636 		mcsnssmap[1] = 0xff;
637 	} else if (nss > 4 && nss <= 8) {
638 		nssmask = ~HE_GET_MCS_NSS_PACK_MASK(nss - 4);
639 		mcsnssmap[0] &= 0xff;
640 		mcsnssmap[1] |= nssmask;
641 	}
642 }
643 
644 
get_he_mcs_nssmap(uint8_t * mcsnssmap,uint8_t nss,uint8_t mcs)645 static void get_he_mcs_nssmap(uint8_t *mcsnssmap, uint8_t nss,
646 			      uint8_t mcs)
647 {
648 	switch (mcs) {
649 	case 11:
650 		mcsnssmap[0] = 0xaa;
651 		mcsnssmap[1] = 0xaa;
652 		break;
653 	case 9:
654 		mcsnssmap[0] = 0x55;
655 		mcsnssmap[1] = 0x55;
656 		break;
657 	case 7:
658 		mcsnssmap[0] = 0x0;
659 		mcsnssmap[1] = 0x0;
660 		break;
661 	}
662 	he_reset_mcs_values_for_unsupported_ss(mcsnssmap, nss);
663 }
664 
665 
cmd_ap_set_wireless(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)666 static enum sigma_cmd_result cmd_ap_set_wireless(struct sigma_dut *dut,
667 						 struct sigma_conn *conn,
668 						 struct sigma_cmd *cmd)
669 {
670 	/* const char *name = get_param(cmd, "NAME"); */
671 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
672 	const char *val;
673 	unsigned int wlan_tag = 1;
674 	const char *ifname = get_main_ifname(dut);
675 	char buf[128];
676 
677 	/* Allow program to be overridden if specified in the ap_set_wireless
678 	 * to support some 60 GHz test scripts where the program may be 60 GHz
679 	 * or WPS. */
680 	val = get_param(cmd, "PROGRAM");
681 	if (val)
682 		dut->program = sigma_program_to_enum(val);
683 
684 	val = get_param(cmd, "WLAN_TAG");
685 	if (val) {
686 		wlan_tag = atoi(val);
687 		if (wlan_tag < 1 || wlan_tag > 3) {
688 			/*
689 			 * The only valid WLAN Tags as of now as per the latest
690 			 * WFA scripts are 1, 2, and 3.
691 			 */
692 			send_resp(dut, conn, SIGMA_INVALID,
693 				  "errorCode,Invalid WLAN_TAG");
694 			return STATUS_SENT;
695 		}
696 	}
697 
698 	val = get_param(cmd, "Interface");
699 	if (val) {
700 		if (strcasecmp(val, "5G") == 0)
701 			dut->ap_interface_5g = 1;
702 		else
703 			dut->ap_interface_2g = 1;
704 
705 		if (dut->ap_interface_5g && dut->ap_interface_2g)
706 			dut->ap_is_dual = 1;
707 	}
708 
709 	val = get_param(cmd, "CountryCode");
710 	if (val) {
711 		if (strlen(val) > sizeof(dut->ap_countrycode) - 1)
712 			return INVALID_SEND_STATUS;
713 		snprintf(dut->ap_countrycode, sizeof(dut->ap_countrycode),
714 			 "%s", val);
715 
716 		/*
717 		 * Regdomain self-managed driver does not accept hostapd country
718 		 * code setting in all cases. Try to use wpa_supplicant DRIVER
719 		 * command first to set the driver to a specific country code
720 		 * before starting AP functionality. This is targeting cases
721 		 * where wpa_supplicant is running on the device as well for
722 		 * non-AP mode functionality.
723 		 */
724 		if (get_driver_type(dut) == DRIVER_LINUX_WCN)
725 			set_ap_country_code(dut);
726 	}
727 
728 	val = get_param(cmd, "regulatory_mode");
729 	if (val) {
730 		if (strcasecmp(val, "11d") == 0 || strcasecmp(val, "11h") == 0)
731 			dut->ap_regulatory_mode = AP_80211D_MODE_ENABLED;
732 	}
733 
734 	val = get_param(cmd, "SSID");
735 	if (val) {
736 		if (strlen(val) > sizeof(dut->ap_ssid) - 1)
737 			return INVALID_SEND_STATUS;
738 
739 		if (wlan_tag == 1) {
740 			/*
741 			 * If tag is not specified, it is deemed to be 1.
742 			 * Hence tag of 1 is a special case and the values
743 			 * corresponding to wlan-tag=1 are stored separately
744 			 * from the values corresponding tags 2 and 3.
745 			 * This approach minimises the changes to existing code
746 			 * since most of the sigma_dut code does not deal with
747 			 * WLAN-TAG CAPI variable.
748 			 */
749 			snprintf(dut->ap_ssid,
750 				 sizeof(dut->ap_ssid), "%s", val);
751 		} else {
752 			snprintf(dut->ap_tag_ssid[wlan_tag - 2],
753 				 sizeof(dut->ap_tag_ssid[wlan_tag - 2]),
754 				 "%s", val);
755 		}
756 	}
757 
758 	val = get_param(cmd, "CHANNEL");
759 	if (val) {
760 		const char *pos;
761 		dut->ap_channel = atoi(val);
762 		pos = strchr(val, ';');
763 		if (pos) {
764 			pos++;
765 			dut->ap_channel_1 = atoi(pos);
766 		}
767 	}
768 
769 	/* Overwrite the AP channel with DFS channel if configured */
770 	val = get_param(cmd, "dfs_chan");
771 	if (val) {
772 		dut->ap_channel = atoi(val);
773 	}
774 
775 	val = get_param(cmd, "dfs_mode");
776 	if (val) {
777 		if (strcasecmp(val, "Enable") == 0)
778 			dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
779 		else if (strcasecmp(val, "Disable") == 0)
780 			dut->ap_dfs_mode = AP_DFS_MODE_DISABLED;
781 		else
782 			sigma_dut_print(dut, DUT_MSG_ERROR,
783 					"Unsupported dfs_mode value: %s", val);
784 	}
785 
786 	val = get_param(cmd, "MODE");
787 	if (val) {
788 		char *str, *pos;
789 
790 		str = strdup(val);
791 		if (str == NULL)
792 			return INVALID_SEND_STATUS;
793 		pos = strchr(str, ';');
794 		if (pos)
795 			*pos++ = '\0';
796 
797 		dut->ap_is_dual = 0;
798 		dut->ap_mode = get_mode(str);
799 		if (dut->ap_mode == AP_inval) {
800 			send_resp(dut, conn, SIGMA_INVALID,
801 				  "errorCode,Unsupported MODE");
802 			free(str);
803 			return STATUS_SENT;
804 		}
805 		if (dut->ap_mode == AP_11ac && dut->ap_80plus80 != 1)
806 			dut->ap_chwidth = AP_80;
807 
808 		if (pos) {
809 			dut->ap_mode_1 = get_mode(pos);
810 			if (dut->ap_mode_1 == AP_inval) {
811 				send_resp(dut, conn, SIGMA_INVALID,
812 					  "errorCode,Unsupported MODE");
813 				free(str);
814 				return STATUS_SENT;
815 			}
816 			if (dut->ap_mode_1 == AP_11ac)
817 				dut->ap_chwidth_1 = AP_80;
818 			dut->ap_is_dual = 1;
819 		}
820 
821 		free(str);
822 	} else if (dut->ap_mode == AP_inval) {
823 		if (dut->ap_channel <= 11)
824 			dut->ap_mode = AP_11ng;
825 		else if (dut->program == PROGRAM_VHT)
826 			dut->ap_mode = AP_11ac;
827 		else
828 			dut->ap_mode = AP_11na;
829 	}
830 
831 	/* Override the AP mode in case of 60 GHz */
832 	if (dut->program == PROGRAM_60GHZ) {
833 		dut->ap_mode = AP_11ad;
834 		/* Workaround to force channel 2 if not specified */
835 		if (!dut->ap_channel)
836 			dut->ap_channel = 2;
837 	}
838 
839 	switch (dut->ap_mode) {
840 	case AP_11g:
841 	case AP_11b:
842 	case AP_11ng:
843 		dut->use_5g = 0;
844 		break;
845 	case AP_11a:
846 	case AP_11na:
847 	case AP_11ac:
848 		dut->use_5g = 1;
849 		break;
850 	case AP_11ax:
851 		if (dut->ap_channel >= 1 && dut->ap_channel <= 14)
852 			dut->use_5g = 0;
853 		else if (dut->ap_channel >= 36 && dut->ap_channel <= 171)
854 			dut->use_5g = 1;
855 		break;
856 	case AP_11ad:
857 	case AP_inval:
858 		break;
859 	}
860 
861 	val = get_param(cmd, "WME");
862 	if (val) {
863 		if (strcasecmp(val, "on") == 0)
864 			dut->ap_wme = AP_WME_ON;
865 		else if (strcasecmp(val, "off") == 0)
866 			dut->ap_wme = AP_WME_OFF;
867 		else
868 			sigma_dut_print(dut, DUT_MSG_ERROR,
869 					"Unsupported WME value: %s", val);
870 	}
871 
872 	val = get_param(cmd, "WMMPS");
873 	if (val) {
874 		if (strcasecmp(val, "on") == 0)
875 			dut->ap_wmmps = AP_WMMPS_ON;
876 		else if (strcasecmp(val, "off") == 0)
877 			dut->ap_wmmps = AP_WMMPS_OFF;
878 		else
879 			sigma_dut_print(dut, DUT_MSG_ERROR,
880 					"Unsupported WMMPS value: %s", val);
881 	}
882 
883 	val = get_param(cmd, "RTS");
884 	if (val)
885 		dut->ap_rts = atoi(val);
886 
887 	val = get_param(cmd, "FRGMNT");
888 	if (val)
889 		dut->ap_frgmnt = atoi(val);
890 
891 	/* TODO: PWRSAVE */
892 
893 	val = get_param(cmd, "BCNINT");
894 	if (val)
895 		dut->ap_bcnint = atoi(val);
896 
897 	val = get_param(cmd, "RADIO");
898 	if (val) {
899 		enum driver_type drv = get_driver_type(dut);
900 
901 		if (strcasecmp(val, "on") == 0) {
902 			if (drv == DRIVER_OPENWRT)
903 				ath_radio(dut, val);
904 			if (drv == DRIVER_ATHEROS)
905 				ath_ap_start_hostapd(dut);
906 			else if (cmd_ap_config_commit(dut, conn, cmd) <= 0)
907 				return STATUS_SENT;
908 		} else if (strcasecmp(val, "off") == 0) {
909 			if (drv == DRIVER_OPENWRT) {
910 				ath_radio(dut, val);
911 			} else if (dut->use_hostapd_pid_file) {
912 				kill_hostapd_process_pid(dut);
913 			} else if (kill_process(dut, "(hostapd)", 1,
914 						SIGTERM) == 0 ||
915 				   system("killall hostapd") == 0) {
916 				sigma_dut_print(dut, DUT_MSG_INFO,
917 						"Killed hostapd on radio,off");
918 			}
919 		} else {
920 			send_resp(dut, conn, SIGMA_INVALID,
921 				  "errorCode,Unsupported RADIO value");
922 			return STATUS_SENT;
923 		}
924 	}
925 
926 	val = get_param(cmd, "P2PMgmtBit");
927 	if (val)
928 		dut->ap_p2p_mgmt = atoi(val);
929 
930 	/* TODO: ChannelUsage */
931 
932 	/* TODO: 40_INTOLERANT */
933 
934 	val = get_param(cmd, "ADDBA_REJECT");
935 	if (val) {
936 		if (strcasecmp(val, "Enable") == 0)
937 			dut->ap_addba_reject = VALUE_ENABLED;
938 		else if (strcasecmp(val, "Disable") == 0)
939 			dut->ap_addba_reject = VALUE_DISABLED;
940 	}
941 
942 	val = get_param(cmd, "AMPDU");
943 	if (val) {
944 		if (strcasecmp(val, "Enable") == 0)
945 			dut->ap_ampdu = VALUE_ENABLED;
946 		else if (strcasecmp(val, "Disable") == 0)
947 			dut->ap_ampdu = VALUE_DISABLED;
948 	}
949 
950 	val = get_param(cmd, "AMPDU_EXP");
951 	if (val)
952 		dut->ap_ampdu_exp = atoi(val);
953 
954 	val = get_param(cmd, "AMSDU");
955 	if (val) {
956 		if (strcasecmp(val, "Enable") == 0)
957 			dut->ap_amsdu = VALUE_ENABLED;
958 		else if (strcasecmp(val, "Disable") == 0)
959 			dut->ap_amsdu = VALUE_DISABLED;
960 	}
961 
962 	val = get_param(cmd, "NoAck");
963 	if (val) {
964 		if (strcasecmp(val, "on") == 0)
965 			dut->ap_noack = VALUE_ENABLED;
966 		else if (strcasecmp(val, "off") == 0)
967 			dut->ap_noack = VALUE_DISABLED;
968 	}
969 
970 	/* TODO: GREENFIELD */
971 	/* TODO: MCS_32 */
972 
973 	val = get_param(cmd, "OFFSET");
974 	if (val) {
975 		if (strcasecmp(val, "Above") == 0)
976 			dut->ap_chwidth_offset = SEC_CH_40ABOVE;
977 		else if (strcasecmp(val, "Below") == 0)
978 			dut->ap_chwidth_offset = SEC_CH_40BELOW;
979 	}
980 
981 	val = get_param(cmd, "MCS_FIXEDRATE");
982 	if (val) {
983 		dut->ap_fixed_rate = 1;
984 		dut->ap_mcs = atoi(val);
985 	}
986 
987 	val = get_param(cmd, "SPATIAL_RX_STREAM");
988 	if (val) {
989 		if (strcasecmp(val, "1SS") == 0 || strcasecmp(val, "1") == 0) {
990 			dut->ap_rx_streams = 1;
991 			if (dut->device_type == AP_testbed)
992 				dut->ap_vhtmcs_map = 0xfffc;
993 		} else if (strcasecmp(val, "2SS") == 0 ||
994 			   strcasecmp(val, "2") == 0) {
995 			dut->ap_rx_streams = 2;
996 			if (dut->device_type == AP_testbed)
997 				dut->ap_vhtmcs_map = 0xfff0;
998 		} else if (strcasecmp(val, "3SS") == 0 ||
999 			   strcasecmp(val, "3") == 0) {
1000 			dut->ap_rx_streams = 3;
1001 			if (dut->device_type == AP_testbed)
1002 				dut->ap_vhtmcs_map = 0xffc0;
1003 		} else if (strcasecmp(val, "4SS") == 0 ||
1004 			   strcasecmp(val, "4") == 0) {
1005 			dut->ap_rx_streams = 4;
1006 		}
1007 	}
1008 
1009 	val = get_param(cmd, "SPATIAL_TX_STREAM");
1010 	if (val) {
1011 		if (strcasecmp(val, "1SS") == 0 ||
1012 		    strcasecmp(val, "1") == 0) {
1013 			dut->ap_tx_streams = 1;
1014 			if (dut->device_type == AP_testbed)
1015 				dut->ap_vhtmcs_map =  0xfffc;
1016 		} else if (strcasecmp(val, "2SS") == 0 ||
1017 			   strcasecmp(val, "2") == 0) {
1018 			dut->ap_tx_streams = 2;
1019 			if (dut->device_type == AP_testbed)
1020 				dut->ap_vhtmcs_map = 0xfff0;
1021 		} else if (strcasecmp(val, "3SS") == 0 ||
1022 			   strcasecmp(val, "3") == 0) {
1023 			dut->ap_tx_streams = 3;
1024 			if (dut->device_type == AP_testbed)
1025 				dut->ap_vhtmcs_map = 0xffc0;
1026 		} else if (strcasecmp(val, "4SS") == 0 ||
1027 			   strcasecmp(val, "4") == 0) {
1028 			dut->ap_tx_streams = 4;
1029 		}
1030 	}
1031 
1032 	val = get_param(cmd, "BSS_max_idle");
1033 	if (val) {
1034 		if (strncasecmp(val, "Enable", 7) == 0) {
1035 			dut->wnm_bss_max_feature = VALUE_ENABLED;
1036 		} else if (strncasecmp(val, "Disable", 8) == 0) {
1037 			dut->wnm_bss_max_feature = VALUE_DISABLED;
1038 		} else {
1039 			send_resp(dut, conn, SIGMA_ERROR,
1040 				  "errorCode,Invalid value for BSS_max_Feature");
1041 			return STATUS_SENT;
1042 		}
1043 	}
1044 
1045 	val = get_param(cmd, "BSS_Idle_Protection_options");
1046 	if (val) {
1047 		int protection = (int) strtol(val, (char **) NULL, 10);
1048 
1049 		if (protection != 1 && protection != 0) {
1050 			send_resp(dut, conn, SIGMA_ERROR,
1051 				  "errorCode,Invalid value for BSS_Idle_Protection_options");
1052 			return STATUS_SENT;
1053 		}
1054 		dut->wnm_bss_max_protection = protection ?
1055 			VALUE_ENABLED : VALUE_DISABLED;
1056 	}
1057 
1058 	val = get_param(cmd, "BSS_max_Idle_period");
1059 	if (val) {
1060 		long int idle_time = strtol(val, (char **) NULL, 10);
1061 
1062 		if (idle_time == LONG_MIN || idle_time == LONG_MAX) {
1063 			send_resp(dut, conn, SIGMA_ERROR,
1064 				  "errorCode,Invalid value for BSS_max_Idle_period");
1065 			return STATUS_SENT;
1066 		}
1067 		dut->wnm_bss_max_idle_time = (int) idle_time;
1068 	}
1069 
1070 	val = get_param(cmd, "PROXY_ARP");
1071 	if (val)
1072 		dut->ap_proxy_arp = (int) strtol(val, (char **) NULL, 10);
1073 
1074 	val = get_param(cmd, "nss_mcs_cap");
1075 	if (val) {
1076 		int nss, mcs;
1077 		char token[20];
1078 		char *result = NULL;
1079 		char *saveptr;
1080 
1081 		if (strlen(val) >= sizeof(token))
1082 			return INVALID_SEND_STATUS;
1083 		strlcpy(token, val, sizeof(token));
1084 		result = strtok_r(token, ";", &saveptr);
1085 		if (!result) {
1086 			send_resp(dut, conn, SIGMA_ERROR,
1087 				  "errorCode,VHT NSS not specified");
1088 			return STATUS_SENT;
1089 		}
1090 		nss = atoi(result);
1091 		result = strtok_r(NULL, ";", &saveptr);
1092 		if (result == NULL) {
1093 			send_resp(dut, conn, SIGMA_ERROR,
1094 				  "errorCode,VHTMCS not specified");
1095 			return STATUS_SENT;
1096 		}
1097 		result = strtok_r(result, "-", &saveptr);
1098 		result = strtok_r(NULL, "-", &saveptr);
1099 		if (!result) {
1100 			send_resp(dut, conn, SIGMA_ERROR,
1101 				  "errorCode,VHT MCS not specified");
1102 			return STATUS_SENT;
1103 		}
1104 		mcs = atoi(result);
1105 		if (dut->program == PROGRAM_HE) {
1106 			uint16_t mcsnssmap = 0;
1107 
1108 			get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs);
1109 			dut->he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap;
1110 			dut->he_ul_mcs = mcs;
1111 		} else {
1112 			set_vht_mcsmap_nss(dut, nss, mcs);
1113 		}
1114 	}
1115 
1116 	/* TODO: MPDU_MIN_START_SPACING */
1117 	/* TODO: RIFS_TEST */
1118 	/* TODO: SGI20 */
1119 
1120 	val = get_param(cmd, "STBC_TX");
1121 	if (val)
1122 		dut->ap_tx_stbc = atoi(val);
1123 
1124 	val = get_param(cmd, "WIDTH");
1125 	if (val) {
1126 		if (strcasecmp(val, "20") == 0)
1127 			dut->ap_chwidth = AP_20;
1128 		else if (strcasecmp(val, "40") == 0)
1129 			dut->ap_chwidth = AP_40;
1130 		else if (strcasecmp(val, "80") == 0)
1131 			dut->ap_chwidth = AP_80;
1132 		else if (strcasecmp(val, "160") == 0)
1133 			dut->ap_chwidth = AP_160;
1134 		else if (strcasecmp(val, "80plus80") == 0) {
1135 			dut->ap_80plus80 = 1;
1136 			dut->ap_chwidth = AP_80_80;
1137 		} else if (strcasecmp(val, "Auto") == 0)
1138 			dut->ap_chwidth = AP_AUTO;
1139 		else {
1140 			send_resp(dut, conn, SIGMA_INVALID,
1141 				  "errorCode,Unsupported WIDTH");
1142 			return STATUS_SENT;
1143 		}
1144 	}
1145 
1146 	/* TODO: WIDTH_SCAN */
1147 
1148 	val = get_param(cmd, "TDLSProhibit");
1149 	dut->ap_tdls_prohibit = val && strcasecmp(val, "Enabled") == 0;
1150 	val = get_param(cmd, "TDLSChswitchProhibit");
1151 	dut->ap_tdls_prohibit_chswitch =
1152 		val && strcasecmp(val, "Enabled") == 0;
1153 	val = get_param(cmd, "HS2");
1154 	if (val && wlan_tag == 1)
1155 		dut->ap_hs2 = atoi(val);
1156 	val = get_param(cmd, "P2P_CROSS_CONNECT");
1157 	if (val)
1158 		dut->ap_p2p_cross_connect = strcasecmp(val, "Enabled") == 0;
1159 
1160 	val = get_param(cmd, "FakePubKey");
1161 	dut->ap_fake_pkhash = val && atoi(val);
1162 
1163 	val = get_param(cmd, "vht_tkip");
1164 	dut->ap_allow_vht_tkip = val && strcasecmp(val, "Enable") == 0;
1165 	val = get_param(cmd, "vht_wep");
1166 	dut->ap_allow_vht_wep = val && strcasecmp(val, "Enable") == 0;
1167 
1168 	val = get_param(cmd, "Protect_mode");
1169 	dut->ap_disable_protection = val && strcasecmp(val, "Disable") == 0;
1170 
1171 	val = get_param(cmd, "DYN_BW_SGNL");
1172 	if (val) {
1173 		switch (get_driver_type(dut)) {
1174 		case DRIVER_OPENWRT:
1175 			switch (get_openwrt_driver_type()) {
1176 			case OPENWRT_DRIVER_ATHEROS:
1177 				ath_config_dyn_bw_sig(dut, ifname, val);
1178 				break;
1179 			default:
1180 				send_resp(dut, conn, SIGMA_ERROR,
1181 					  "errorCode,Unsupported DYN_BW_SGNL with OpenWrt driver");
1182 				return STATUS_SENT;
1183 			}
1184 			break;
1185 		case DRIVER_WCN:
1186 		case DRIVER_LINUX_WCN:
1187 			ath_config_dyn_bw_sig(dut, ifname, val);
1188 			break;
1189 		default:
1190 			sigma_dut_print(dut, DUT_MSG_ERROR,
1191 					"Unsupported DYN_BW_SGL with the current driver");
1192 			break;
1193 		}
1194 	}
1195 
1196 	val = get_param(cmd, "SGI80");
1197 	if (val) {
1198 		if (strcasecmp(val, "enable") == 0)
1199 			dut->ap_sgi80 = 1;
1200 		else if (strcasecmp(val, "disable") == 0)
1201 			dut->ap_sgi80 = 0;
1202 		else {
1203 			send_resp(dut, conn, SIGMA_INVALID,
1204 				  "errorCode,Unsupported SGI80");
1205 			return STATUS_SENT;
1206 		}
1207 	}
1208 
1209 	val = get_param(cmd, "LDPC");
1210 	if (val) {
1211 		if (strcasecmp(val, "enable") == 0)
1212 			dut->ap_ldpc = VALUE_ENABLED;
1213 		else if (strcasecmp(val, "disable") == 0)
1214 			dut->ap_ldpc = VALUE_DISABLED;
1215 		else {
1216 			send_resp(dut, conn, SIGMA_INVALID,
1217 				  "errorCode,Unsupported LDPC");
1218 			return STATUS_SENT;
1219 		}
1220 		switch (get_driver_type(dut)) {
1221 		case DRIVER_WCN:
1222 		case DRIVER_LINUX_WCN:
1223 			wcn_config_ap_ldpc(dut, ifname);
1224 			break;
1225 		default:
1226 			break;
1227 		}
1228 	}
1229 
1230 	val = get_param(cmd, "BW_SGNL");
1231 	if (val) {
1232 		/*
1233 		 * With dynamic bandwidth signaling enabled we should see
1234 		 * RTS if the threshold is met.
1235 		 */
1236 		if (strcasecmp(val, "enable") == 0) {
1237 			dut->ap_sig_rts = VALUE_ENABLED;
1238 		} else if (strcasecmp(val, "disable") == 0) {
1239 			dut->ap_sig_rts = VALUE_DISABLED;
1240 		} else {
1241 			send_resp(dut, conn, SIGMA_INVALID,
1242 				  "errorCode,Unsupported BW_SGNL");
1243 			return STATUS_SENT;
1244 		}
1245 	}
1246 
1247 	val = get_param(cmd, "RTS_FORCE");
1248 	if (val) {
1249 		switch (get_driver_type(dut)) {
1250 		case DRIVER_OPENWRT:
1251 			switch (get_openwrt_driver_type()) {
1252 			case OPENWRT_DRIVER_ATHEROS:
1253 				ath_config_rts_force(dut, ifname, val);
1254 				break;
1255 			default:
1256 				send_resp(dut, conn, SIGMA_ERROR,
1257 					  "errorCode,Unsupported RTS_FORCE with OpenWrt driver");
1258 				return STATUS_SENT;
1259 			}
1260 			break;
1261 		case DRIVER_MAC80211:
1262 			mac80211_config_rts_force(dut, ifname, val);
1263 			break;
1264 		default:
1265 			sigma_dut_print(dut, DUT_MSG_ERROR,
1266 					"Unsupported RTS_FORCE with the current driver");
1267 			break;
1268 		}
1269 	}
1270 
1271 	val = get_param(cmd, "Zero_crc");
1272 	if (val) {
1273 		switch (get_driver_type(dut)) {
1274 		case DRIVER_ATHEROS:
1275 			ath_set_zero_crc(dut, val);
1276 			break;
1277 		case DRIVER_OPENWRT:
1278 			switch (get_openwrt_driver_type()) {
1279 			case OPENWRT_DRIVER_ATHEROS:
1280 				ath_set_zero_crc(dut, val);
1281 				break;
1282 			default:
1283 				send_resp(dut, conn, SIGMA_ERROR,
1284 					  "errorCode,Unsupported zero_crc with the current driver");
1285 				return STATUS_SENT;
1286 			}
1287 			break;
1288 		default:
1289 			send_resp(dut, conn, SIGMA_ERROR,
1290 				  "errorCode,Unsupported zero_crc with the current driver");
1291 			return STATUS_SENT;
1292 		}
1293 	}
1294 
1295 	val = get_param(cmd, "TxBF");
1296 	if (val) {
1297 		dut->ap_txBF = strcasecmp(val, "enable") == 0;
1298 		dut->he_sounding = VALUE_DISABLED;
1299 		dut->he_set_sta_1x1 = VALUE_ENABLED;
1300 	}
1301 
1302 	val = get_param(cmd, "MU_TxBF");
1303 	if (val) {
1304 		if (strcasecmp(val, "enable") == 0) {
1305 			dut->ap_txBF = 1;
1306 			dut->ap_mu_txBF = 1;
1307 			dut->he_sounding = VALUE_DISABLED;
1308 		} else if (strcasecmp(val, "disable") == 0) {
1309 			dut->ap_txBF = 0;
1310 			dut->ap_mu_txBF = 0;
1311 		} else {
1312 			sigma_dut_print(dut, DUT_MSG_ERROR,
1313 					"Unsupported MU_TxBF");
1314 		}
1315 	}
1316 
1317 	/* UNSUPPORTED: tx_lgi_rate */
1318 
1319 	val = get_param(cmd, "wpsnfc");
1320 	if (val)
1321 		dut->ap_wpsnfc = atoi(val);
1322 
1323 	val = get_param(cmd, "GROUP_ID");
1324 	if (val) {
1325 		switch (get_driver_type(dut)) {
1326 		case DRIVER_OPENWRT:
1327 			switch (get_openwrt_driver_type()) {
1328 			case OPENWRT_DRIVER_ATHEROS:
1329 				ath_ap_set_group_id(dut, ifname, val);
1330 				break;
1331 			default:
1332 				send_resp(dut, conn, SIGMA_ERROR,
1333 					  "errorCode,Unsupported group_id with the current driver");
1334 				return STATUS_SENT;
1335 			}
1336 			break;
1337 		default:
1338 			send_resp(dut, conn, SIGMA_ERROR,
1339 				  "errorCode,Unsupported group_id with the current driver");
1340 			return STATUS_SENT;
1341 		}
1342 	}
1343 
1344 	val = get_param(cmd, "CTS_WIDTH");
1345 	if (val) {
1346 		switch (get_driver_type(dut)) {
1347 		case DRIVER_OPENWRT:
1348 			switch (get_openwrt_driver_type()) {
1349 			case OPENWRT_DRIVER_ATHEROS:
1350 				ath_set_cts_width(dut, ifname, val);
1351 				break;
1352 			default:
1353 				send_resp(dut, conn, SIGMA_ERROR,
1354 					  "errorCode,Unsupported cts_width with the current driver");
1355 				return STATUS_SENT;
1356 			}
1357 			break;
1358 		default:
1359 			send_resp(dut, conn, SIGMA_ERROR,
1360 				  "errorCode,Unsupported cts_width with the current driver");
1361 			return STATUS_SENT;
1362 		}
1363 	}
1364 
1365 	val = get_param(cmd, "MU_NDPA_FrameFormat");
1366 	if (val)
1367 		dut->ap_ndpa_frame = atoi(val);
1368 
1369 	val = get_param(cmd, "interworking");
1370 	if (val && strcmp(val, "1") == 0)
1371 		dut->ap_interworking = 1;
1372 
1373 	val = get_param(cmd, "GAS_CB_DELAY");
1374 	if (val)
1375 		dut->ap_gas_cb_delay = atoi(val);
1376 
1377 	val = get_param(cmd, "LCI");
1378 	if (val) {
1379 		if (strlen(val) > sizeof(dut->ap_val_lci) - 1)
1380 			return INVALID_SEND_STATUS;
1381 		dut->ap_lci = 1;
1382 		snprintf(dut->ap_val_lci, sizeof(dut->ap_val_lci), "%s", val);
1383 		ath_set_lci_config(dut, val, cmd);
1384 	}
1385 
1386 	val = get_param(cmd, "InfoZ");
1387 	if (val) {
1388 		if (strlen(val) > sizeof(dut->ap_infoz) - 1)
1389 			return INVALID_SEND_STATUS;
1390 		snprintf(dut->ap_infoz, sizeof(dut->ap_infoz), "%s", val);
1391 	}
1392 
1393 	val = get_param(cmd, "LocCivicAddr");
1394 	if (val) {
1395 		if (strlen(val) > sizeof(dut->ap_val_lcr) - 1)
1396 			return INVALID_SEND_STATUS;
1397 		dut->ap_lcr = 1;
1398 		snprintf(dut->ap_val_lcr, sizeof(dut->ap_val_lcr), "%s", val);
1399 		if (dut->ap_lci == 0)
1400 			ath_set_lci_config(dut, val, cmd);
1401 	}
1402 
1403 	val = get_param(cmd, "NeighAPBSSID");
1404 	if (val) {
1405 		if (dut->ap_neighap < 3) {
1406 			if (parse_mac_address(
1407 				    dut, val,
1408 				    dut->ap_val_neighap[dut->ap_neighap]) < 0) {
1409 				send_resp(dut, conn, SIGMA_INVALID,
1410 					  "Failed to parse MAC address");
1411 				return STATUS_SENT;
1412 			}
1413 			dut->ap_neighap++;
1414 			if (dut->ap_lci == 1)
1415 				dut->ap_scan = 1;
1416 		}
1417 	}
1418 
1419 	val = get_param(cmd, "OpChannel");
1420 	if (val) {
1421 		if (dut->ap_opchannel < 3) {
1422 			dut->ap_val_opchannel[dut->ap_opchannel] = atoi(val);
1423 			dut->ap_opchannel++;
1424 		}
1425 	}
1426 
1427 	val = get_param(cmd, "URI-FQDNdescriptor");
1428 	if (val) {
1429 		if (strcasecmp(val, "HELD") == 0) {
1430 			dut->ap_fqdn_held = 1;
1431 		} else if (strcasecmp(val, "SUPL") == 0) {
1432 			dut->ap_fqdn_supl = 1;
1433 		} else {
1434 			send_resp(dut, conn, SIGMA_INVALID,
1435 				  "errorCode,Unsupported URI-FQDNdescriptor");
1436 			return STATUS_SENT;
1437 		}
1438 	}
1439 
1440 	val = get_param(cmd, "Reg_Domain");
1441 	if (val) {
1442 		if (strcasecmp(val, "Local") == 0) {
1443 			dut->ap_reg_domain = REG_DOMAIN_LOCAL;
1444 		} else if (strcasecmp(val, "Global") == 0) {
1445 			dut->ap_reg_domain = REG_DOMAIN_GLOBAL;
1446 		} else {
1447 			send_resp(dut, conn, SIGMA_ERROR,
1448 				  "errorCode,Wrong value for Reg_Domain");
1449 			return STATUS_SENT;
1450 		}
1451 	}
1452 
1453 	val = get_param(cmd, "NAME");
1454 	if (val) {
1455 		if (strcasecmp(val, "ap1mbo") == 0)
1456 			dut->ap_name = 1;
1457 		else if (strcasecmp(val, "ap2mbo") == 0)
1458 			dut->ap_name = 2;
1459 		else
1460 			dut->ap_name = 0;
1461 	}
1462 
1463 	val = get_param(cmd, "FT_OA");
1464 	if (val) {
1465 		if (strcasecmp(val, "Enable") == 0) {
1466 			dut->ap_ft_oa = 1;
1467 		} else if (strcasecmp(val, "Disable") == 0) {
1468 			dut->ap_ft_oa = 0;
1469 		} else {
1470 			send_resp(dut, conn, SIGMA_ERROR,
1471 				  "errorCode,Wrong value for FT_OA");
1472 			return STATUS_SENT;
1473 		}
1474 	}
1475 
1476 	val = get_param(cmd, "FT_DS");
1477 	if (val) {
1478 		if (strcasecmp(val, "Enable") == 0) {
1479 			dut->ap_ft_ds = VALUE_ENABLED;
1480 		} else if (strcasecmp(val, "Disable") == 0) {
1481 			dut->ap_ft_ds = VALUE_DISABLED;
1482 		} else {
1483 			send_resp(dut, conn, SIGMA_ERROR,
1484 				  "errorCode,Unsupported value for FT_DS");
1485 			return STATUS_SENT_ERROR;
1486 		}
1487 	}
1488 
1489 	val = get_param(cmd, "Cellular_Cap_Pref");
1490 	if (val)
1491 		dut->ap_cell_cap_pref = atoi(val);
1492 
1493 	val = get_param(cmd, "DOMAIN");
1494 	if (val) {
1495 		if (strlen(val) >= sizeof(dut->ap_mobility_domain)) {
1496 			send_resp(dut, conn, SIGMA_ERROR,
1497 				  "errorCode,Too long DOMAIN");
1498 			return STATUS_SENT;
1499 		}
1500 		snprintf(dut->ap_mobility_domain,
1501 			 sizeof(dut->ap_mobility_domain), "%s", val);
1502 	}
1503 
1504 	val = get_param(cmd, "ft_bss_list");
1505 	if (val) {
1506 		char *mac_str;
1507 		int i;
1508 		char *saveptr;
1509 		char *mac_list_str;
1510 
1511 		mac_list_str = strdup(val);
1512 		if (!mac_list_str)
1513 			return INVALID_SEND_STATUS;
1514 		mac_str = strtok_r(mac_list_str, " ", &saveptr);
1515 		for (i = 0; mac_str && i < MAX_FT_BSS_LIST; i++) {
1516 			if (parse_mac_address(dut, mac_str,
1517 					      dut->ft_bss_mac_list[i]) < 0) {
1518 				sigma_dut_print(dut, DUT_MSG_ERROR,
1519 						"MAC Address not in proper format");
1520 				break;
1521 			}
1522 			dut->ft_bss_mac_cnt++;
1523 			mac_str = strtok_r(NULL, " ", &saveptr);
1524 		}
1525 		sigma_dut_print(dut, DUT_MSG_DEBUG,
1526 				"Storing the following FT BSS MAC List");
1527 		for (i = 0; i < dut->ft_bss_mac_cnt; i++) {
1528 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1529 					"MAC[%d] %02x:%02x:%02x:%02x:%02x:%02x",
1530 					i,
1531 					dut->ft_bss_mac_list[i][0],
1532 					dut->ft_bss_mac_list[i][1],
1533 					dut->ft_bss_mac_list[i][2],
1534 					dut->ft_bss_mac_list[i][3],
1535 					dut->ft_bss_mac_list[i][4],
1536 					dut->ft_bss_mac_list[i][5]);
1537 		}
1538 		free(mac_list_str);
1539 	}
1540 
1541 	val = get_param(cmd, "OCESupport");
1542 	if (val) {
1543 		if (strcasecmp(val, "enable") == 0) {
1544 			dut->ap_oce = VALUE_ENABLED;
1545 		} else if (strcasecmp(val, "disable") == 0) {
1546 			dut->ap_oce = VALUE_DISABLED;
1547 			dut->ap_filsdscv = VALUE_DISABLED;
1548 		} else {
1549 			send_resp(dut, conn, SIGMA_INVALID,
1550 				  "errorCode,Unsupported OCE");
1551 			return STATUS_SENT;
1552 		}
1553 	}
1554 
1555 	val = get_param(cmd, "FILSDscvInterval");
1556 	if (val)
1557 		dut->ap_fils_dscv_int = atoi(val);
1558 
1559 	val = get_param(cmd, "BroadcastSSID");
1560 	if (val) {
1561 		if (strcasecmp(val, "enable") == 0) {
1562 			dut->ap_broadcast_ssid = VALUE_ENABLED;
1563 		} else if (strcasecmp(val, "disable") == 0) {
1564 			dut->ap_broadcast_ssid = VALUE_DISABLED;
1565 		} else {
1566 			send_resp(dut, conn, SIGMA_INVALID,
1567 				  "errorCode,Unsupported hidden SSID");
1568 			return STATUS_SENT;
1569 		}
1570 	}
1571 
1572 	val = get_param(cmd, "FILSDscv");
1573 	if (val) {
1574 		if (strcasecmp(val, "enable") == 0) {
1575 			dut->ap_filsdscv = VALUE_ENABLED;
1576 		} else if (strcasecmp(val, "disable") == 0) {
1577 			dut->ap_filsdscv = VALUE_DISABLED;
1578 		} else {
1579 			send_resp(dut, conn, SIGMA_INVALID,
1580 				  "errorCode,Unsupported FILSDscv");
1581 			return STATUS_SENT;
1582 		}
1583 	}
1584 
1585 	val = get_param(cmd, "FILSHLP");
1586 	if (val) {
1587 		if (strcasecmp(val, "enable") == 0) {
1588 			dut->ap_filshlp = VALUE_ENABLED;
1589 		} else if (strcasecmp(val, "disable") == 0) {
1590 			dut->ap_filshlp = VALUE_DISABLED;
1591 		} else {
1592 			send_resp(dut, conn, SIGMA_INVALID,
1593 				  "errorCode,Unsupported FILSHLP");
1594 			return STATUS_SENT;
1595 		}
1596 	}
1597 
1598 	val = get_param(cmd, "NAIRealm");
1599 	if (val) {
1600 		dut->ap_nairealm_int = 1;
1601 		if (strlen(val) > sizeof(dut->ap_nairealm) - 1)
1602 			return INVALID_SEND_STATUS;
1603 		snprintf(dut->ap_nairealm, sizeof(dut->ap_nairealm), "%s", val);
1604 	}
1605 
1606 	val = get_param(cmd, "DeauthDisassocTx");
1607 	if (val) {
1608 		if (strcasecmp(val, "disable") == 0) {
1609 			deauth_disassoc(dut, ifname, val);
1610 		} else {
1611 			send_resp(dut, conn, SIGMA_INVALID,
1612 				  "errorCode,Unsupported DeauthDisassocTx");
1613 			return STATUS_SENT;
1614 		}
1615 	}
1616 
1617 	val = get_param(cmd, "RNR");
1618 	if (val) {
1619 		if (strcasecmp(val, "enable") == 0) {
1620 			dut->ap_rnr = VALUE_ENABLED;
1621 		} else if (strcasecmp(val, "disable") == 0) {
1622 			dut->ap_rnr = VALUE_DISABLED;
1623 		} else {
1624 			send_resp(dut, conn, SIGMA_INVALID,
1625 				  "errorCode,Unsupported RNR");
1626 			return STATUS_SENT;
1627 		}
1628 	}
1629 
1630 	val = get_param(cmd, "BLEChannelUtil");
1631 	if (val)
1632 		dut->ap_blechanutil = atoi(val);
1633 
1634 	val = get_param(cmd, "BLEAvailAdminCap");
1635 	if (val)
1636 		dut->ap_ble_admit_cap = atoi(val);
1637 
1638 	val = get_param(cmd, "DataPPDUDuration");
1639 	if (val)
1640 		dut->ap_datappdudura = atoi(val);
1641 
1642 	val = get_param(cmd, "AirTimeFract");
1643 	if (val)
1644 		dut->ap_airtimefract = atoi(val);
1645 
1646 	val = get_param(cmd, "dhcpServIPADDR");
1647 	if (val) {
1648 		if (strlen(val) > sizeof(dut->ap_dhcpserv_ipaddr) - 1)
1649 			return INVALID_SEND_STATUS;
1650 		snprintf(dut->ap_dhcpserv_ipaddr,
1651 			 sizeof(dut->ap_dhcpserv_ipaddr), "%s", val);
1652 		dut->ap_dhcp_stop = 1;
1653 	}
1654 
1655 	val = get_param(cmd, "ESP_IE");
1656 	if (val) {
1657 		if (strcasecmp(val, "enable") == 0) {
1658 			dut->ap_esp = VALUE_ENABLED;
1659 		} else if (strcasecmp(val, "disable") == 0) {
1660 			dut->ap_esp = VALUE_DISABLED;
1661 		} else {
1662 			send_resp(dut, conn, SIGMA_INVALID,
1663 				  "errorCode,Unsupported ESP_IE");
1664 			return STATUS_SENT;
1665 		}
1666 	}
1667 
1668 	val = get_param(cmd, "BAWinSize");
1669 	if (val)
1670 		dut->ap_bawinsize = atoi(val);
1671 
1672 	val = get_param(cmd, "BLEStaCount");
1673 	if (val)
1674 		dut->ap_blestacnt = atoi(val);
1675 
1676 	val = get_param(cmd, "PPDUTxType");
1677 	if (val) {
1678 		if (strcasecmp(val, "MU") == 0) {
1679 			dut->ap_he_ppdu = PPDU_MU;
1680 		} else if (strcasecmp(val, "HE-SU") == 0) {
1681 			/* Do nothing */
1682 		} else if (strcasecmp(val, "SU") == 0) {
1683 			/* Do nothing */
1684 		} else if (strcasecmp(val, "legacy") == 0) {
1685 			/* Do nothing */
1686 		} else if (strcasecmp(val, "ER") == 0) {
1687 			/* Do nothing */
1688 		} else if (strcasecmp(val, "TB") == 0) {
1689 			/* Do nothing */
1690 		} else {
1691 			send_resp(dut, conn, SIGMA_ERROR,
1692 				  "errorCode,Unsupported PPDUTxType");
1693 			return STATUS_SENT_ERROR;
1694 		}
1695 	}
1696 
1697 	val = get_param(cmd, "WscIEFragment");
1698 	if (val && strcasecmp(val, "enable") == 0) {
1699 		sigma_dut_print(dut, DUT_MSG_DEBUG,
1700 				"Enable WSC IE fragmentation");
1701 		dut->wsc_fragment = 1;
1702 	}
1703 
1704 	val = get_param(cmd, "WpsVersion");
1705 	if (val)
1706 		dut->wps_forced_version = get_wps_forced_version(dut, val);
1707 
1708 	val = get_param(cmd, "WscEAPFragment");
1709 	if (val && strcasecmp(val, "enable") == 0)
1710 		dut->eap_fragment = 1;
1711 
1712 	val = get_param(cmd, "MSDUSize");
1713 	if (val) {
1714 		int mtu;
1715 
1716 		dut->amsdu_size = atoi(val);
1717 		if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
1718 		    dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
1719 			sigma_dut_print(dut, DUT_MSG_ERROR,
1720 					"MSDUSize %d is above max %d or below min %d",
1721 					dut->amsdu_size,
1722 					IEEE80211_MAX_DATA_LEN_DMG,
1723 					IEEE80211_SNAP_LEN_DMG);
1724 			dut->amsdu_size = 0;
1725 			return ERROR_SEND_STATUS;
1726 		}
1727 
1728 		mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
1729 		sigma_dut_print(dut, DUT_MSG_DEBUG,
1730 				"Setting amsdu_size to %d", mtu);
1731 		snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
1732 			 get_station_ifname(dut), mtu);
1733 
1734 		if (system(buf) != 0) {
1735 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
1736 					buf);
1737 			return ERROR_SEND_STATUS;
1738 		}
1739 	}
1740 
1741 	val = get_param(cmd, "BAckRcvBuf");
1742 	if (val) {
1743 		dut->back_rcv_buf = atoi(val);
1744 		if (dut->back_rcv_buf == 0) {
1745 			sigma_dut_print(dut, DUT_MSG_ERROR,
1746 					"Failed to convert %s or value is 0",
1747 					val);
1748 			return ERROR_SEND_STATUS;
1749 		}
1750 
1751 		sigma_dut_print(dut, DUT_MSG_DEBUG,
1752 				"Setting BAckRcvBuf to %s", val);
1753 	}
1754 
1755 	val = get_param(cmd, "ExtSchIE");
1756 	if (val && !strcasecmp(val, "Enable")) {
1757 		int num_allocs = MAX_ESE_ALLOCS;
1758 
1759 		if (sta_extract_60g_ese(dut, cmd, dut->ap_ese_allocs,
1760 					&num_allocs)) {
1761 			send_resp(dut, conn, SIGMA_INVALID,
1762 				  "errorCode,Invalid ExtSchIE");
1763 			return STATUS_SENT;
1764 		}
1765 		dut->ap_num_ese_allocs = num_allocs;
1766 	}
1767 
1768 	if (is_60g_sigma_dut(dut)) {
1769 		unsigned int abft_len = 1; /* default is one slot */
1770 
1771 		val = get_param(cmd, "ABFTLRang");
1772 		if (val) {
1773 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1774 					"ABFTLRang parameter %s", val);
1775 			if (strcasecmp(val, "Gt1") == 0)
1776 				abft_len = 2; /* 2 slots in this case */
1777 		}
1778 
1779 		if (sta_set_60g_abft_len(dut, conn, abft_len)) {
1780 			send_resp(dut, conn, SIGMA_ERROR,
1781 				  "ErrorCode,Can't set ABFT length");
1782 			return STATUS_SENT;
1783 		}
1784 	}
1785 
1786 	val = get_param(cmd, "OFDMA");
1787 	if (val) {
1788 		if (strcasecmp(val, "UL") == 0) {
1789 			dut->ap_he_ulofdma = VALUE_ENABLED;
1790 		} else if (strcasecmp(val, "DL") == 0) {
1791 			dut->ap_he_dlofdma = VALUE_ENABLED;
1792 		} else if (strcasecmp(val, "DL-20and80") == 0) {
1793 			dut->ap_he_dlofdma = VALUE_ENABLED;
1794 		} else {
1795 			send_resp(dut, conn, SIGMA_ERROR,
1796 				  "errorCode,Unsupported OFDMA value");
1797 			return STATUS_SENT_ERROR;
1798 		}
1799 	}
1800 
1801 	val = get_param(cmd, "NumSoundDim");
1802 	if (val)
1803 		dut->ap_numsounddim = atoi(val);
1804 
1805 	val = get_param(cmd, "BCC");
1806 	if (val) {
1807 		if (strcasecmp(val, "enable") == 0) {
1808 			dut->ap_bcc = VALUE_ENABLED;
1809 			dut->ap_ldpc = VALUE_DISABLED;
1810 		} else if (strcasecmp(val, "disable") == 0) {
1811 			dut->ap_ldpc = VALUE_ENABLED;
1812 			dut->ap_bcc = VALUE_DISABLED;
1813 		} else {
1814 			send_resp(dut, conn, SIGMA_ERROR,
1815 				  "errorCode,Unsupported BCC value");
1816 			return STATUS_SENT_ERROR;
1817 		}
1818 		switch (get_driver_type(dut)) {
1819 		case DRIVER_WCN:
1820 		case DRIVER_LINUX_WCN:
1821 			wcn_config_ap_ldpc(dut, ifname);
1822 			break;
1823 		default:
1824 			break;
1825 		}
1826 	}
1827 
1828 	val = get_param(cmd, "FrgmntSupport");
1829 	if (val) {
1830 		if (strcasecmp(val, "enable") == 0) {
1831 			dut->ap_he_frag = VALUE_ENABLED;
1832 		} else if (strcasecmp(val, "disable") == 0) {
1833 			dut->ap_he_frag = VALUE_DISABLED;
1834 		} else {
1835 			send_resp(dut, conn, SIGMA_ERROR,
1836 				  "errorCode,Unsupported FrgmntSupport value");
1837 			return STATUS_SENT_ERROR;
1838 		}
1839 	}
1840 
1841 	val = get_param(cmd, "ADDBAReq_BufSize");
1842 	if (val) {
1843 		if (strcasecmp(val, "le64") == 0) {
1844 			dut->ap_ba_bufsize = BA_BUFSIZE_64;
1845 		} else if (strcasecmp(val, "gt64") == 0) {
1846 			dut->ap_ba_bufsize = BA_BUFSIZE_256;
1847 		} else {
1848 			send_resp(dut, conn, SIGMA_ERROR,
1849 				  "errorCode,Unsupported ADDBAReq Buffer Size");
1850 			return STATUS_SENT_ERROR;
1851 		}
1852 	}
1853 
1854 	val = get_param(cmd, "ADDBAResp_BufSize");
1855 	if (val) {
1856 		if (strcasecmp(val, "gt64") == 0) {
1857 			dut->ap_ba_bufsize = BA_BUFSIZE_256;
1858 		} else {
1859 			send_resp(dut, conn, SIGMA_ERROR,
1860 				  "errorCode,Unsupported ADDBAResp Buffer Size");
1861 			return STATUS_SENT_ERROR;
1862 		}
1863 	}
1864 
1865 	val = get_param(cmd, "MU_EDCA");
1866 	if (val) {
1867 		if (strcasecmp(val, "override") == 0) {
1868 			dut->ap_mu_edca = VALUE_ENABLED;
1869 		} else if (strcasecmp(val, "disable") == 0) {
1870 			dut->ap_mu_edca = VALUE_DISABLED;
1871 		} else {
1872 			send_resp(dut, conn, SIGMA_ERROR,
1873 				  "errorCode,Unsupported mu_edca param value");
1874 			return STATUS_SENT_ERROR;
1875 		}
1876 	}
1877 
1878 	val = get_param(cmd, "MIMO");
1879 	if (val) {
1880 		if (strcasecmp(val, "DL") == 0) {
1881 			dut->ap_he_mimo = MIMO_DL;
1882 			dut->he_sounding = VALUE_DISABLED;
1883 		} else if (strcasecmp(val, "UL") == 0) {
1884 			dut->ap_he_mimo = MIMO_UL;
1885 		} else {
1886 			send_resp(dut, conn, SIGMA_ERROR,
1887 				  "errorCode,Unsupported mimo param value");
1888 			return STATUS_SENT_ERROR;
1889 		}
1890 	}
1891 
1892 	val = get_param(cmd, "HE_TXOPDurRTSThr");
1893 	if (val) {
1894 		if (strcasecmp(val, "enable") == 0) {
1895 			dut->ap_he_rtsthrshld = VALUE_ENABLED;
1896 		} else if (strcasecmp(val, "disable") == 0) {
1897 			dut->ap_he_rtsthrshld = VALUE_DISABLED;
1898 		} else {
1899 			send_resp(dut, conn, SIGMA_ERROR,
1900 				  "errorCode,Unsupported HE_TXOPDurRTSThr value");
1901 			return STATUS_SENT_ERROR;
1902 		}
1903 	}
1904 
1905 	val = get_param(cmd, "MBSSID");
1906 	if (val) {
1907 		if (strcasecmp(val, "enable") == 0) {
1908 			dut->ap_mbssid = VALUE_ENABLED;
1909 		} else if (strcasecmp(val, "disable") == 0) {
1910 			dut->ap_mbssid = VALUE_DISABLED;
1911 		} else {
1912 			send_resp(dut, conn, SIGMA_ERROR,
1913 				  "errorCode,Unsupported MBSSID Value");
1914 			return STATUS_SENT_ERROR;
1915 		}
1916 	}
1917 
1918 	val = get_param(cmd, "TWT_RespSupport");
1919 	if (val) {
1920 		if (strcasecmp(val, "enable") == 0) {
1921 			dut->ap_twtresp = VALUE_ENABLED;
1922 		} else if (strcasecmp(val, "disable") == 0) {
1923 			dut->ap_twtresp = VALUE_DISABLED;
1924 		} else {
1925 			send_resp(dut, conn, SIGMA_ERROR,
1926 				  "errorCode,Unsupported TWT_RespSupport value");
1927 			return STATUS_SENT_ERROR;
1928 		}
1929 	}
1930 
1931 	val = get_param(cmd, "MinMPDUStartSpacing");
1932 	if (val)
1933 		dut->he_mmss = atoi(val);
1934 
1935 	val = get_param(cmd, "SRCtrl_SRValue15Allowed");
1936 	if (val)
1937 		dut->he_srctrl_allow = atoi(val);
1938 
1939 	val = get_param(cmd, "ocvc");
1940 	if (val)
1941 		dut->ap_ocvc = atoi(val);
1942 
1943 	return SUCCESS_SEND_STATUS;
1944 }
1945 
1946 
ath_inject_frame(struct sigma_dut * dut,const char * ifname,int tid)1947 static void ath_inject_frame(struct sigma_dut *dut, const char *ifname, int tid)
1948 {
1949 	char buf[256];
1950 	int tid_to_dscp[] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
1951 
1952 	if (tid < 0 ||
1953 	    tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
1954 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
1955 		return;
1956 	}
1957 
1958 	snprintf(buf, sizeof(buf),
1959 		 "wlanconfig %s list sta | grep : | cut -b 1-17 > %s",
1960 		 ifname, VI_QOS_TMP_FILE);
1961 	if (system(buf) != 0)
1962 		return;
1963 
1964 	snprintf(buf, sizeof(buf),
1965 		 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
1966 		 ifname, VI_QOS_TMP_FILE);
1967 	if (system(buf) != 0)
1968 		sigma_dut_print(dut, DUT_MSG_ERROR, "Retrieve HWaddr failed");
1969 
1970 	snprintf(buf, sizeof(buf), "sed -n '3,$p' %s >> %s",
1971 		 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
1972 	if (system(buf) != 0) {
1973 		sigma_dut_print(dut, DUT_MSG_ERROR,
1974 				"Output redirection to VI_QOS_TMP_FILE failed");
1975 	}
1976 
1977 	snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
1978 		 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
1979 	if (system(buf) != 0) {
1980 		sigma_dut_print(dut, DUT_MSG_ERROR,
1981 				"Append TID to VI_QOS_FILE failed ");
1982 	}
1983 
1984 	snprintf(buf, sizeof(buf), "ethinject %s %s", ifname, VI_QOS_FILE);
1985 	if (system(buf) != 0)
1986 		sigma_dut_print(dut, DUT_MSG_ERROR, "Ethinject frame failed");
1987 }
1988 
1989 
ath_ap_send_addba_req(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)1990 static int ath_ap_send_addba_req(struct sigma_dut *dut, struct sigma_conn *conn,
1991 				 struct sigma_cmd *cmd)
1992 {
1993 	const char *val;
1994 	const char *ifname;
1995 	char buf[256];
1996 	int tid = 0;
1997 
1998 	ifname = get_main_ifname(dut);
1999 	val = get_param(cmd, "TID");
2000 	if (val) {
2001 		tid = atoi(val);
2002 		if (tid)
2003 			ath_inject_frame(dut, ifname, tid);
2004 	}
2005 
2006 	/* NOTE: This is the command sequence on Peregrine for ADDBA */
2007 	run_iwpriv(dut, ifname, "setaddbaoper 1");
2008 
2009 	snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4",
2010 		 ifname, tid);
2011 	if (system(buf) != 0) {
2012 		sigma_dut_print(dut, DUT_MSG_ERROR,
2013 				"wifitool senddelba failed");
2014 	}
2015 
2016 	snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64",
2017 		 ifname, tid);
2018 	if (system(buf) != 0) {
2019 		sigma_dut_print(dut, DUT_MSG_ERROR,
2020 				"wifitool sendaddba failed");
2021 	}
2022 
2023 	return 1;
2024 }
2025 
2026 
mac80211_debug_enable_addba_req(struct sigma_dut * dut,int tid,const char * sta_mac,const char * dir_path,int * ret)2027 static int mac80211_debug_enable_addba_req(struct sigma_dut *dut, int tid,
2028 					   const char *sta_mac,
2029 					   const char *dir_path, int *ret)
2030 {
2031 	DIR *dir;
2032 	struct dirent *entry;
2033 	char buf[128], path[128];
2034 	int res;
2035 	struct stat s;
2036 
2037 	*ret = 0;
2038 
2039 	dir = opendir(dir_path);
2040 	if (!dir)
2041 		return *ret;
2042 
2043 	while ((entry = readdir(dir))) {
2044 		if (strcmp(entry->d_name, ".") == 0 ||
2045 		    strcmp(entry->d_name, "..") == 0)
2046 			continue;
2047 
2048 		res = snprintf(path, sizeof(path) - 1, "%s/%s",
2049 			       dir_path, entry->d_name);
2050 		if (res < 0 || res >= sizeof(path))
2051 			continue;
2052 
2053 		if (strcmp(entry->d_name, sta_mac) == 0) {
2054 			res = snprintf(buf, sizeof(buf),
2055 				       "%s/aggr_mode", path);
2056 			if (res < 0 || res >= sizeof(buf) || stat(buf, &s) != 0)
2057 				continue;
2058 
2059 			res = snprintf(buf, sizeof(buf),
2060 				       "%s/addba", path);
2061 			if (res < 0 || res >= sizeof(buf) || stat(buf, &s) != 0)
2062 				continue;
2063 
2064 			*ret = 1;
2065 
2066 			res = snprintf(buf, sizeof(buf),
2067 				       "echo 1 > %s/aggr_mode", path);
2068 			if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
2069 				*ret = 0;
2070 				sigma_dut_print(dut, DUT_MSG_ERROR,
2071 						"Failed to set aggr mode for %s",
2072 						sta_mac);
2073 			}
2074 
2075 			res = snprintf(buf, sizeof(buf),
2076 				       "echo %d 32 > %s/addba", tid, path);
2077 			if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
2078 				*ret = 0;
2079 				sigma_dut_print(dut, DUT_MSG_ERROR,
2080 						"Failed to set addbareq for %s",
2081 						sta_mac);
2082 			}
2083 
2084 			break;
2085 		}
2086 
2087 		/* Recursively search subdirectories */
2088 		if (!*ret)
2089 			mac80211_debug_enable_addba_req(dut, tid, sta_mac, path,
2090 							ret);
2091 	}
2092 
2093 	closedir(dir);
2094 
2095 	return *ret;
2096 }
2097 
2098 
mac80211_ap_send_addba_req(struct sigma_dut * dut,struct sigma_cmd * cmd)2099 static int mac80211_ap_send_addba_req(struct sigma_dut *dut,
2100 				      struct sigma_cmd *cmd)
2101 {
2102 	const char *val;
2103 	int tid = 0, ret;
2104 
2105 	val = get_param(cmd, "TID");
2106 	if (val)
2107 		tid = atoi(val);
2108 
2109 	val = get_param(cmd, "sta_mac_address");
2110 	if (!val) {
2111 		sigma_dut_print(dut, DUT_MSG_ERROR,
2112 				"Failed to parse station MAC address");
2113 		return 0;
2114 	}
2115 
2116 	mac80211_debug_enable_addba_req(dut, tid, val,
2117 					"/sys/kernel/debug/ieee80211",
2118 					&ret);
2119 	return ret;
2120 }
2121 
2122 
cmd_ap_send_addba_req(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)2123 static enum sigma_cmd_result cmd_ap_send_addba_req(struct sigma_dut *dut,
2124 						   struct sigma_conn *conn,
2125 						   struct sigma_cmd *cmd)
2126 {
2127 	/* const char *name = get_param(cmd, "NAME"); */
2128 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
2129 	int ret;
2130 
2131 	switch (get_driver_type(dut)) {
2132 	case DRIVER_ATHEROS:
2133 		return ath_ap_send_addba_req(dut, conn, cmd);
2134 #ifdef __linux__
2135 	case DRIVER_WIL6210:
2136 		return send_addba_60g(dut, conn, cmd, "sta_mac_address");
2137 #endif /* __linux__ */
2138 	case DRIVER_OPENWRT:
2139 		switch (get_openwrt_driver_type()) {
2140 		case OPENWRT_DRIVER_ATHEROS:
2141 			return ath_ap_send_addba_req(dut, conn, cmd);
2142 		default:
2143 			send_resp(dut, conn, SIGMA_ERROR,
2144 				  "errorCode,ap_send_addba_req not supported with this driver");
2145 			return 0;
2146 		}
2147 	case DRIVER_WCN:
2148 	case DRIVER_LINUX_WCN:
2149 		/* AP automatically sends ADDBA request after association. */
2150 		sigma_dut_print(dut, DUT_MSG_INFO,
2151 				"ap_send_addba_req command ignored");
2152 		return 1;
2153 	case DRIVER_MAC80211:
2154 		ret = mac80211_ap_send_addba_req(dut, cmd);
2155 		if (ret)
2156 			return ret;
2157 		/* fall through */
2158 	default:
2159 		send_resp(dut, conn, SIGMA_ERROR,
2160 			  "errorCode,ap_send_addba_req not supported with this driver");
2161 		return 0;
2162 	}
2163 }
2164 
2165 
get_sae_pk_key(const char * file_name)2166 static const char * get_sae_pk_key(const char *file_name)
2167 {
2168 	if (strcasecmp(file_name, "saepk1.pem") == 0)
2169 		return SAE_PK_KEY_1;
2170 	if (strcasecmp(file_name, "saepk2.pem") == 0)
2171 		return SAE_PK_KEY_2;
2172 	if (strcasecmp(file_name, "saepkP256.pem") == 0)
2173 		return SAE_PK_KEY_P256;
2174 	if (strcasecmp(file_name, "saepkP384.pem") == 0)
2175 		return SAE_PK_KEY_P384;
2176 	if (strcasecmp(file_name, "saepkP521.pem") == 0)
2177 		return SAE_PK_KEY_P521;
2178 	return NULL;
2179 }
2180 
2181 
cmd_ap_set_security(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)2182 static enum sigma_cmd_result cmd_ap_set_security(struct sigma_dut *dut,
2183 						 struct sigma_conn *conn,
2184 						 struct sigma_cmd *cmd)
2185 {
2186 	/* const char *name = get_param(cmd, "NAME"); */
2187 	const char *val;
2188 	unsigned int wlan_tag = 1;
2189 	const char *security;
2190 
2191 	val = get_param(cmd, "WLAN_TAG");
2192 	if (val)
2193 		wlan_tag = atoi(val);
2194 
2195 	security = get_param(cmd, "Security");
2196 
2197 	if (wlan_tag > 1) {
2198 		val = get_param(cmd, "KEYMGNT");
2199 		if (!val)
2200 			val = get_param(cmd, "KeyMgmtType");
2201 		if (val) {
2202 			if (strcasecmp(val, "NONE") == 0) {
2203 				dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OPEN;
2204 			} else if (strcasecmp(val, "OSEN") == 0 &&
2205 				   wlan_tag == 2) {
2206 				/*
2207 				 * OSEN only supported on WLAN_TAG = 2 for now
2208 				 */
2209 				dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OSEN;
2210 			} else if (strcasecmp(val, "WPA2-PSK") == 0 ||
2211 				   (security &&
2212 				    strcasecmp(security, "PSK") == 0 &&
2213 				    strcasecmp(val, "WPA2") == 0)) {
2214 				dut->ap_tag_key_mgmt[wlan_tag - 2] =
2215 					AP2_WPA2_PSK;
2216 			} else if (strcasecmp(val, "OWE") == 0 &&
2217 				   wlan_tag == 2) {
2218 				dut->ap_tag_key_mgmt[wlan_tag - 2] =
2219 					AP2_WPA2_OWE;
2220 			} else {
2221 				send_resp(dut, conn, SIGMA_INVALID,
2222 					  "errorCode,Unsupported KEYMGNT");
2223 				return 0;
2224 			}
2225 			return 1;
2226 		}
2227 	}
2228 
2229 	val = get_param(cmd, "KEYMGNT");
2230 	if (!val)
2231 		val = get_param(cmd,"KeyMgmtType");
2232 	if (val) {
2233 		if (strcasecmp(val, "WPA2-PSK") == 0 ||
2234 		    (security && strcasecmp(security, "PSK") == 0 &&
2235 		     strcasecmp(val, "WPA2") == 0)) {
2236 			dut->ap_key_mgmt = AP_WPA2_PSK;
2237 			dut->ap_cipher = AP_CCMP;
2238 		} else if (strcasecmp(val, "WPA2-EAP") == 0 ||
2239 			   strcasecmp(val, "WPA2-Ent") == 0) {
2240 			dut->ap_key_mgmt = AP_WPA2_EAP;
2241 			dut->ap_cipher = AP_CCMP;
2242 		} else if (strcasecmp(val, "SuiteB") == 0) {
2243 			dut->ap_key_mgmt = AP_SUITEB;
2244 			dut->ap_cipher = AP_GCMP_256;
2245 			dut->ap_pmf = AP_PMF_REQUIRED;
2246 		} else if (strcasecmp(val, "WPA-PSK") == 0) {
2247 			dut->ap_key_mgmt = AP_WPA_PSK;
2248 			dut->ap_cipher = AP_TKIP;
2249 		} else if (strcasecmp(val, "WPA-EAP") == 0 ||
2250 			   strcasecmp(val, "WPA-Ent") == 0) {
2251 			dut->ap_key_mgmt = AP_WPA_EAP;
2252 			dut->ap_cipher = AP_TKIP;
2253 		} else if (strcasecmp(val, "WPA2-Mixed") == 0) {
2254 			dut->ap_key_mgmt = AP_WPA2_EAP_MIXED;
2255 			dut->ap_cipher = AP_CCMP_TKIP;
2256 		} else if (strcasecmp(val, "WPA2-PSK-Mixed") == 0) {
2257 			dut->ap_key_mgmt = AP_WPA2_PSK_MIXED;
2258 			dut->ap_cipher = AP_CCMP_TKIP;
2259 		} else if (strcasecmp(val, "WPA2-SAE") == 0 ||
2260 			   strcasecmp(val, "SAE") == 0) {
2261 			dut->ap_key_mgmt = AP_WPA2_SAE;
2262 			dut->ap_cipher = AP_CCMP;
2263 			dut->ap_pmf = AP_PMF_REQUIRED;
2264 		} else if (strcasecmp(val, "WPA2-PSK-SAE") == 0) {
2265 			dut->ap_key_mgmt = AP_WPA2_PSK_SAE;
2266 			dut->ap_cipher = AP_CCMP;
2267 			dut->ap_pmf = AP_PMF_OPTIONAL;
2268 		} else if (strcasecmp(val, "OWE") == 0) {
2269 			dut->ap_key_mgmt = AP_WPA2_OWE;
2270 			dut->ap_cipher = AP_CCMP;
2271 			dut->ap_pmf = AP_PMF_REQUIRED;
2272 		} else if (strcasecmp(val, "WPA2-ENT-OSEN") == 0) {
2273 			dut->ap_key_mgmt = AP_WPA2_EAP_OSEN;
2274 			dut->ap_cipher = AP_CCMP;
2275 			dut->ap_pmf = AP_PMF_OPTIONAL;
2276 		} else if (strcasecmp(val, "OSEN") == 0) {
2277 			dut->ap_key_mgmt = AP_OSEN;
2278 			dut->ap_cipher = AP_CCMP;
2279 		} else if (strcasecmp(val, "FT-EAP") == 0) {
2280 			dut->ap_key_mgmt = AP_WPA2_FT_EAP;
2281 			dut->ap_cipher = AP_CCMP;
2282 			dut->ap_pmf = AP_PMF_OPTIONAL;
2283 		} else if (strcasecmp(val, "FT-PSK") == 0) {
2284 			dut->ap_key_mgmt = AP_WPA2_FT_PSK;
2285 			dut->ap_cipher = AP_CCMP;
2286 			dut->ap_pmf = AP_PMF_OPTIONAL;
2287 		} else if (strcasecmp(val, "WPA2-ENT-256") == 0) {
2288 			dut->ap_key_mgmt = AP_WPA2_EAP_SHA256;
2289 			dut->ap_cipher = AP_CCMP;
2290 			dut->ap_pmf = AP_PMF_OPTIONAL;
2291 		} else if (strcasecmp(val, "WPA2-PSK-256") == 0) {
2292 			dut->ap_key_mgmt = AP_WPA2_PSK_SHA256;
2293 			dut->ap_cipher = AP_CCMP;
2294 			dut->ap_pmf = AP_PMF_OPTIONAL;
2295 		} else if (strcasecmp(val, "WPA2-ENT-FT-EAP") == 0) {
2296 			dut->ap_key_mgmt = AP_WPA2_ENT_FT_EAP;
2297 			dut->ap_cipher = AP_CCMP;
2298 			dut->ap_pmf = AP_PMF_OPTIONAL;
2299 		} else if (strcasecmp(val, "NONE") == 0) {
2300 			dut->ap_key_mgmt = AP_OPEN;
2301 			dut->ap_cipher = AP_PLAIN;
2302 		} else {
2303 			send_resp(dut, conn, SIGMA_INVALID,
2304 				  "errorCode,Unsupported KEYMGNT");
2305 			return 0;
2306 		}
2307 	}
2308 
2309 	val = get_param(cmd, "ECGroupID");
2310 	if (val) {
2311 		free(dut->ap_sae_groups);
2312 		dut->ap_sae_groups = strdup(val);
2313 	}
2314 
2315 	val = get_param(cmd, "AntiCloggingThreshold");
2316 	if (val)
2317 		dut->sae_anti_clogging_threshold = atoi(val);
2318 
2319 	val = get_param(cmd, "Reflection");
2320 	if (val)
2321 		dut->sae_reflection = strcasecmp(val, "SAE") == 0;
2322 
2323 	val = get_param(cmd, "InvalidSAEElement");
2324 	if (val) {
2325 		free(dut->sae_commit_override);
2326 		dut->sae_commit_override = strdup(val);
2327 	}
2328 
2329 	val = get_param(cmd, "SAEPasswords");
2330 	if (val) {
2331 		free(dut->ap_sae_passwords);
2332 		dut->ap_sae_passwords = strdup(val);
2333 	}
2334 
2335 	val = get_param(cmd, "SAE_Commit_StatusCode");
2336 	if (val)
2337 		dut->ap_sae_commit_status = atoi(val);
2338 
2339 	val = get_param(cmd, "SAE_PK_Omit");
2340 	if (val)
2341 		dut->ap_sae_pk_omit = get_enable_disable(val);
2342 
2343 	val = get_param(cmd, "SAE_Confirm_Immediate");
2344 	if (val)
2345 		dut->sae_confirm_immediate = get_enable_disable(val);
2346 
2347 	val = get_param(cmd, "sae_pwe");
2348 	if (val) {
2349 		if (strcasecmp(val, "h2e") == 0) {
2350 			dut->sae_pwe = SAE_PWE_H2E;
2351 		} else if (strcasecmp(val, "loop") == 0 ||
2352 			   strcasecmp(val, "looping") == 0) {
2353 			dut->sae_pwe = SAE_PWE_LOOP;
2354 		} else {
2355 			send_resp(dut, conn, SIGMA_ERROR,
2356 				  "errorCode,Unsupported sae_pwe value");
2357 			return STATUS_SENT_ERROR;
2358 		}
2359 	}
2360 
2361 	val = get_param(cmd, "sae_pk");
2362 	if (val)
2363 		dut->ap_sae_pk = atoi(val);
2364 
2365 	val = get_param(cmd, "SAE_PK_KeyPair");
2366 	if (!val)
2367 		val = get_param(cmd, "SAE_PK_KeyPairMism");
2368 	if (val) {
2369 		free(dut->ap_sae_pk_keypair);
2370 		dut->ap_sae_pk_keypair = NULL;
2371 
2372 		val = get_sae_pk_key(val);
2373 		if (val)
2374 			dut->ap_sae_pk_keypair = strdup(val);
2375 
2376 		if (!dut->ap_sae_pk_keypair) {
2377 			send_resp(dut, conn, SIGMA_ERROR,
2378 				  "errorCode,Unknown SAE_PK_KeyPair value");
2379 			return STATUS_SENT_ERROR;
2380 		}
2381 	}
2382 
2383 	val = get_param(cmd, "SAE_PK_KeyPairSigOverride");
2384 	if (val) {
2385 		free(dut->ap_sae_pk_keypair_sig);
2386 		dut->ap_sae_pk_keypair_sig = NULL;
2387 
2388 		val = get_sae_pk_key(val);
2389 		if (val)
2390 			dut->ap_sae_pk_keypair_sig = strdup(val);
2391 
2392 		if (!dut->ap_sae_pk_keypair_sig) {
2393 			send_resp(dut, conn, SIGMA_ERROR,
2394 				  "errorCode,Unknown SAE_PK_KeyPairSigOverride value");
2395 			return STATUS_SENT_ERROR;
2396 		}
2397 	}
2398 
2399 	val = get_param(cmd, "SAE_PK_Modifier");
2400 	if (!val)
2401 		val = get_param(cmd, "SAE_PK_ModifierMism");
2402 	if (val) {
2403 		free(dut->ap_sae_pk_modifier);
2404 		dut->ap_sae_pk_modifier = strdup(val);
2405 	}
2406 
2407 	val = get_param(cmd, "RSNXE_Content");
2408 	if (val) {
2409 		if (strncasecmp(val, "EapolM3:", 8) != 0) {
2410 			send_resp(dut, conn, SIGMA_ERROR,
2411 				  "errorCode,Unsupported RSNXE_Content value");
2412 			return STATUS_SENT_ERROR;
2413 		}
2414 		val += 8;
2415 		free(dut->rsnxe_override_eapol);
2416 		dut->rsnxe_override_eapol = strdup(val);
2417 	}
2418 
2419 	val = get_param(cmd, "ENCRYPT");
2420 	if (!val)
2421 		val = get_param(cmd, "EncpType");
2422 	if (val) {
2423 		if (strcasecmp(val, "WEP") == 0) {
2424 			dut->ap_cipher = AP_WEP;
2425 		} else if (strcasecmp(val, "TKIP") == 0) {
2426 			dut->ap_cipher = AP_TKIP;
2427 		} else if (strcasecmp(val, "AES") == 0 ||
2428 			   strcasecmp(val, "AES-CCMP") == 0) {
2429 			dut->ap_cipher = AP_CCMP;
2430 		} else if (strcasecmp(val, "AES-GCMP") == 0) {
2431 			dut->ap_cipher = AP_GCMP_128;
2432 		} else {
2433 			send_resp(dut, conn, SIGMA_INVALID,
2434 				  "errorCode,Unsupported ENCRYPT");
2435 			return 0;
2436 		}
2437 	}
2438 
2439 	val = get_param(cmd, "PairwiseCipher");
2440 	if (val) {
2441 		if (strcasecmp(val, "AES-GCMP-256") == 0) {
2442 			dut->ap_cipher = AP_GCMP_256;
2443 		} else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2444 			dut->ap_cipher = AP_CCMP_256;
2445 		} else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2446 			dut->ap_cipher = AP_GCMP_128;
2447 		} else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2448 			dut->ap_cipher = AP_CCMP;
2449 		} else if (strcasecmp(val, "AES-CCMP-128 AES-GCMP-256") == 0 ||
2450 			   strcasecmp(val, "AES-GCMP-256 AES-CCMP-128") == 0) {
2451 			dut->ap_cipher = AP_CCMP_128_GCMP_256;
2452 		} else {
2453 			send_resp(dut, conn, SIGMA_INVALID,
2454 				  "errorCode,Unsupported PairwiseCipher");
2455 			return 0;
2456 		}
2457 	}
2458 
2459 	val = get_param(cmd, "GroupCipher");
2460 	if (val) {
2461 		if (strcasecmp(val, "AES-GCMP-256") == 0) {
2462 			dut->ap_group_cipher = AP_GCMP_256;
2463 		} else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2464 			dut->ap_group_cipher = AP_CCMP_256;
2465 		} else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2466 			dut->ap_group_cipher = AP_GCMP_128;
2467 		} else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2468 			dut->ap_group_cipher = AP_CCMP;
2469 		} else {
2470 			send_resp(dut, conn, SIGMA_INVALID,
2471 				  "errorCode,Unsupported GroupCipher");
2472 			return 0;
2473 		}
2474 	}
2475 
2476 	val = get_param(cmd, "GroupMgntCipher");
2477 	if (val) {
2478 		if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2479 			dut->ap_group_mgmt_cipher = AP_BIP_GMAC_256;
2480 		} else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2481 			dut->ap_group_mgmt_cipher = AP_BIP_CMAC_256;
2482 		} else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2483 			dut->ap_group_mgmt_cipher = AP_BIP_GMAC_128;
2484 		} else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2485 			dut->ap_group_mgmt_cipher = AP_BIP_CMAC_128;
2486 		} else {
2487 			send_resp(dut, conn, SIGMA_INVALID,
2488 				  "errorCode,Unsupported GroupMgntCipher");
2489 			return 0;
2490 		}
2491 	}
2492 
2493 	val = get_param(cmd, "WEPKEY");
2494 	if (val) {
2495 		size_t len;
2496 		if (dut->ap_cipher != AP_WEP) {
2497 			send_resp(dut, conn, SIGMA_INVALID,
2498 				  "errorCode,Unexpected WEPKEY without WEP "
2499 				  "configuration");
2500 			return 0;
2501 		}
2502 		len = strlen(val);
2503 		if (len != 10 && len != 26) {
2504 			send_resp(dut, conn, SIGMA_INVALID,
2505 				  "errorCode,Unexpected WEPKEY length");
2506 			return 0;
2507 		}
2508 		snprintf(dut->ap_wepkey, sizeof(dut->ap_wepkey), "%s", val);
2509 	}
2510 
2511 	val = get_param(cmd, "PSK");
2512 	if (!val)
2513 		val = get_param(cmd, "passphrase");
2514 	if (val) {
2515 		if (dut->ap_key_mgmt != AP_WPA2_SAE &&
2516 		    (dut->ap_akm_values & (AKM_WPA_PSK | AKM_SAE)) !=
2517 		    AKM_SAE &&
2518 		    strlen(val) > 64) {
2519 			sigma_dut_print(dut, DUT_MSG_ERROR,
2520 					"Too long PSK/passphtase");
2521 			return -1;
2522 		}
2523 		if (strlen(val) > sizeof(dut->ap_passphrase) - 1)
2524 			return -1;
2525 		snprintf(dut->ap_passphrase, sizeof(dut->ap_passphrase),
2526 			 "%s", val);
2527 	}
2528 
2529 	val = get_param(cmd, "PSKHEX");
2530 	if (val) {
2531 		if (strlen(val) != 64)
2532 			return -1;
2533 		strlcpy(dut->ap_psk, val, sizeof(dut->ap_psk));
2534 	}
2535 
2536 	if (dut->program == PROGRAM_OCE && dut->dev_role == DEVROLE_STA_CFON)
2537 		dut->ap_pmf = AP_PMF_OPTIONAL;
2538 
2539 	val = get_param(cmd, "PMF");
2540 	if (val) {
2541 		if (strcasecmp(val, "Disabled") == 0) {
2542 			dut->ap_pmf = AP_PMF_DISABLED;
2543 		} else if (strcasecmp(val, "Optional") == 0) {
2544 			dut->ap_pmf = AP_PMF_OPTIONAL;
2545 		} else if (strcasecmp(val, "Required") == 0) {
2546 			dut->ap_pmf = AP_PMF_REQUIRED;
2547 		} else {
2548 			send_resp(dut, conn, SIGMA_INVALID,
2549 				  "errorCode,Unsupported PMF");
2550 			return 0;
2551 		}
2552 	}
2553 
2554 	dut->ap_add_sha256 = 0;
2555 	val = get_param(cmd, "SHA256AD");
2556 	if (val == NULL)
2557 		val = get_param(cmd, "SHA256");
2558 	if (val) {
2559 		if (strcasecmp(val, "Disabled") == 0) {
2560 		} else if (strcasecmp(val, "Enabled") == 0) {
2561 			dut->ap_add_sha256 = 1;
2562 		} else {
2563 			send_resp(dut, conn, SIGMA_INVALID,
2564 				  "errorCode,Unsupported SHA256");
2565 			return 0;
2566 		}
2567 	}
2568 
2569 	val = get_param(cmd, "PreAuthentication");
2570 	if (val) {
2571 		if (strcasecmp(val, "disabled") == 0) {
2572 			dut->ap_rsn_preauth = 0;
2573 		} else if (strcasecmp(val, "enabled") == 0) {
2574 			dut->ap_rsn_preauth = 1;
2575 		} else {
2576 			send_resp(dut, conn, SIGMA_INVALID,
2577 				  "errorCode,Unsupported PreAuthentication value");
2578 			return 0;
2579 		}
2580 	}
2581 
2582 	val = get_param(cmd, "AKMSuiteType");
2583 	if (val) {
2584 		const char *in_pos = val;
2585 
2586 		dut->ap_akm_values = 0;
2587 		while (*in_pos) {
2588 			int akm = atoi(in_pos);
2589 
2590 			if (akm < 0 || akm >= 32) {
2591 				send_resp(dut, conn, SIGMA_ERROR,
2592 					  "errorCode,Unsupported AKMSuiteType value");
2593 				return STATUS_SENT;
2594 			}
2595 
2596 			dut->ap_akm_values |= 1 << akm;
2597 
2598 			in_pos = strchr(in_pos, ';');
2599 			if (!in_pos)
2600 				break;
2601 			while (*in_pos == ';')
2602 				in_pos++;
2603 		}
2604 		dut->ap_akm = 1;
2605 		if (dut->ap_akm_values & (1 << 14))
2606 			dut->ap_add_sha384 = 1;
2607 		if (dut->ap_akm_values & (1 << 15))
2608 			dut->ap_add_sha384 = 1;
2609 	}
2610 
2611 	if (dut->ap_key_mgmt == AP_OPEN && !dut->ap_akm_values) {
2612 		dut->ap_hs2 = 0;
2613 		dut->ap_pmf = AP_PMF_DISABLED;
2614 	}
2615 
2616 	val = get_param(cmd, "PMKSACaching");
2617 	if (val) {
2618 		dut->ap_pmksa = 1;
2619 		if (strcasecmp(val, "disabled") == 0) {
2620 			dut->ap_pmksa_caching = 1;
2621 		} else if (strcasecmp(val, "enabled") == 0) {
2622 			dut->ap_pmksa_caching = 0;
2623 		} else {
2624 			send_resp(dut, conn, SIGMA_INVALID,
2625 				  "errorCode,Unsupported PMKSACaching value");
2626 			return 0;
2627 		}
2628 	}
2629 
2630 	val = get_param(cmd, "BeaconProtection");
2631 	if (val)
2632 		dut->ap_beacon_prot = atoi(val);
2633 
2634 	val = get_param(cmd, "Transition_Disable");
2635 	if (val) {
2636 		if (atoi(val)) {
2637 			val = get_param(cmd, "Transition_Disable_Index");
2638 			if (!val) {
2639 				send_resp(dut, conn, SIGMA_INVALID,
2640 					  "errorCode,Transition_Disable without Transition_Disable_Index");
2641 				return STATUS_SENT;
2642 			}
2643 			dut->ap_transition_disable = 1 << atoi(val);
2644 		} else {
2645 			dut->ap_transition_disable = 0;
2646 		}
2647 	}
2648 
2649 	return 1;
2650 }
2651 
2652 
sta_cfon_set_wireless(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)2653 int sta_cfon_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
2654 			  struct sigma_cmd *cmd)
2655 {
2656 	int status;
2657 
2658 	status = cmd_ap_set_wireless(dut, conn, cmd);
2659 	if (status != 1)
2660 		return status;
2661 	status = cmd_ap_set_security(dut, conn, cmd);
2662 	if (status != 1)
2663 		return status;
2664 	return cmd_ap_config_commit(dut, conn, cmd);
2665 }
2666 
2667 
cmd_ap_set_radius(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)2668 static enum sigma_cmd_result cmd_ap_set_radius(struct sigma_dut *dut,
2669 					       struct sigma_conn *conn,
2670 					       struct sigma_cmd *cmd)
2671 {
2672 	/* const char *name = get_param(cmd, "NAME"); */
2673 	const char *val;
2674 	unsigned int wlan_tag = 1, radius_port = 0;
2675 	char *radius_ipaddr = NULL, *radius_password = NULL;
2676 
2677 	val = get_param(cmd, "WLAN_TAG");
2678 	if (val) {
2679 		wlan_tag = atoi(val);
2680 		if (wlan_tag != 1 && wlan_tag != 2) {
2681 			send_resp(dut, conn, SIGMA_INVALID,
2682 				  "errorCode,Invalid WLAN_TAG");
2683 			return 0;
2684 		}
2685 	}
2686 
2687 	val = get_param(cmd, "PORT");
2688 	if (val)
2689 		radius_port = atoi(val);
2690 
2691 	if (wlan_tag == 1) {
2692 		if (radius_port)
2693 			dut->ap_radius_port = radius_port;
2694 		radius_ipaddr = dut->ap_radius_ipaddr;
2695 		radius_password = dut->ap_radius_password;
2696 	} else if (wlan_tag == 2) {
2697 		if (radius_port)
2698 			dut->ap2_radius_port = radius_port;
2699 		radius_ipaddr = dut->ap2_radius_ipaddr;
2700 		radius_password = dut->ap2_radius_password;
2701 	}
2702 
2703 	val = get_param(cmd, "IPADDR");
2704 	if (val) {
2705 		if (strlen(val) > sizeof(dut->ap_radius_ipaddr) - 1)
2706 			return -1;
2707 		snprintf(radius_ipaddr, sizeof(dut->ap_radius_ipaddr),
2708 			 "%s", val);
2709 	}
2710 
2711 	val = get_param(cmd, "PASSWORD");
2712 	if (val) {
2713 		if (strlen(val) > sizeof(dut->ap_radius_password) - 1)
2714 			return -1;
2715 		snprintf(radius_password,
2716 			 sizeof(dut->ap_radius_password), "%s", val);
2717 	}
2718 
2719 	return 1;
2720 }
2721 
2722 
owrt_ap_set_qcawifi(struct sigma_dut * dut,const char * key,const char * val)2723 static void owrt_ap_set_qcawifi(struct sigma_dut *dut, const char *key,
2724 				const char *val)
2725 {
2726 	if (!val) {
2727 		run_system_wrapper(dut, "uci delete wireless.qcawifi.%s", key);
2728 		return;
2729 	}
2730 
2731 	run_system(dut, "uci set wireless.qcawifi=qcawifi");
2732 	run_system_wrapper(dut, "uci set wireless.qcawifi.%s=%s", key, val);
2733 }
2734 
2735 
owrt_ap_set_radio(struct sigma_dut * dut,int id,const char * key,const char * val)2736 static void owrt_ap_set_radio(struct sigma_dut *dut, int id,
2737 			      const char *key, const char *val)
2738 {
2739 	char buf[100];
2740 
2741 	if (val == NULL) {
2742 		snprintf(buf, sizeof(buf),
2743 			 "uci delete wireless.wifi%d.%s", id, key);
2744 		run_system(dut, buf);
2745 		return;
2746 	}
2747 
2748 	snprintf(buf, sizeof(buf), "uci set wireless.wifi%d.%s=%s",
2749 		 id, key, val);
2750 	run_system(dut, buf);
2751 }
2752 
2753 
owrt_ap_set_list_radio(struct sigma_dut * dut,int id,const char * key,const char * val)2754 static void owrt_ap_set_list_radio(struct sigma_dut *dut, int id,
2755 				   const char *key, const char *val)
2756 {
2757 	char buf[256];
2758 
2759 	if (val == NULL) {
2760 		snprintf(buf, sizeof(buf),
2761 			 "uci del_list wireless.wifi%d.%s", id, key);
2762 		run_system(dut, buf);
2763 		return;
2764 	}
2765 
2766 	snprintf(buf, sizeof(buf), "uci add_list wireless.wifi%d.%s=%s",
2767 		 id, key, val);
2768 	run_system(dut, buf);
2769 }
2770 
2771 
owrt_ap_set_vap(struct sigma_dut * dut,int id,const char * key,const char * val)2772 static void owrt_ap_set_vap(struct sigma_dut *dut, int id, const char *key,
2773 			    const char *val)
2774 {
2775 	char buf[256];
2776 
2777 	if (val == NULL) {
2778 		snprintf(buf, sizeof(buf),
2779 			 "uci delete wireless.@wifi-iface[%d].%s", id, key);
2780 		run_system(dut, buf);
2781 		return;
2782 	}
2783 
2784 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2785 		 id, key, val);
2786 	run_system(dut, buf);
2787 }
2788 
2789 
owrt_ap_set_list_vap(struct sigma_dut * dut,int id,const char * key,const char * val)2790 static void owrt_ap_set_list_vap(struct sigma_dut *dut, int id,
2791 				 const char *key, const char *val)
2792 {
2793 	char buf[1024];
2794 
2795 	if (val == NULL) {
2796 		snprintf(buf, sizeof(buf),
2797 			 "uci del_list wireless.@wifi-iface[%d].%s", id, key);
2798 		run_system(dut, buf);
2799 		return;
2800 	}
2801 
2802 	snprintf(buf, sizeof(buf),
2803 		 "uci add_list wireless.@wifi-iface[%d].%s=%s",
2804 		 id, key, val);
2805 	run_system(dut, buf);
2806 }
2807 
2808 
owrt_ap_add_vap(struct sigma_dut * dut,int id,const char * key,const char * val)2809 static void owrt_ap_add_vap(struct sigma_dut *dut, int id, const char *key,
2810 			    const char *val)
2811 {
2812 	char buf[256];
2813 	int res;
2814 
2815 	if (val == NULL) {
2816 		res = snprintf(buf, sizeof(buf),
2817 			       "uci delete wireless.@wifi-iface[%d].%s",
2818 			       id, key);
2819 		if (res >= 0 && res < sizeof(buf))
2820 			run_system(dut, buf);
2821 		return;
2822 	}
2823 
2824 	run_system(dut, "uci add wireless wifi-iface");
2825 	res = snprintf(buf, sizeof(buf),
2826 		       "uci set wireless.@wifi-iface[%d].%s=%s",
2827 		       id, key, val);
2828 	if (res >= 0 && res < sizeof(buf))
2829 		run_system(dut, buf);
2830 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2831 		 id, "network", "lan");
2832 	run_system(dut, buf);
2833 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2834 		 id, "mode", "ap");
2835 	run_system(dut, buf);
2836 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2837 		 id, "encryption", "none");
2838 	run_system(dut, buf);
2839 }
2840 
2841 
2842 #define OPENWRT_MAX_NUM_RADIOS (MAX_RADIO + 1)
owrt_ap_config_radio(struct sigma_dut * dut)2843 static int owrt_ap_config_radio(struct sigma_dut *dut)
2844 {
2845 	int radio_id[MAX_RADIO] = { 0, 1, 2 };
2846 	int radio_count, radio_no;
2847 	char buf[64];
2848 
2849 	for (radio_count = 0; radio_count < OPENWRT_MAX_NUM_RADIOS;
2850 	     radio_count++) {
2851 		snprintf(buf, sizeof(buf), "%s%d", "wifi", radio_count);
2852 		for (radio_no = 0; radio_no < MAX_RADIO; radio_no++) {
2853 			if (!sigma_radio_ifname[radio_no] ||
2854 			    strcmp(sigma_radio_ifname[radio_no], buf) != 0)
2855 				continue;
2856 			owrt_ap_set_radio(dut, radio_count, "disabled", "0");
2857 			owrt_ap_set_vap(dut, radio_count, "device", buf);
2858 			radio_id[radio_no] = radio_count;
2859 		}
2860 	}
2861 
2862 	/* Hardware mode (11a/b/g/n/ac) & HT mode selection */
2863 	switch (dut->ap_mode) {
2864 	case AP_11g:
2865 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11g");
2866 		break;
2867 	case AP_11b:
2868 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11b");
2869 		break;
2870 	case AP_11ng:
2871 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng");
2872 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2873 		break;
2874 	case AP_11a:
2875 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11a");
2876 		break;
2877 	case AP_11na:
2878 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11na");
2879 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2880 		break;
2881 	case AP_11ac:
2882 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ac");
2883 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2884 		break;
2885 	case AP_11ax:
2886 		if (dut->ap_channel >= 36) {
2887 			owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axa");
2888 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2889 		} else {
2890 			owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axg");
2891 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2892 		}
2893 		break;
2894 	case AP_inval:
2895 		sigma_dut_print(dut, DUT_MSG_ERROR,
2896 				"MODE NOT SPECIFIED!");
2897 		return -1;
2898 	default:
2899 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng");
2900 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2901 		break;
2902 	}
2903 
2904 	if (dut->ap_is_dual) {
2905 		/* Hardware mode (11a/b/g/n/ac) & HT mode selection */
2906 		switch (dut->ap_mode_1) {
2907 		case AP_11g:
2908 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11g");
2909 			break;
2910 		case AP_11b:
2911 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11b");
2912 			break;
2913 		case AP_11ng:
2914 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng");
2915 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2916 			break;
2917 		case AP_11a:
2918 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11a");
2919 			break;
2920 		case AP_11na:
2921 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11na");
2922 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2923 			break;
2924 		case AP_11ac:
2925 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ac");
2926 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT80");
2927 			break;
2928 		case AP_11ax:
2929 			if (dut->ap_channel >= 36) {
2930 				owrt_ap_set_radio(dut, radio_id[1],
2931 						  "hwmode", "11axa");
2932 				owrt_ap_set_radio(dut, radio_id[1],
2933 						  "htmode", "HT80");
2934 			} else {
2935 				owrt_ap_set_radio(dut, radio_id[1],
2936 						  "hwmode", "11axg");
2937 				owrt_ap_set_radio(dut, radio_id[1],
2938 						  "htmode", "HT20");
2939 			}
2940 			break;
2941 		case AP_inval:
2942 			sigma_dut_print(dut, DUT_MSG_ERROR,
2943 					"MODE NOT SPECIFIED!");
2944 			return -1;
2945 		default:
2946 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng");
2947 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2948 			break;
2949 		}
2950 
2951 	}
2952 
2953 	/* Channel */
2954 	snprintf(buf, sizeof(buf), "%d", dut->ap_channel);
2955 	owrt_ap_set_radio(dut, radio_id[0], "channel", buf);
2956 
2957 	switch (dut->ap_chwidth) {
2958 		case AP_20:
2959 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2960 			break;
2961 		case AP_40:
2962 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT40");
2963 			break;
2964 		case AP_80:
2965 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2966 			break;
2967 		case AP_160:
2968 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT160");
2969 			break;
2970 		case AP_80_80:
2971 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80_80");
2972 			break;
2973 		case AP_AUTO:
2974 		default:
2975 			break;
2976 	}
2977 
2978 	if (dut->ap_channel == 140 || dut->ap_channel == 144) {
2979 		if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
2980 			owrt_ap_set_radio(dut, radio_id[0], "set_ch_144", "3");
2981 	}
2982 
2983 	if (dut->ap_is_dual) {
2984 		snprintf(buf, sizeof(buf), "%d", dut->ap_channel_1);
2985 		owrt_ap_set_radio(dut, radio_id[1], "channel", buf);
2986 	}
2987 
2988 	/* Country Code */
2989 	if (dut->ap_reg_domain == REG_DOMAIN_GLOBAL) {
2990 		const char *country;
2991 
2992 		country = dut->ap_countrycode[0] ? dut->ap_countrycode : "US";
2993 		snprintf(buf, sizeof(buf), "%s4", country);
2994 		owrt_ap_set_radio(dut, radio_id[0], "country", buf);
2995 		if (dut->ap_is_dual)
2996 			owrt_ap_set_radio(dut, radio_id[1], "country", buf);
2997 	} else if (dut->ap_countrycode[0]) {
2998 		owrt_ap_set_radio(dut, radio_id[0], "country",
2999 				  dut->ap_countrycode);
3000 	}
3001 
3002 	if (dut->ap_disable_protection == 1) {
3003 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'0 0'");
3004 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'1 0'");
3005 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'2 0'");
3006 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'3 0'");
3007 	}
3008 
3009 	if (dut->ap_oce == VALUE_ENABLED &&
3010 	    get_driver_type(dut) == DRIVER_OPENWRT)
3011 		owrt_ap_set_radio(dut, radio_id[0], "bcnburst", "1");
3012 
3013 	if (dut->ap_mbssid == VALUE_ENABLED)
3014 		owrt_ap_set_qcawifi(dut, "mbss_ie_enable", "1");
3015 
3016 	if (dut->program == PROGRAM_HE) {
3017 		owrt_ap_set_radio(dut, radio_id[0], "he_bsscolor", "'1 1'");
3018 		if (dut->ap_is_dual)
3019 			owrt_ap_set_radio(dut, radio_id[1], "he_bsscolor",
3020 					  "'2 1'");
3021 		owrt_ap_set_qcawifi(dut, "ap_bss_color_collision_detection",
3022 				    "1");
3023 	}
3024 
3025 	return 1;
3026 }
3027 
3028 
owrt_ap_config_vap_hs2(struct sigma_dut * dut,int vap_id)3029 static int owrt_ap_config_vap_hs2(struct sigma_dut *dut, int vap_id)
3030 {
3031 	char buf[256];
3032 
3033 	snprintf(buf, sizeof(buf), "%d", dut->ap_hs2);
3034 	owrt_ap_set_vap(dut, vap_id, "hs20", buf);
3035 	owrt_ap_set_vap(dut, vap_id, "qbssload", "1");
3036 	owrt_ap_set_vap(dut, vap_id, "hs20_deauth_req_timeout","3");
3037 
3038 	owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name",
3039 			     "'eng:Wi-Fi Alliance'");
3040 
3041 	owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name",
3042 			     "'chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f'");
3043 
3044 	if (dut->ap_wan_metrics == 1)
3045 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3046 				"'01:2500:384:0:0:10'");
3047 	else if (dut->ap_wan_metrics == 1)
3048 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3049 				"'01:1500:384:20:20:10'");
3050 	else if (dut->ap_wan_metrics == 2)
3051 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3052 				"'01:1500:384:20:20:10'");
3053 	else if (dut->ap_wan_metrics == 3)
3054 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3055 				"'01:2000:1000:20:20:10'");
3056 	else if (dut->ap_wan_metrics == 4)
3057 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3058 				"'01:8000:1000:20:20:10'");
3059 	else if (dut->ap_wan_metrics == 5)
3060 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3061 				"'01:9000:5000:20:20:10'");
3062 
3063 	if (dut->ap_conn_capab == 1) {
3064 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", "'1:0:0'");
3065 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3066 				     "'6:20:1'");
3067 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3068 				     "'6:22:0'");
3069 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3070 				     "'6:80:1'");
3071 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3072 				     "'6:443:1'");
3073 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3074 				     "'6:1723:0'");
3075 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3076 				     "'6:5060:0'");
3077 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3078 				     "'17:500:1'");
3079 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3080 				     "'17:5060:0'");
3081 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3082 				     "'17:4500:1'");
3083 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3084 				     "'50:0:1'");
3085 	} else if (dut->ap_conn_capab == 2) {
3086 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3087 				     "'6:80:1'");
3088 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3089 				     "'6:443:1'");
3090 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3091 				     "'17:5060:1'");
3092 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3093 				     "'6:5060:1'");
3094 	} else if (dut->ap_conn_capab == 3) {
3095 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3096 				     "'6:80:1'");
3097 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3098 				     "'6:443:1'");
3099 	}
3100 
3101 	if (dut->ap_oper_class == 1)
3102 		snprintf(buf, sizeof(buf), "%s", "51");
3103 	else if (dut->ap_oper_class == 2)
3104 		snprintf(buf, sizeof(buf), "%s", "73");
3105 	else if (dut->ap_oper_class == 3)
3106 		snprintf(buf, sizeof(buf), "%s", "5173");
3107 
3108 	if (dut->ap_oper_class)
3109 		owrt_ap_set_vap(dut, vap_id, "hs20_operating_class", buf);
3110 
3111 	if (dut->ap_osu_provider_list) {
3112 		char *osu_friendly_name = NULL;
3113 		char *osu_icon = NULL;
3114 		char *osu_ssid = NULL;
3115 		char *osu_nai = NULL;
3116 		char *osu_service_desc = NULL;
3117 		char *hs20_icon_filename = NULL;
3118 		char hs20_icon[150];
3119 		int osu_method;
3120 
3121 		hs20_icon_filename = "icon_red_zxx.png";
3122 		if (dut->ap_osu_icon_tag == 2)
3123 			hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3124 		snprintf(hs20_icon, sizeof(hs20_icon),
3125 			 "'128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s'",
3126 			 hs20_icon_filename);
3127 		osu_icon = "icon_red_zxx.png";
3128 		osu_ssid = "OSU";
3129 		osu_friendly_name = "'kor:SP 빨강 테스트 전용'";
3130 		osu_service_desc = "'kor:테스트 목적으로 무료 서비스'";
3131 		osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 :
3132 			dut->ap_osu_method[0];
3133 
3134 		if (strlen(dut->ap_osu_server_uri[0]))
3135 			owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri",
3136 					     dut->ap_osu_server_uri[0]);
3137 		else
3138 			owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri",
3139 					     "'https://osu-server.r2-testbed.wi-fi.org/'");
3140 		switch (dut->ap_osu_provider_list) {
3141 		case 1:
3142 		case 101:
3143 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3144 					     "'eng:SP Red Test Only'");
3145 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3146 					     "'eng:Free service for test purpose'");
3147 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3148 					     hs20_icon);
3149 
3150 			hs20_icon_filename = "icon_red_eng.png";
3151 			if (dut->ap_osu_icon_tag == 2)
3152 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3153 
3154 			snprintf(hs20_icon, sizeof(hs20_icon),
3155 				 "'160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s'",
3156 				 hs20_icon_filename);
3157 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3158 					     "icon_red_eng.png");
3159 			break;
3160 		case 2:
3161 		case 102:
3162 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3163 					     "'eng:Wireless Broadband Alliance'");
3164 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3165 					     "'eng:Free service for test purpose'");
3166 			hs20_icon_filename = "icon_orange_zxx.png";
3167 			if (dut->ap_osu_icon_tag == 2)
3168 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3169 
3170 			snprintf(hs20_icon, sizeof(hs20_icon),
3171 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3172 				 hs20_icon_filename);
3173 			osu_icon = "icon_orange_zxx.png";
3174 			osu_friendly_name = "'kor:와이어리스 브로드밴드 얼라이언스'";
3175 			break;
3176 		case 3:
3177 		case 103:
3178 			osu_friendly_name = "'spa:SP Red Test Only'";
3179 			osu_service_desc = "'spa:Free service for test purpose'";
3180 			break;
3181 		case 4:
3182 		case 104:
3183 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3184 					     "'eng:SP Orange Test Only'");
3185 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3186 					     "'eng:Free service for test purpose'");
3187 			hs20_icon_filename = "icon_orange_eng.png";
3188 			if (dut->ap_osu_icon_tag == 2)
3189 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3190 
3191 			snprintf(hs20_icon, sizeof(hs20_icon),
3192 				 "'160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s'",
3193 				 hs20_icon_filename);
3194 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3195 					     hs20_icon);
3196 			osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3197 
3198 			hs20_icon_filename = "icon_orange_zxx.png";
3199 			if (dut->ap_osu_icon_tag == 2)
3200 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3201 
3202 			snprintf(hs20_icon, sizeof(hs20_icon),
3203 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3204 				 hs20_icon_filename);
3205 			osu_icon = "icon_orange_zxx.png";
3206 			break;
3207 		case 5:
3208 		case 105:
3209 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3210 					     "'eng:SP Orange Test Only'");
3211 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3212 					     "'eng:Free service for test purpose'");
3213 			osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3214 
3215 			hs20_icon_filename = "icon_orange_zxx.png";
3216 			if (dut->ap_osu_icon_tag == 2)
3217 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3218 
3219 			snprintf(hs20_icon, sizeof(hs20_icon),
3220 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3221 				 hs20_icon_filename);
3222 			osu_icon = "icon_orange_zxx.png";
3223 			break;
3224 		case 6:
3225 		case 106:
3226 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3227 					     "'eng:SP Green Test Only'");
3228 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3229 					     "'kor:SP 초록 테스트 전용'");
3230 
3231 			hs20_icon_filename = "icon_green_zxx.png";
3232 			if (dut->ap_osu_icon_tag == 2)
3233 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3234 
3235 			snprintf(hs20_icon, sizeof(hs20_icon),
3236 				 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'",
3237 				 hs20_icon_filename);
3238 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3239 					     hs20_icon);
3240 
3241 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3242 					     "'icon_green_zxx.png'");
3243 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 :
3244 				dut->ap_osu_method[0];
3245 
3246 			snprintf(buf, sizeof(buf), "%d", osu_method);
3247 			owrt_ap_set_vap(dut, vap_id, "osu_method_list", buf);
3248 
3249 			if (strlen(dut->ap_osu_server_uri[1]))
3250 				owrt_ap_set_list_vap(dut, vap_id,
3251 						     "osu_server_uri",
3252 						     dut->ap_osu_server_uri[1]);
3253 			else
3254 				owrt_ap_set_list_vap(dut, vap_id,
3255 						     "osu_server_uri",
3256 						     "'https://osu-server.r2-testbed.wi-fi.org/'");
3257 
3258 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3259 					     "'eng:SP Orange Test Only'");
3260 
3261 			hs20_icon_filename = "icon_orange_zxx.png";
3262 			if (dut->ap_osu_icon_tag == 2)
3263 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3264 
3265 			snprintf(hs20_icon, sizeof(hs20_icon),
3266 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3267 				 hs20_icon_filename);
3268 
3269 			osu_icon = "icon_orange_zxx.png";
3270 			osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3271 			osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 :
3272 				dut->ap_osu_method[1];
3273 			osu_service_desc = NULL;
3274 			break;
3275 		case 7:
3276 		case 107:
3277 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3278 					     "'eng:SP Green Test Only'");
3279 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3280 					     "'eng:Free service for test purpose'");
3281 
3282 			hs20_icon_filename = "icon_green_eng.png";
3283 			if (dut->ap_osu_icon_tag == 2)
3284 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3285 
3286 			snprintf(hs20_icon, sizeof(hs20_icon),
3287 				 "'160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s'",
3288 				 hs20_icon_filename);
3289 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3290 					     hs20_icon);
3291 
3292 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3293 					     "'icon_green_eng.png'");
3294 			osu_friendly_name = "'kor:SP 초록 테스트 전용'";
3295 
3296 			hs20_icon_filename = "icon_green_zxx.png";
3297 			if (dut->ap_osu_icon_tag == 2)
3298 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3299 
3300 			snprintf(hs20_icon, sizeof(hs20_icon),
3301 				 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'",
3302 				 hs20_icon_filename);
3303 			osu_icon = "icon_green_zxx.png";
3304 			break;
3305 		case 8:
3306 		case 108:
3307 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3308 					     "'eng:SP Red Test Only'");
3309 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3310 					     "'eng:Free service for test purpose'");
3311 			osu_ssid = "OSU-Encrypted";
3312 			osu_nai = "'anonymous@hotspot.net'";
3313 			break;
3314 		case 9:
3315 		case 109:
3316 			osu_ssid = "OSU-OSEN";
3317 			osu_nai = "'test-anonymous@wi-fi.org'";
3318 			osu_friendly_name = "'eng:SP Orange Test Only'";
3319 			hs20_icon_filename = "icon_orange_zxx.png";
3320 			if (dut->ap_osu_icon_tag == 2)
3321 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3322 
3323 			snprintf(hs20_icon, sizeof(hs20_icon),
3324 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3325 				 hs20_icon_filename);
3326 			osu_icon = "icon_orange_zxx.png";
3327 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 :
3328 				dut->ap_osu_method[0];
3329 			osu_service_desc = NULL;
3330 			break;
3331 		default:
3332 			break;
3333 		}
3334 
3335 		if (strlen(dut->ap_osu_ssid)) {
3336 			if (dut->ap_tag_ssid[0][0] &&
3337 			    strcmp(dut->ap_tag_ssid[0],
3338 				   dut->ap_osu_ssid) != 0 &&
3339 			    strcmp(dut->ap_tag_ssid[0], osu_ssid) != 0) {
3340 				sigma_dut_print(dut, DUT_MSG_ERROR,
3341 						"OSU_SSID and WLAN_TAG2 SSID differ");
3342 				return -2;
3343 			}
3344 
3345 			snprintf(buf, sizeof(buf), "'\"%s\"'",
3346 				 dut->ap_osu_ssid);
3347 		} else {
3348 			snprintf(buf, sizeof(buf), "'\"%s\"'", osu_ssid);
3349 		}
3350 
3351 		owrt_ap_set_vap(dut, vap_id, "osu_ssid", buf);
3352 
3353 
3354 		if (osu_friendly_name)
3355 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3356 					     osu_friendly_name);
3357 		if (osu_service_desc)
3358 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3359 					     osu_service_desc);
3360 		if (osu_nai)
3361 			owrt_ap_set_vap(dut, vap_id, "osu_nai", osu_nai);
3362 
3363 		owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", hs20_icon);
3364 
3365 		if (osu_icon)
3366 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3367 					     osu_icon);
3368 
3369 		if (dut->ap_osu_provider_list > 100) {
3370 			owrt_ap_set_list_vap(dut, vap_id, "osu_method_list",
3371 					     "0");
3372 		} else {
3373 			snprintf(buf, sizeof(buf), "%d", osu_method);
3374 			owrt_ap_set_list_vap(dut, vap_id, "osu_method_list",
3375 					     buf);
3376 		}
3377 	}
3378 
3379 	return 0;
3380 }
3381 
3382 
set_anqp_elem_value(struct sigma_dut * dut,const char * ifname,char * anqp_string,size_t str_size)3383 static int set_anqp_elem_value(struct sigma_dut *dut, const char *ifname,
3384 			       char *anqp_string, size_t str_size)
3385 {
3386 	unsigned char bssid[ETH_ALEN];
3387 	unsigned char dummy_mac[] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50 };
3388 	int preference = 0xff;
3389 
3390 	if (get_hwaddr(ifname, bssid) < 0)
3391 		return -1;
3392 	snprintf(anqp_string, str_size,
3393 		 "272:3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x",
3394 		 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5],
3395 		 preference,
3396 		 dummy_mac[0], dummy_mac[1], dummy_mac[2],
3397 		 dummy_mac[3], dummy_mac[4], dummy_mac[5],
3398 		 preference - 1);
3399 	return 0;
3400 }
3401 
3402 
get_hostapd_ifname(struct sigma_dut * dut)3403 const char * get_hostapd_ifname(struct sigma_dut *dut)
3404 {
3405 	enum driver_type drv;
3406 
3407 	/* Use the configured hostapd ifname */
3408 	if (dut->hostapd_ifname && if_nametoindex(dut->hostapd_ifname) > 0)
3409 		return dut->hostapd_ifname;
3410 
3411 	/* Use configured main ifname */
3412 	if (dut->main_ifname) {
3413 		if (dut->use_5g && dut->main_ifname_5g &&
3414 		    if_nametoindex(dut->main_ifname_5g) > 0)
3415 			return dut->main_ifname_5g;
3416 		if (!dut->use_5g && dut->main_ifname_2g &&
3417 		    if_nametoindex(dut->main_ifname_2g) > 0)
3418 			return dut->main_ifname_2g;
3419 		if (if_nametoindex(dut->main_ifname) > 0)
3420 			return dut->main_ifname;
3421 	}
3422 
3423 	/* Return based on driver type (indirectly started hostapd) */
3424 	drv = get_driver_type(dut);
3425 	if (drv == DRIVER_ATHEROS) {
3426 		if (dut->use_5g && if_nametoindex("ath1") > 0)
3427 			return "ath1";
3428 		return "ath0";
3429 	}
3430 
3431 	if (drv == DRIVER_OPENWRT) {
3432 		if (sigma_radio_ifname[0] &&
3433 		    strcmp(sigma_radio_ifname[0], "wifi2") == 0)
3434 			return "ath2";
3435 		if (sigma_radio_ifname[0] &&
3436 		    strcmp(sigma_radio_ifname[0], "wifi1") == 0)
3437 			return "ath1";
3438 		return "ath0";
3439 	}
3440 
3441 	/* wlan1-is-likely-5-GHz design */
3442 	if (dut->use_5g && if_nametoindex("wlan1") > 0)
3443 		return "wlan1";
3444 
3445 	/* If nothing else matches, hope for the best and guess this is wlan0 */
3446 	return "wlan0";
3447 }
3448 
3449 
get_if_name(struct sigma_dut * dut,char * ifname_str,size_t str_size,int wlan_tag)3450 static void get_if_name(struct sigma_dut *dut, char *ifname_str,
3451 			size_t str_size, int wlan_tag)
3452 {
3453 	const char *ifname;
3454 	enum driver_type drv;
3455 
3456 	ifname = get_hostapd_ifname(dut);
3457 	drv = get_driver_type(dut);
3458 
3459 	if (drv == DRIVER_OPENWRT && wlan_tag > 1) {
3460 		/* Handle tagged-ifname only on OPENWRT for now */
3461 		snprintf(ifname_str, str_size, "%s%d", ifname, wlan_tag - 1);
3462 	} else if ((drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN) &&
3463 		   wlan_tag == 2) {
3464 		snprintf(ifname_str, str_size, "%s_1", ifname);
3465 	} else {
3466 		snprintf(ifname_str, str_size, "%s", ifname);
3467 	}
3468 }
3469 
3470 
sae_pw_id_used(struct sigma_dut * dut)3471 static int sae_pw_id_used(struct sigma_dut *dut)
3472 {
3473 	return dut->ap_sae_passwords &&
3474 		strchr(dut->ap_sae_passwords, ':');
3475 }
3476 
3477 
owrt_ap_config_vap(struct sigma_dut * dut)3478 static int owrt_ap_config_vap(struct sigma_dut *dut)
3479 {
3480 	char buf[256], *temp;
3481 	int vap_id = 0, vap_count, i, j, res;
3482 	const char *ifname;
3483 	char ifname2[50];
3484 
3485 	if (sigma_radio_ifname[0] &&
3486 	    strcmp(sigma_radio_ifname[0], "wifi2") == 0)
3487 		ifname = "ath2";
3488 	else if (sigma_radio_ifname[0] &&
3489 		 strcmp(sigma_radio_ifname[0], "wifi1") == 0)
3490 		ifname = "ath1";
3491 	else
3492 		ifname = "ath0";
3493 
3494 	for (vap_count = 0; vap_count < OPENWRT_MAX_NUM_RADIOS; vap_count++) {
3495 		snprintf(buf, sizeof(buf), "wifi%d", vap_count);
3496 
3497 		for (vap_id = 0; vap_id < MAX_RADIO; vap_id++) {
3498 			if (sigma_radio_ifname[vap_id] &&
3499 			    strcmp(sigma_radio_ifname[vap_id], buf) == 0)
3500 				break;
3501 		}
3502 		if (vap_id == MAX_RADIO)
3503 			continue;
3504 
3505 		/* Single VAP configuration */
3506 		if (!dut->ap_is_dual)
3507 			vap_id = vap_count;
3508 
3509 		for (j = 0; j < MAX_WLAN_TAGS - 1; j++) {
3510 			/*
3511 			 * We keep a separate array of ap_tag_ssid and
3512 			 * ap_tag_key_mgmt for tags starting from WLAN_TAG=2.
3513 			 * So j=0 => WLAN_TAG = 2
3514 			 */
3515 			int wlan_tag = j + 2;
3516 
3517 			if (wlan_tag == 2 && dut->program == PROGRAM_WPA3 &&
3518 			   (dut->ap_interface_5g || dut->ap_interface_2g)) {
3519 				res = snprintf(
3520 					dut->ap_tag_ssid[wlan_tag - 2],
3521 					sizeof(dut->ap_tag_ssid[wlan_tag - 2]),
3522 					"%s-owe", dut->ap_ssid);
3523 				if (res < 0 ||
3524 				    res >= sizeof(dut->ap_tag_ssid[wlan_tag -
3525 								   2]))
3526 					dut->ap_tag_ssid[wlan_tag - 2][0] =
3527 						'\0';
3528 			}
3529 
3530 			if (dut->ap_tag_ssid[j][0] == '\0')
3531 				continue;
3532 
3533 			snprintf(buf, sizeof(buf), "%s%d", "wifi", vap_count);
3534 			owrt_ap_add_vap(dut, vap_count + (wlan_tag - 1),
3535 					"device", buf);
3536 			/* SSID */
3537 			snprintf(buf, sizeof(buf), "\"%s\"",
3538 				 dut->ap_tag_ssid[j]);
3539 			owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3540 					"ssid", buf);
3541 
3542 			if (dut->ap_key_mgmt == AP_WPA2_OWE &&
3543 			    dut->ap_tag_ssid[0][0] &&
3544 			    dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
3545 				/* OWE transition mode */
3546 				snprintf(buf, sizeof(buf), "%s", ifname);
3547 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3548 						"owe_transition_ifname", buf);
3549 			}
3550 
3551 			if (dut->ap_key_mgmt == AP_OPEN &&
3552 			    dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3553 				/* OWE transition mode */
3554 				snprintf(buf, sizeof(buf), "%s", ifname);
3555 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3556 						"owe_transition_ifname", buf);
3557 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3558 						"hidden", "1");
3559 			}
3560 
3561 			if (ap_ft_enabled(dut)) {
3562 				unsigned char self_mac[ETH_ALEN];
3563 				char mac_str[20];
3564 
3565 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3566 						"mobility_domain",
3567 						dut->ap_mobility_domain);
3568 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3569 						"ft_over_ds",
3570 						dut->ap_ft_ds == VALUE_ENABLED ?
3571 						"1" : "0");
3572 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3573 						"ieee80211r", "1");
3574 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3575 						"nasid", "nas1.example.com");
3576 				if (get_hwaddr(sigma_radio_ifname[0],
3577 					       self_mac) < 0)
3578 					return -1;
3579 				snprintf(mac_str, sizeof(mac_str),
3580 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3581 					 self_mac[0], self_mac[1], self_mac[2],
3582 					 self_mac[3], self_mac[4], self_mac[5]);
3583 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3584 						"ap_macaddr", mac_str);
3585 				snprintf(mac_str, sizeof(mac_str),
3586 					 "%02x%02x%02x%02x%02x%02x",
3587 					 self_mac[0], self_mac[1], self_mac[2],
3588 					 self_mac[3], self_mac[4], self_mac[5]);
3589 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3590 						"r1_key_holder", mac_str);
3591 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3592 						"ft_psk_generate_local", "1");
3593 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3594 						"kh_key_hex",
3595 						"000102030405060708090a0b0c0d0e0f");
3596 				snprintf(mac_str, sizeof(mac_str),
3597 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3598 					 dut->ft_bss_mac_list[0][0],
3599 					 dut->ft_bss_mac_list[0][1],
3600 					 dut->ft_bss_mac_list[0][2],
3601 					 dut->ft_bss_mac_list[0][3],
3602 					 dut->ft_bss_mac_list[0][4],
3603 					 dut->ft_bss_mac_list[0][5]);
3604 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3605 						"ap2_macaddr", mac_str);
3606 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3607 						"ap2_r1_key_holder", mac_str);
3608 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3609 						"nasid2", "nas2.example.com");
3610 			}
3611 
3612 			if (dut->ap_tag_key_mgmt[j] == AP2_OSEN &&
3613 			    wlan_tag == 2) {
3614 				/* Only supported for WLAN_TAG=2 */
3615 				owrt_ap_set_vap(dut, vap_count + 1, "osen",
3616 						"1");
3617 				snprintf(buf, sizeof(buf), "wpa2");
3618 				owrt_ap_set_vap(dut, vap_count + 1,
3619 						"encryption", buf);
3620 				snprintf(buf, sizeof(buf), "%s",
3621 					 dut->ap2_radius_ipaddr);
3622 				owrt_ap_set_vap(dut, vap_count + 1,
3623 						"auth_server", buf);
3624 				snprintf(buf, sizeof(buf), "%d",
3625 					 dut->ap2_radius_port);
3626 				owrt_ap_set_vap(dut, vap_count + 1,
3627 						"auth_port", buf);
3628 				snprintf(buf, sizeof(buf), "%s",
3629 					 dut->ap2_radius_password);
3630 				owrt_ap_set_vap(dut, vap_count + 1,
3631 						"auth_secret", buf);
3632 			} else if (dut->ap_tag_key_mgmt[j] == AP2_WPA2_PSK) {
3633 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3634 						"encryption", "psk2+ccmp");
3635 				snprintf(buf, sizeof(buf), "\"%s\"",
3636 					 dut->ap_passphrase);
3637 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3638 						"key", buf);
3639 				snprintf(buf, sizeof(buf), "%d", dut->ap_pmf);
3640 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3641 						"ieee80211w", buf);
3642 			} else if (dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3643 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3644 						"owe", "1");
3645 				snprintf(buf, sizeof(buf), "ccmp");
3646 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3647 						"encryption", buf);
3648 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3649 						"ieee80211w", "2");
3650 				if (dut->ap_sae_groups) {
3651 					snprintf(buf, sizeof(buf), "\'%s\'",
3652 						 dut->ap_sae_groups);
3653 					owrt_ap_set_list_vap(dut, vap_count +
3654 							     (wlan_tag - 1),
3655 							     "owe_groups", buf);
3656 				}
3657 
3658 				if (dut->owe_ptk_workaround)
3659 					owrt_ap_set_list_vap(
3660 						dut, vap_count + (wlan_tag - 1),
3661 						"owe_ptk_workaround", "1");
3662 			}
3663 		}
3664 
3665 		/* Now set anqp_elem and ft_oa for wlan_tag = 1 */
3666 		if (dut->program == PROGRAM_MBO &&
3667 		    get_driver_type(dut) == DRIVER_OPENWRT) {
3668 			unsigned char self_mac[ETH_ALEN];
3669 			char mac_str[20];
3670 			char anqp_string[200];
3671 
3672 			if (set_anqp_elem_value(dut, sigma_radio_ifname[0],
3673 						anqp_string,
3674 						sizeof(anqp_string)) < 0)
3675 				return -1;
3676 			owrt_ap_set_list_vap(dut, vap_count, "anqp_elem",
3677 					     anqp_string);
3678 
3679 			if (ap_ft_enabled(dut)) {
3680 				owrt_ap_set_vap(dut, vap_count,
3681 						"mobility_domain",
3682 						dut->ap_mobility_domain);
3683 				owrt_ap_set_vap(dut, vap_count,
3684 						"ft_over_ds",
3685 						dut->ap_ft_ds == VALUE_ENABLED ?
3686 						"1" : "0");
3687 				owrt_ap_set_vap(dut, vap_count,
3688 						"ieee80211r", "1");
3689 				owrt_ap_set_vap(dut, vap_count,
3690 						"nasid", "nas1.example.com");
3691 				get_hwaddr(sigma_radio_ifname[0], self_mac);
3692 				snprintf(mac_str, sizeof(mac_str),
3693 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3694 					 self_mac[0], self_mac[1], self_mac[2],
3695 					 self_mac[3], self_mac[4], self_mac[5]);
3696 				owrt_ap_set_vap(dut, vap_count,
3697 						"ap_macaddr", mac_str);
3698 				snprintf(mac_str, sizeof(mac_str),
3699 					 "%02x%02x%02x%02x%02x%02x",
3700 					 self_mac[0], self_mac[1], self_mac[2],
3701 					 self_mac[3], self_mac[4], self_mac[5]);
3702 				owrt_ap_set_vap(dut, vap_count,
3703 						"r1_key_holder", mac_str);
3704 				owrt_ap_set_vap(dut, vap_count,
3705 						"ft_psk_generate_local", "1");
3706 				owrt_ap_set_vap(dut, vap_count,
3707 						"kh_key_hex",
3708 						"000102030405060708090a0b0c0d0e0f");
3709 				snprintf(mac_str, sizeof(mac_str),
3710 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3711 					 dut->ft_bss_mac_list[0][0],
3712 					 dut->ft_bss_mac_list[0][1],
3713 					 dut->ft_bss_mac_list[0][2],
3714 					 dut->ft_bss_mac_list[0][3],
3715 					 dut->ft_bss_mac_list[0][4],
3716 					 dut->ft_bss_mac_list[0][5]);
3717 				owrt_ap_set_vap(dut, vap_count,
3718 						"ap2_macaddr", mac_str);
3719 				owrt_ap_set_vap(dut, vap_count,
3720 						"ap2_r1_key_holder", mac_str);
3721 				owrt_ap_set_vap(dut, vap_count,
3722 						"nasid2", "nas2.example.com");
3723 			}
3724 		}
3725 
3726 		if (dut->ap_oce == VALUE_ENABLED &&
3727 		    get_driver_type(dut) == DRIVER_OPENWRT) {
3728 			owrt_ap_set_vap(dut, vap_id, "oce", "1");
3729 			owrt_ap_set_vap(dut, vap_id, "qbssload", "1");
3730 			owrt_ap_set_vap(dut, vap_id, "bpr_enable", "1");
3731 
3732 			if (dut->ap_80plus80 == 1)
3733 				owrt_ap_set_vap(dut, vap_id, "cfreq2", "5775");
3734 
3735 			if (dut->ap_akm == 1) {
3736 				owrt_ap_set_vap(dut, vap_id, "wpa_group_rekey",
3737 						"3600");
3738 				owrt_ap_set_vap(dut, vap_id, "key", "12345678");
3739 				owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3740 						"1");
3741 				owrt_ap_set_vap(dut, vap_id, "fils_cache_id",
3742 						"1234");
3743 				owrt_ap_set_vap(dut, vap_id,
3744 						"erp_send_reauth_start", "1");
3745 			}
3746 
3747 			if (dut->ap_filshlp == VALUE_ENABLED) {
3748 				struct ifreq ifr;
3749 				char *ifname;
3750 				int s;
3751 				struct sockaddr_in *ipaddr;
3752 
3753 				s = socket(AF_INET, SOCK_DGRAM, 0);
3754 				if (s < 0) {
3755 					sigma_dut_print(dut, DUT_MSG_ERROR,
3756 							"Failed to open socket");
3757 					return -1;
3758 				}
3759 				ifr.ifr_addr.sa_family = AF_INET;
3760 
3761 				memset(&ifr, 0, sizeof(ifr));
3762 				ifname = "br-lan";
3763 				strlcpy(ifr.ifr_name, ifname,
3764 					sizeof(ifr.ifr_name));
3765 				if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
3766 					perror("ioctl");
3767 					close(s);
3768 					return -1;
3769 				}
3770 
3771 				ipaddr = (struct sockaddr_in*)&ifr.ifr_addr;
3772 				snprintf(buf, sizeof(buf), "%s",
3773 					 inet_ntoa(ipaddr->sin_addr));
3774 				owrt_ap_set_vap(dut, vap_id, "own_ip_addr",
3775 						buf);
3776 				snprintf(buf, sizeof(buf), "%s",
3777 					 dut->ap_dhcpserv_ipaddr);
3778 				owrt_ap_set_vap(dut, vap_id, "dhcp_server",
3779 						buf);
3780 				owrt_ap_set_vap(dut, vap_id,
3781 						"dhcp_rapid_commit_proxy", "1");
3782 				owrt_ap_set_vap(dut, vap_id,
3783 						"fils_hlp_wait_time", "300");
3784 			}
3785 
3786 			if (dut->ap_filsdscv == VALUE_ENABLED) {
3787 				owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3788 						"1");
3789 				owrt_ap_set_vap(dut, vap_id, "fils_fd_period",
3790 						"20");
3791 			}
3792 		}
3793 
3794 		if (dut->ap_filsdscv == VALUE_DISABLED) {
3795 			owrt_ap_set_vap(dut, vap_id, "ieee80211ai", "0");
3796 			owrt_ap_set_vap(dut, vap_id, "fils_fd_period", "0");
3797 		}
3798 
3799 		if (dut->ap_oce == VALUE_DISABLED &&
3800 		    get_driver_type(dut) == DRIVER_OPENWRT) {
3801 			owrt_ap_set_vap(dut, vap_id, "oce", "0");
3802 			owrt_ap_set_vap(dut, vap_id, "qbssload", "0");
3803 			owrt_ap_set_vap(dut, vap_id, "bpr_enable", "0");
3804 
3805 			if (dut->ap_filsdscv == VALUE_DISABLED) {
3806 				owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3807 						"0");
3808 				owrt_ap_set_vap(dut, vap_id, "fils_fd_period",
3809 						"0");
3810 			}
3811 
3812 			if (dut->device_type == AP_testbed)
3813 				owrt_ap_set_vap(dut, vap_id, "mbo", "1");
3814 		}
3815 
3816 		/* NAIRealm */
3817 		if (dut->ap_nairealm_int == 1) {
3818 			snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_nairealm);
3819 			owrt_ap_set_vap(dut, vap_id, "fils_realm", buf);
3820 			owrt_ap_set_vap(dut, vap_id, "erp_domain", buf);
3821 		}
3822 
3823 		/* SSID */
3824 		snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_ssid);
3825 		owrt_ap_set_vap(dut, vap_count, "ssid", buf);
3826 
3827 		/* Encryption */
3828 		switch (dut->ap_key_mgmt) {
3829 		case AP_OPEN:
3830 			if (dut->ap_cipher == AP_WEP) {
3831 				owrt_ap_set_vap(dut, vap_count, "encryption",
3832 						"wep-mixed");
3833 				owrt_ap_set_vap(dut, vap_count, "key",
3834 						dut->ap_wepkey);
3835 			} else {
3836 				owrt_ap_set_vap(dut, vap_count, "encryption",
3837 						"none");
3838 			}
3839 			if (dut->ap_key_mgmt == AP_OPEN &&
3840 			    dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3841 				/* OWE transition mode */
3842 				snprintf(ifname2, sizeof(ifname2), "%s1",
3843 					 ifname);
3844 				owrt_ap_set_vap(dut, vap_count,
3845 						"owe_transition_ifname",
3846 						ifname2);
3847 			}
3848 			break;
3849 		case AP_WPA2_PSK:
3850 		case AP_WPA2_PSK_MIXED:
3851 		case AP_WPA_PSK:
3852 		case AP_WPA2_SAE:
3853 		case AP_WPA2_PSK_SAE:
3854 			if (dut->ap_key_mgmt == AP_WPA2_PSK ||
3855 			    dut->ap_key_mgmt == AP_WPA2_PSK_SAE) {
3856 				snprintf(buf, sizeof(buf), "psk2");
3857 			} else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) {
3858 				snprintf(buf, sizeof(buf), "psk-mixed");
3859 			} else if (dut->ap_key_mgmt == AP_WPA2_SAE) {
3860 				snprintf(buf, sizeof(buf), "ccmp");
3861 			} else {
3862 				snprintf(buf, sizeof(buf), "psk");
3863 			}
3864 
3865 			if (dut->ap_key_mgmt != AP_WPA2_SAE) {
3866 				if (dut->ap_cipher == AP_CCMP_TKIP)
3867 					strlcat(buf, "+ccmp+tkip", sizeof(buf));
3868 				else if (dut->ap_cipher == AP_TKIP)
3869 					strlcat(buf, "+tkip", sizeof(buf));
3870 				else if (dut->ap_cipher == AP_GCMP_128)
3871 					strlcat(buf, "+gcmp", sizeof(buf));
3872 				else
3873 					strlcat(buf, "+ccmp", sizeof(buf));
3874 			}
3875 
3876 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3877 
3878 			if (!dut->ap_passphrase[0] && dut->ap_psk[0]) {
3879 				snprintf(buf, sizeof(buf), "\"%s\"",
3880 					 dut->ap_psk);
3881 				owrt_ap_set_vap(dut, vap_count, "key", buf);
3882 			} else {
3883 				snprintf(buf, sizeof(buf), "\"%s\"",
3884 					 dut->ap_passphrase);
3885 				owrt_ap_set_vap(dut, vap_count, "key", buf);
3886 			}
3887 
3888 			if (dut->ap_key_mgmt == AP_WPA2_SAE ||
3889 			    dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
3890 				owrt_ap_set_vap(dut, vap_count, "sae", "1");
3891 			else
3892 				owrt_ap_set_vap(dut, vap_count, "sae", "0");
3893 
3894 			if (dut->ap_key_mgmt == AP_WPA2_SAE && dut->ap_sae_pk &&
3895 			    dut->ap_sae_pk_keypair_sig) {
3896 				snprintf(buf, sizeof(buf), "%s|pk=%s:%s:%s",
3897 					 dut->ap_passphrase,
3898 					 dut->ap_sae_pk_modifier,
3899 					 dut->ap_sae_pk_keypair,
3900 					 dut->ap_sae_pk_keypair_sig);
3901 				owrt_ap_set_vap(dut, vap_count, "sae_password",
3902 						buf);
3903 			} else if (dut->ap_key_mgmt == AP_WPA2_SAE &&
3904 				   dut->ap_sae_pk) {
3905 				snprintf(buf, sizeof(buf), "%s|pk=%s:%s",
3906 					 dut->ap_passphrase,
3907 					 dut->ap_sae_pk_modifier,
3908 					 dut->ap_sae_pk_keypair);
3909 				owrt_ap_set_vap(dut, vap_count, "sae_password",
3910 						buf);
3911 			} else if (dut->ap_key_mgmt == AP_WPA2_SAE) {
3912 				snprintf(buf, sizeof(buf), "%s",
3913 					 dut->ap_passphrase);
3914 				owrt_ap_set_vap(dut, vap_count, "sae_password",
3915 						buf);
3916 			} else {
3917 				snprintf(buf, sizeof(buf), "%s",
3918 					 dut->ap_passphrase);
3919 				owrt_ap_set_vap(dut, vap_count,
3920 						"wpa_passphrase", buf);
3921 			}
3922 			break;
3923 		case AP_WPA2_EAP:
3924 		case AP_WPA2_EAP_MIXED:
3925 		case AP_WPA_EAP:
3926 			if (dut->ap_key_mgmt == AP_WPA2_EAP) {
3927 				snprintf(buf, sizeof(buf), "wpa2");
3928 			} else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) {
3929 				snprintf(buf, sizeof(buf), "wpa-mixed");
3930 			} else {
3931 				snprintf(buf, sizeof(buf), "wpa");
3932 			}
3933 
3934 			if (dut->ap_cipher == AP_CCMP_TKIP)
3935 				strlcat(buf, "+ccmp+tkip", sizeof(buf));
3936 			else if (dut->ap_cipher == AP_TKIP)
3937 				strlcat(buf, "+tkip", sizeof(buf));
3938 			else
3939 				strlcat(buf, "+ccmp", sizeof(buf));
3940 
3941 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3942 			snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr);
3943 			owrt_ap_set_vap(dut, vap_count, "auth_server", buf);
3944 			snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port);
3945 			owrt_ap_set_vap(dut, vap_count, "auth_port", buf);
3946 			snprintf(buf, sizeof(buf), "%s",
3947 				 dut->ap_radius_password);
3948 			owrt_ap_set_vap(dut, vap_count, "auth_secret", buf);
3949 			break;
3950 		case AP_WPA2_EAP_OSEN:
3951 		case AP_OSEN:
3952 		case AP_WPA2_FT_EAP:
3953 		case AP_WPA2_FT_PSK:
3954 		case AP_WPA2_EAP_SHA256:
3955 		case AP_WPA2_PSK_SHA256:
3956 		case AP_WPA2_ENT_FT_EAP:
3957 			/* TODO */
3958 			break;
3959 		case AP_SUITEB:
3960 			owrt_ap_set_vap(dut, vap_count, "suite_b", "192");
3961 			snprintf(buf, sizeof(buf), "gcmp");
3962 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3963 			snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr);
3964 			owrt_ap_set_vap(dut, vap_count, "auth_server", buf);
3965 			snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port);
3966 			owrt_ap_set_vap(dut, vap_count, "auth_port", buf);
3967 			snprintf(buf, sizeof(buf), "%s",
3968 				 dut->ap_radius_password);
3969 			owrt_ap_set_vap(dut, vap_count, "auth_secret", buf);
3970 			snprintf(buf, sizeof(buf), "%d",
3971 				 dut->ap_group_mgmt_cipher);
3972 			owrt_ap_set_vap(dut, vap_count, "group_mgmt_cipher",
3973 					buf);
3974 			break;
3975 		case AP_WPA2_OWE:
3976 			owrt_ap_set_vap(dut, vap_count, "owe", "1");
3977 			snprintf(buf, sizeof(buf), "ccmp");
3978 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3979 			if (dut->ap_sae_groups) {
3980 				snprintf(buf, sizeof(buf), "\'%s\'",
3981 					 dut->ap_sae_groups);
3982 				owrt_ap_set_list_vap(dut, vap_count,
3983 						     "owe_groups", buf);
3984 			}
3985 
3986 			if (dut->owe_ptk_workaround)
3987 				owrt_ap_set_list_vap(dut, vap_count,
3988 						     "owe_ptk_workaround", "1");
3989 
3990 			if (dut->ap_key_mgmt == AP_WPA2_OWE &&
3991 			    dut->ap_tag_ssid[0][0] &&
3992 			    dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
3993 				/* OWE transition mode */
3994 				snprintf(ifname2, sizeof(ifname2), "%s1",
3995 					 ifname);
3996 				owrt_ap_set_vap(dut, vap_count,
3997 						"owe_transition_ifname",
3998 						ifname2);
3999 				owrt_ap_set_vap(dut, vap_count, "hidden", "1");
4000 			}
4001 			break;
4002 		}
4003 
4004 		if (!dut->ap_is_dual)
4005 			break;
4006 	}
4007 
4008 	if (dut->ap_is_dual)
4009 		return 1;
4010 
4011 	/* PMF */
4012 	snprintf(buf, sizeof(buf), "%d", dut->ap_pmf);
4013 	owrt_ap_set_vap(dut, vap_id, "ieee80211w", buf);
4014 
4015 	/* Add SHA256 */
4016 	snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha256);
4017 	owrt_ap_set_vap(dut, vap_id, "add_sha256", buf);
4018 
4019 	/* Add SHA384 for akmsuitetype 15 */
4020 	if (dut->ap_akm == 1) {
4021 		snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha384);
4022 		owrt_ap_set_vap(dut, vap_id, "add_sha384", buf);
4023 	}
4024 
4025 	/* Enable RSN preauthentication, if asked to */
4026 	snprintf(buf, sizeof(buf), "%d", dut->ap_rsn_preauth);
4027 	owrt_ap_set_vap(dut, vap_id, "rsn_preauth", buf);
4028 
4029 	/* Hotspot 2.0 */
4030 	if (dut->ap_hs2) {
4031 		int ret;
4032 
4033 		ret = owrt_ap_config_vap_hs2(dut, vap_id);
4034 		if (ret)
4035 			return ret;
4036 	}
4037 
4038 	/* Interworking */
4039 	if (dut->ap_interworking) {
4040 		snprintf(buf, sizeof(buf), "%d", dut->ap_access_net_type);
4041 		owrt_ap_set_vap(dut, vap_id, "access_network_type", buf);
4042 		snprintf(buf, sizeof(buf), "%d", dut->ap_internet);
4043 		owrt_ap_set_vap(dut, vap_id, "internet", buf);
4044 		snprintf(buf, sizeof(buf), "%d", dut->ap_venue_group);
4045 		owrt_ap_set_vap(dut, vap_id, "venue_group", buf);
4046 		snprintf(buf, sizeof(buf), "%d", dut->ap_venue_type);
4047 		owrt_ap_set_vap(dut, vap_id, "venue_type", buf);
4048 		snprintf(buf, sizeof(buf), "%s", dut->ap_hessid);
4049 		owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4050 
4051 		if (dut->ap_gas_cb_delay > 0) {
4052 			snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay);
4053 			owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf);
4054 		}
4055 
4056 		if (dut->ap_roaming_cons[0]) {
4057 			char *rcons, *temp_ptr;
4058 
4059 			rcons = strdup(dut->ap_roaming_cons);
4060 			if (rcons == NULL)
4061 				return -1;
4062 
4063 			temp_ptr = strchr(rcons, ';');
4064 
4065 			if (temp_ptr)
4066 				*temp_ptr++ = '\0';
4067 
4068 			owrt_ap_set_list_vap(dut, vap_id, "roaming_consortium",
4069 					     rcons);
4070 
4071 			if (temp_ptr)
4072 				owrt_ap_set_list_vap(dut, vap_id,
4073 						     "roaming_consortium",
4074 						     temp_ptr);
4075 
4076 			free(rcons);
4077 		}
4078 	}
4079 
4080 	if (dut->ap_venue_name) {
4081 		owrt_ap_set_list_vap(dut, vap_id, "venue_name",
4082 				     "'P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"'");
4083 		owrt_ap_set_list_vap(dut, vap_id, "venue_name",
4084 				     "\'"ANQP_VENUE_NAME_1_CHI"\'");
4085 	}
4086 
4087 	if (dut->ap_net_auth_type == 1) {
4088 		owrt_ap_set_list_vap(dut, vap_id, "network_auth_type",
4089 				     "'00https://tandc-server.wi-fi.org'");
4090 	} else if (dut->ap_net_auth_type == 2) {
4091 		owrt_ap_set_list_vap(dut, vap_id, "network_auth_type", "'01'");
4092 	}
4093 
4094 	if (dut->ap_nai_realm_list == 1) {
4095 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4096 				     "'0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]'");
4097 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4098 				     "'0,wi-fi.org;example.com,13[5:6]'");
4099 
4100 	} else if (dut->ap_nai_realm_list == 2) {
4101 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4102 				     "'0,wi-fi.org,21[2:4][5:7]'");
4103 	} else if (dut->ap_nai_realm_list == 3) {
4104 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4105 				     "'0,cisco.com;wi-fi.org,21[2:4][5:7]'");
4106 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4107 				     "'0,wi-fi.org;example.com,13[5:6]'");
4108 	} else if (dut->ap_nai_realm_list == 4) {
4109 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4110 				     "'0,mail.example.com,21[2:4][5:7],13[5:6]'");
4111 	} else if (dut->ap_nai_realm_list == 5) {
4112 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4113 				     "'0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]'");
4114 	} else if (dut->ap_nai_realm_list == 6) {
4115 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4116 				     "'0,wi-fi.org;mail.example.com,21[2:4][5:7]'");
4117 	} else if (dut->ap_nai_realm_list == 7) {
4118 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4119 				     "'0,wi-fi.org,13[5:6]'");
4120 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4121 				     "'0,wi-fi.org,21[2:4][5:7]'");
4122 	}
4123 
4124 	if (dut->ap_domain_name_list[0])
4125 		owrt_ap_set_list_vap(dut, vap_id, "domain_name",
4126 				     dut->ap_domain_name_list);
4127 
4128 	if (dut->ap_ip_addr_type_avail)
4129 		owrt_ap_set_vap(dut, vap_id, "ipaddr_type_availability",
4130 				"'0c'");
4131 
4132 	temp = buf;
4133 
4134 	*temp++ = '\'';
4135 
4136 	for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) {
4137 		if (i)
4138 			*temp++ = ';';
4139 
4140 		snprintf(temp,
4141 			 sizeof(dut->ap_plmn_mcc[i]) +
4142 			 sizeof(dut->ap_plmn_mnc[i]) + 1,
4143 			 "%s,%s",
4144 			 dut->ap_plmn_mcc[i],
4145 			 dut->ap_plmn_mnc[i]);
4146 
4147 		temp += strlen(dut->ap_plmn_mcc[i]) +
4148 			strlen(dut->ap_plmn_mnc[i]) + 1;
4149 	}
4150 
4151 	*temp++ = '\'';
4152 	*temp++ = '\0';
4153 
4154 	if (i)
4155 		owrt_ap_set_vap(dut, vap_id, "anqp_3gpp_cell_net", buf);
4156 
4157 	if (dut->ap_qos_map_set == 1)
4158 		owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_1);
4159 	else if (dut->ap_qos_map_set == 2)
4160 		owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_2);
4161 
4162 	/* Proxy-ARP */
4163 	snprintf(buf, sizeof(buf), "%d", dut->ap_proxy_arp);
4164 	owrt_ap_set_vap(dut, vap_id, "proxyarp", buf);
4165 
4166 	/* DGAF */
4167 	snprintf(buf, sizeof(buf), "%d", dut->ap_dgaf_disable);
4168 	/* parse to hostapd */
4169 	owrt_ap_set_vap(dut, vap_id, "disable_dgaf", buf);
4170 	/* parse to wifi driver */
4171 	owrt_ap_set_vap(dut, vap_id, "dgaf_disable", buf);
4172 
4173 	/* HCBSSLoad */
4174 	if (dut->ap_bss_load) {
4175 		unsigned int bssload = 0;
4176 
4177 		if (dut->ap_bss_load == 1) {
4178 			/* STA count: 1, CU: 50, AAC: 65535 */
4179 			bssload = 0x0132ffff;
4180 		} else if (dut->ap_bss_load == 2) {
4181 			/* STA count: 1, CU: 200, AAC: 65535 */
4182 			bssload = 0x01c8ffff;
4183 		} else if (dut->ap_bss_load == 3) {
4184 			/* STA count: 1, CU: 75, AAC: 65535 */
4185 			bssload = 0x014bffff;
4186 		}
4187 
4188 		snprintf(buf, sizeof(buf), "%d", bssload);
4189 		owrt_ap_set_vap(dut, vap_id, "hcbssload", buf);
4190 	}
4191 
4192 	/* L2TIF */
4193 	if  (dut->ap_l2tif)
4194 		owrt_ap_set_vap(dut, vap_id, "l2tif", "1");
4195 
4196 	if (dut->ap_disable_protection == 1)
4197 		owrt_ap_set_vap(dut, vap_id, "enablertscts", "0");
4198 
4199 	if (dut->ap_txBF) {
4200 		owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "1");
4201 		owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "1");
4202 		if (dut->program == PROGRAM_HE) {
4203 			owrt_ap_set_vap(dut, vap_id, "he_subfer", "1");
4204 			owrt_ap_set_vap(dut, vap_id, "cwmenable", "0");
4205 		}
4206 	} else {
4207 		owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0");
4208 		owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0");
4209 		if (dut->program == PROGRAM_HE)
4210 			owrt_ap_set_vap(dut, vap_id, "he_subfer", "0");
4211 	}
4212 
4213 	if (dut->ap_mu_txBF) {
4214 		owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "1");
4215 		if (dut->program == PROGRAM_HE) {
4216 			owrt_ap_set_vap(dut, vap_id, "he_mubfer", "1");
4217 			owrt_ap_set_vap(dut, vap_id, "he_mubfee", "1");
4218 		}
4219 	} else {
4220 		owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "0");
4221 		if (dut->program == PROGRAM_HE) {
4222 			owrt_ap_set_vap(dut, vap_id, "he_mubfer", "0");
4223 			owrt_ap_set_vap(dut, vap_id, "he_mubfee", "0");
4224 		}
4225 	}
4226 
4227 	if (dut->ap_tx_stbc) {
4228 		/* STBC and beamforming are mutually exclusive features */
4229 		owrt_ap_set_vap(dut, vap_id, "implicitbf", "0");
4230 	}
4231 
4232 	/* enable dfsmode */
4233 	snprintf(buf, sizeof(buf), "%d", dut->ap_dfs_mode);
4234 	owrt_ap_set_vap(dut, vap_id, "doth", buf);
4235 
4236 	if (dut->program == PROGRAM_LOC && dut->ap_interworking) {
4237 		char anqpval[1024];
4238 
4239 		owrt_ap_set_vap(dut, vap_id, "interworking", "1");
4240 
4241 		if (dut->ap_lci == 1 && strlen(dut->ap_tag_ssid[0]) == 0) {
4242 			snprintf(anqpval, sizeof(anqpval),
4243 				"'265:0010%s%s060101'",
4244 				dut->ap_val_lci, dut->ap_infoz);
4245 			owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4246 		}
4247 
4248 		if (dut->ap_lcr == 1) {
4249 			snprintf(anqpval, sizeof(anqpval),
4250 				"'266:0000b2555302ae%s'",
4251 				dut->ap_val_lcr);
4252 			owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4253 		}
4254 
4255 		if (dut->ap_fqdn_held == 1 && dut->ap_fqdn_supl == 1)
4256 			owrt_ap_set_list_vap(dut, vap_id, "anqp_elem",
4257 					     "'267:00110168656c642e6578616d706c652e636f6d0011027375706c2e6578616d706c652e636f6d'");
4258 	}
4259 
4260 	if (dut->program == PROGRAM_MBO) {
4261 		owrt_ap_set_vap(dut, vap_id, "interworking", "1");
4262 		owrt_ap_set_vap(dut, vap_id, "mbo", "1");
4263 		owrt_ap_set_vap(dut, vap_id, "rrm", "1");
4264 		owrt_ap_set_vap(dut, vap_id, "mbo_cell_conn_pref", "1");
4265 
4266 		owrt_ap_set_list_vap(dut, vap_id, "anqp_elem",
4267 				     "'272:34108cfdf0020df1f7000000733000030101'");
4268 		snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay);
4269 		owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf);
4270 	}
4271 
4272 	if (ap_ft_enabled(dut)) {
4273 		unsigned char self_mac[ETH_ALEN];
4274 		char mac_str[20];
4275 
4276 		owrt_ap_set_vap(dut, vap_id, "ft_over_ds",
4277 				dut->ap_ft_ds == VALUE_ENABLED ? "1" : "0");
4278 		owrt_ap_set_vap(dut, vap_id, "ieee80211r", "1");
4279 		if (get_hwaddr(sigma_radio_ifname[0], self_mac) < 0)
4280 			return -1;
4281 		snprintf(mac_str, sizeof(mac_str),
4282 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4283 			 self_mac[0], self_mac[1], self_mac[2],
4284 			 self_mac[3], self_mac[4], self_mac[5]);
4285 		owrt_ap_set_vap(dut, vap_id, "ap_macaddr", mac_str);
4286 		snprintf(mac_str, sizeof(mac_str),
4287 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4288 			 self_mac[0], self_mac[1], self_mac[2],
4289 			 self_mac[3], self_mac[4], self_mac[5]);
4290 		owrt_ap_set_vap(dut, vap_id, "r1_key_holder", mac_str);
4291 		owrt_ap_set_vap(dut, vap_id, "ft_psk_generate_local", "1");
4292 		owrt_ap_set_vap(dut, vap_id, "kh_key_hex",
4293 				"000102030405060708090a0b0c0d0e0f");
4294 		snprintf(mac_str, sizeof(mac_str),
4295 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4296 			 dut->ft_bss_mac_list[0][0],
4297 			 dut->ft_bss_mac_list[0][1],
4298 			 dut->ft_bss_mac_list[0][2],
4299 			 dut->ft_bss_mac_list[0][3],
4300 			 dut->ft_bss_mac_list[0][4],
4301 			 dut->ft_bss_mac_list[0][5]);
4302 		owrt_ap_set_vap(dut, vap_id, "ap2_macaddr", mac_str);
4303 		owrt_ap_set_vap(dut, vap_id, "mobility_domain",
4304 				dut->ap_mobility_domain);
4305 		owrt_ap_set_vap(dut, vap_id, "ap2_r1_key_holder", mac_str);
4306 	}
4307 
4308 	if ((ap_ft_enabled(dut) && dut->ap_name == 0) ||
4309 	    (ap_ft_enabled(dut) && dut->ap_name == 2)) {
4310 		owrt_ap_set_vap(dut, vap_id, "nasid2", "nas2.example.com");
4311 		owrt_ap_set_vap(dut, vap_id, "nasid", "nas1.example.com");
4312 	}
4313 
4314 	if (ap_ft_enabled(dut) && dut->ap_name == 1) {
4315 		owrt_ap_set_vap(dut, vap_id, "nasid2", "nas1.example.com");
4316 		owrt_ap_set_vap(dut, vap_id, "nasid", "nas2.example.com");
4317 	}
4318 
4319 	if (dut->ap_broadcast_ssid == VALUE_DISABLED)
4320 		owrt_ap_set_vap(dut, vap_id, "hidden", "1");
4321 
4322 	/* Enable/disable PMKSA caching, if asked to */
4323 	if (dut->ap_pmksa == 1) {
4324 		snprintf(buf, sizeof(buf), "%d", dut->ap_pmksa_caching);
4325 		owrt_ap_set_vap(dut, vap_id, "disable_pmksa_caching", buf);
4326 	}
4327 
4328 	if (dut->ap_beacon_prot)
4329 		owrt_ap_set_vap(dut, vap_id, "beacon_prot", "1");
4330 
4331 	if (dut->ap_transition_disable) {
4332 		snprintf(buf, sizeof(buf), "0x%02x",
4333 			 dut->ap_transition_disable);
4334 		owrt_ap_set_vap(dut, vap_id, "transition_disable", buf);
4335 	}
4336 
4337 	if (dut->rsne_override) {
4338 		snprintf(buf, sizeof(buf), "%s", dut->rsne_override);
4339 		owrt_ap_set_vap(dut, vap_count, "own_ie_override", buf);
4340 	}
4341 
4342 	if (dut->rsnxe_override_eapol)
4343 		owrt_ap_set_vap(dut, vap_count, "rsnxe_override_eapol",
4344 				dut->rsnxe_override_eapol);
4345 
4346 	if (dut->sae_commit_override) {
4347 		snprintf(buf, sizeof(buf), "%s", dut->sae_commit_override);
4348 		owrt_ap_set_vap(dut, vap_count, "sae_commit_override", buf);
4349 	}
4350 
4351 	if (dut->ap_sae_groups) {
4352 		snprintf(buf, sizeof(buf), "\'%s\'", dut->ap_sae_groups);
4353 		owrt_ap_set_list_vap(dut, vap_count, "sae_groups", buf);
4354 	}
4355 
4356 	if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) {
4357 		const char *sae_pwe = NULL;
4358 
4359 		if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut))
4360 			sae_pwe = "3";
4361 		else if (dut->sae_pwe == SAE_PWE_LOOP)
4362 			sae_pwe = "0";
4363 		else if (dut->sae_pwe == SAE_PWE_H2E)
4364 			sae_pwe = "1";
4365 		else if (dut->sae_h2e_default)
4366 			sae_pwe = "2";
4367 		if (sae_pwe)
4368 			owrt_ap_set_vap(dut, vap_count, "sae_pwe", sae_pwe);
4369 	}
4370 
4371 	if (dut->sae_anti_clogging_threshold >= 0) {
4372 		snprintf(buf, sizeof(buf), "%d",
4373 			 dut->sae_anti_clogging_threshold);
4374 		owrt_ap_set_vap(dut, vap_count, "sae_anti_clogging_threshold",
4375 				buf);
4376 	}
4377 
4378 	if (dut->sae_reflection)
4379 		owrt_ap_set_vap(dut, vap_count, "sae_reflection_attack", "1");
4380 	if (dut->ap_sae_commit_status >= 0) {
4381 		snprintf(buf, sizeof(buf), "%d", dut->ap_sae_commit_status);
4382 		owrt_ap_set_vap(dut, vap_count, "sae_commit_status", buf);
4383 	}
4384 	if (dut->ap_sae_pk_omit)
4385 		owrt_ap_set_vap(dut, vap_count, "sae_pk_omit", "1");
4386 	if (dut->sae_confirm_immediate)
4387 		owrt_ap_set_vap(dut, vap_count, "sae_confirm_immediate", "2");
4388 
4389 	if (dut->ap_he_dlofdma == VALUE_ENABLED && dut->ap_he_ppdu == PPDU_MU) {
4390 		dut->ap_txBF = 0;
4391 		dut->ap_mu_txBF = 0;
4392 		owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0");
4393 		owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0");
4394 		owrt_ap_set_vap(dut, vap_id, "he_subfer", "0");
4395 	}
4396 
4397 	if (dut->program == PROGRAM_HE &&
4398 	    (dut->ap_txBF || dut->ap_he_ulofdma == VALUE_ENABLED ||
4399 	     dut->ap_he_mimo == MIMO_DL)) {
4400 		switch (dut->ap_chwidth) {
4401 		case AP_20:
4402 			owrt_ap_set_vap(dut, vap_id, "chwidth", "0");
4403 			break;
4404 		case AP_40:
4405 			owrt_ap_set_vap(dut, vap_id, "chwidth", "1");
4406 			break;
4407 		case AP_80:
4408 			owrt_ap_set_vap(dut, vap_id, "chwidth", "2");
4409 			break;
4410 		case AP_160:
4411 			owrt_ap_set_vap(dut, vap_id, "chwidth", "3");
4412 			break;
4413 		case AP_80_80:
4414 			owrt_ap_set_vap(dut, vap_id, "chwidth", "3");
4415 			break;
4416 		case AP_AUTO:
4417 		default:
4418 			break;
4419 		}
4420 	}
4421 
4422 	if (dut->ap_ocvc == 1)
4423 		owrt_ap_set_vap(dut, vap_count, "ocv", "1");
4424 	else if (dut->ap_ocvc == 0)
4425 		owrt_ap_set_vap(dut, vap_count, "ocv", "0");
4426 
4427 	return 1;
4428 }
4429 
4430 
owrt_ap_config_vap_anqp(struct sigma_dut * dut)4431 static int owrt_ap_config_vap_anqp(struct sigma_dut *dut)
4432 {
4433 	char anqpval[1024];
4434 	unsigned char addr[6];
4435 	unsigned char addr2[6];
4436 	struct ifreq ifr;
4437 	char *ifname;
4438 	int s;
4439 	int vap_id = 0;
4440 
4441 	s = socket(AF_INET, SOCK_DGRAM, 0);
4442 	if (s < 0) {
4443 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open socket");
4444 		return -1;
4445 	}
4446 
4447 	memset(&ifr, 0, sizeof(ifr));
4448 	ifname = "ath0";
4449 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
4450 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
4451 		perror("ioctl");
4452 		close(s);
4453 		return -1;
4454 	}
4455 	memcpy(addr, ifr.ifr_hwaddr.sa_data, 6);
4456 
4457 	memset(&ifr, 0, sizeof(ifr));
4458 	ifname = "ath01";
4459 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
4460 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
4461 		perror("ioctl");
4462 		close(s);
4463 		return -1;
4464 	}
4465 	close(s);
4466 	memcpy(addr2, ifr.ifr_hwaddr.sa_data, 6);
4467 
4468 	snprintf(anqpval, sizeof(anqpval),
4469 		 "'265:0010%s%s060101070d00%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'",
4470 		 dut->ap_val_lci, dut->ap_infoz,
4471 		 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
4472 		 addr2[0], addr2[1], addr2[2], addr2[3], addr2[4], addr2[5]);
4473 
4474 	owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4475 	return 0;
4476 }
4477 
4478 
owrt_ap_post_config_commit(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)4479 static int owrt_ap_post_config_commit(struct sigma_dut *dut,
4480 				      struct sigma_conn *conn,
4481 				      struct sigma_cmd *cmd)
4482 {
4483 	int ap_security = 0;
4484 	int i;
4485 
4486 	for (i = 0; i < MAX_WLAN_TAGS - 1; i++) {
4487 		if (dut->ap_tag_key_mgmt[i] != AP2_OPEN)
4488 			ap_security = 1;
4489 	}
4490 	if (dut->ap_key_mgmt != AP_OPEN)
4491 		ap_security = 1;
4492 	if (ap_security) {
4493 		/* allow some time for hostapd to start before returning
4494 		 * success */
4495 		usleep(500000);
4496 
4497 		if (run_hostapd_cli(dut, "ping") != 0) {
4498 			send_resp(dut, conn, SIGMA_ERROR,
4499 				  "errorCode,Failed to talk to hostapd");
4500 			return 0;
4501 		}
4502 	}
4503 
4504 	if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
4505 		ath_ap_set_params(dut);
4506 
4507 	/* Send response */
4508 	return 1;
4509 }
4510 
4511 
cmd_owrt_ap_config_commit(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)4512 static int cmd_owrt_ap_config_commit(struct sigma_dut *dut,
4513 				     struct sigma_conn *conn,
4514 				     struct sigma_cmd *cmd)
4515 {
4516 	if (dut->program == PROGRAM_DPP &&
4517 	    get_driver_type(dut) == DRIVER_OPENWRT) {
4518 		wpa_command(dut->hostapd_ifname, "DPP_BOOTSTRAP_REMOVE *");
4519 		wpa_command(dut->hostapd_ifname, "DPP_PKEX_REMOVE *");
4520 	}
4521 
4522 	/* Stop the AP */
4523 	run_system(dut, "wifi down");
4524 
4525 	/* Reset the wireless configuration */
4526 	run_system(dut, "rm -rf /etc/config/wireless");
4527 	switch (get_openwrt_driver_type()) {
4528 	case OPENWRT_DRIVER_ATHEROS:
4529 		run_system(dut, "wifi detect qcawifi > /etc/config/wireless");
4530 		break;
4531 	default:
4532 		run_system(dut, "wifi detect > /etc/config/wireless");
4533 		break;
4534 	}
4535 
4536 	/* Configure Radio & VAP, commit the config */
4537 	if (owrt_ap_config_radio(dut) < 0)
4538 		return ERROR_SEND_STATUS;
4539 	if (owrt_ap_config_vap(dut) < 0)
4540 		return ERROR_SEND_STATUS;
4541 	run_system(dut, "uci commit");
4542 
4543 	/* Start AP */
4544 	run_system(dut, "wifi up");
4545 	if (dut->program != PROGRAM_MBO &&
4546 	    dut->ap_lci == 1 && dut->ap_interworking &&
4547 	    strlen(dut->ap_tag_ssid[0]) > 0) {
4548 		/*
4549 		 * MBO has a different ANQP element value which is set in
4550 		 * owrt_ap_config_vap().
4551 		 */
4552 		owrt_ap_config_vap_anqp(dut);
4553 		run_system(dut, "uci commit");
4554 		run_system(dut, "wifi");
4555 	}
4556 
4557 	return owrt_ap_post_config_commit(dut, conn, cmd);
4558 }
4559 
4560 
cmd_owrt_ap_hs2_reset(struct sigma_dut * dut)4561 static void cmd_owrt_ap_hs2_reset(struct sigma_dut *dut)
4562 {
4563 	unsigned char bssid[6];
4564 	char buf[100];
4565 	char *ifname, *radio_name;
4566 	int vap_id = 0;
4567 
4568 	if (sigma_radio_ifname[0] &&
4569 	    strcmp(sigma_radio_ifname[0], "wifi2") == 0) {
4570 		ifname = "ath2";
4571 		radio_name = "wifi2";
4572 		vap_id = 2;
4573 	} else if (sigma_radio_ifname[0] &&
4574 		   strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
4575 		ifname = "ath1";
4576 		radio_name = "wifi1";
4577 		vap_id = 1;
4578 	} else {
4579 		ifname = "ath0";
4580 		radio_name = "wifi0";
4581 		vap_id = 0;
4582 	}
4583 
4584 	if (!get_hwaddr(ifname, bssid)) {
4585 		snprintf(buf, sizeof(buf), "%s", bssid);
4586 		owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4587 		snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4588 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4589 			 bssid[0], bssid[1], bssid[2], bssid[3],
4590 			 bssid[4], bssid[5]);
4591 	} else {
4592 		if (!get_hwaddr(radio_name, bssid)) {
4593 			snprintf(buf, sizeof(buf), "%s", dut->ap_hessid);
4594 			owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4595 			snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4596 				 "%02x:%02x:%02x:%02x:%02x:%02x",
4597 				 bssid[0], bssid[1], bssid[2], bssid[3],
4598 				 bssid[4], bssid[5]);
4599 		} else {
4600 			/* Select & enable/disable radios */
4601 			if (sigma_radio_ifname[0] &&
4602 			    strcmp(sigma_radio_ifname[0], "wifi2") == 0) {
4603 				/* We want to use wifi2 */
4604 				owrt_ap_set_radio(dut, 0, "disabled", "1");
4605 				owrt_ap_set_radio(dut, 1, "disabled", "1");
4606 				owrt_ap_set_radio(dut, 2, "disabled", "0");
4607 				owrt_ap_set_vap(dut, vap_id, "device", "wifi2");
4608 			} else if (sigma_radio_ifname[0] &&
4609 				   strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
4610 				/* We want to use wifi1 */
4611 				owrt_ap_set_radio(dut, 0, "disabled", "1");
4612 				owrt_ap_set_radio(dut, 1, "disabled", "0");
4613 				owrt_ap_set_vap(dut, vap_id, "device", "wifi1");
4614 			} else {
4615 				/* We want to use wifi0 */
4616 				owrt_ap_set_radio(dut, 0, "disabled", "0");
4617 				owrt_ap_set_radio(dut, 1, "disabled", "1");
4618 				owrt_ap_set_vap(dut, vap_id, "device", "wifi0");
4619 			}
4620 
4621 			run_system(dut, "uci commit");
4622 			run_system(dut, "wifi up");
4623 
4624 			if (!get_hwaddr(radio_name, bssid)) {
4625 				snprintf(buf, sizeof(buf), "%s",
4626 					 dut->ap_hessid);
4627 				owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4628 				snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4629 					 "%02x:%02x:%02x:%02x:%02x:%02x",
4630 					 bssid[0], bssid[1], bssid[2], bssid[3],
4631 					 bssid[4], bssid[5]);
4632 			}
4633 		}
4634 	}
4635 }
4636 
4637 
cmd_ap_reboot(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)4638 static enum sigma_cmd_result cmd_ap_reboot(struct sigma_dut *dut,
4639 					   struct sigma_conn *conn,
4640 					   struct sigma_cmd *cmd)
4641 {
4642 	switch (get_driver_type(dut)) {
4643 	case DRIVER_ATHEROS:
4644 		run_system(dut, "apdown");
4645 		sleep(1);
4646 		run_system(dut, "reboot");
4647 		break;
4648 	case DRIVER_OPENWRT:
4649 		run_system(dut, "wifi down");
4650 		sleep(1);
4651 		run_system(dut, "reboot");
4652 		break;
4653 	default:
4654 		sigma_dut_print(dut, DUT_MSG_INFO, "Ignore ap_reboot command");
4655 		break;
4656 	}
4657 
4658 	return 1;
4659 }
4660 
4661 
ascii2hexstr(const char * str,char * hex)4662 int ascii2hexstr(const char *str, char *hex)
4663 {
4664 	int i, length;
4665 
4666 	length = strlen(str);
4667 
4668 	for (i = 0; i < length; i++)
4669 		snprintf(hex + i * 2, 3, "%X", str[i]);
4670 
4671 	hex[length * 2] = '\0';
4672 	return 1;
4673 }
4674 
4675 
kill_process(struct sigma_dut * dut,char * proc_name,unsigned char is_proc_instance_one,int sig)4676 static int kill_process(struct sigma_dut *dut, char *proc_name,
4677 			unsigned char is_proc_instance_one, int sig)
4678 {
4679 #ifdef __linux__
4680 	struct dirent *dp, *dp_in;
4681 	const char *direc = "/proc/";
4682 	char buf[100];
4683 	DIR *dir = opendir(direc);
4684 	DIR *dir_in;
4685 	FILE *fp;
4686 	char *pid, *temp;
4687 	char *saveptr;
4688 	int ret = -1, res;
4689 
4690 	if (dir == NULL)
4691 		return ret;
4692 
4693 	while ((dp = readdir(dir)) != NULL) {
4694 		if (dp->d_type != DT_DIR)
4695 			continue;
4696 
4697 		res = snprintf(buf, sizeof(buf), "%s%s", direc, dp->d_name);
4698 		if (res < 0 || res >= sizeof(buf))
4699 			continue;
4700 		dir_in = opendir(buf);
4701 		if (dir_in == NULL)
4702 			continue;
4703 		dp_in = readdir(dir_in);
4704 		closedir(dir_in);
4705 		if (dp_in == NULL)
4706 			continue;
4707 		res = snprintf(buf, sizeof(buf), "%s%s/stat",
4708 			       direc, dp->d_name);
4709 		if (res < 0 || res >= sizeof(buf))
4710 			continue;
4711 		fp = fopen(buf, "r");
4712 		if (fp == NULL)
4713 			continue;
4714 		if (fgets(buf, 100, fp) == NULL)
4715 			buf[0] = '\0';
4716 		fclose(fp);
4717 		pid = strtok_r(buf, " ", &saveptr);
4718 		temp = strtok_r(NULL, " ", &saveptr);
4719 		if (pid && temp &&
4720 		    strncmp(temp, proc_name, strlen(proc_name)) == 0) {
4721 			sigma_dut_print(dut, DUT_MSG_INFO,
4722 					"killing %s process with PID %s",
4723 					proc_name, pid);
4724 			snprintf(buf, sizeof(buf), "kill -%d %d", sig,
4725 				 atoi(pid));
4726 			run_system(dut, buf);
4727 			ret = 0;
4728 			if (is_proc_instance_one)
4729 				break;
4730 		}
4731 	}
4732 
4733 	closedir(dir);
4734 
4735 	return ret;
4736 #else /* __linux__ */
4737 	return -1;
4738 #endif /* __linux__ */
4739 }
4740 
4741 
run_ndc(struct sigma_dut * dut,char * buf)4742 static int run_ndc(struct sigma_dut *dut, char *buf)
4743 {
4744 	sigma_dut_print(dut, DUT_MSG_INFO, "CMD NDC:: %s", buf);
4745 	sleep(2);
4746 	return run_system(dut, buf);
4747 }
4748 
4749 
sigma_write_cfg(struct sigma_dut * dut,const char * pfile,const char * field,const char * value)4750 static int sigma_write_cfg(struct sigma_dut *dut, const char *pfile,
4751 			   const char *field, const char *value)
4752 {
4753 	FILE *fcfg, *ftmp;
4754 	char buf[MAX_CONF_LINE_LEN + 1];
4755 	int len, found = 0, res;
4756 
4757 	/* Open the configuration file */
4758 	fcfg = fopen(pfile, "r");
4759 	if (!fcfg) {
4760 		sigma_dut_print(dut, DUT_MSG_ERROR,
4761 				"Failed to open hostapd conf file");
4762 		return -1;
4763 	}
4764 
4765 	snprintf(buf, sizeof(buf), "%s~", pfile);
4766 	/* Open a temporary file */
4767 	ftmp = fopen(buf, "w+");
4768 	if (!ftmp) {
4769 		fclose(fcfg);
4770 		sigma_dut_print(dut, DUT_MSG_ERROR,
4771 				"Failed to open temp buf");
4772 		return -1;
4773 	}
4774 
4775 	/* Read the values from the configuration file */
4776 	len = strlen(field);
4777 	while (fgets(buf, MAX_CONF_LINE_LEN, fcfg)) {
4778 		char *pline = buf;
4779 
4780 		/* commented line */
4781 		if (buf[0] == '#')
4782 			pline++;
4783 
4784 		/* Identify the configuration parameter to be updated */
4785 		if (!found && strncmp(pline, field, len) == 0 &&
4786 		    pline[len] == '=') {
4787 			snprintf(buf, sizeof(buf), "%s=%s\n", field, value);
4788 			found = 1;
4789 			sigma_dut_print(dut, DUT_MSG_INFO,
4790 					"Updated hostapd conf file");
4791 		}
4792 
4793 		fprintf(ftmp, "%s", buf);
4794 	}
4795 
4796 	if (!found) {
4797 		/* Configuration line not found */
4798 		/* Add the new line at the end of file */
4799 		fprintf(ftmp, "%s=%s\n", field, value);
4800 		sigma_dut_print(dut, DUT_MSG_INFO,
4801 				"Adding a new line in hostapd conf file");
4802 	}
4803 
4804 	fclose(fcfg);
4805 	fclose(ftmp);
4806 
4807 	snprintf(buf, sizeof(buf), "%s~", pfile);
4808 
4809 	/* Restore the updated configuration file */
4810 	res = rename(buf, pfile);
4811 
4812 	/* Remove the temporary file. Ignore the return value */
4813 	unlink(buf);
4814 
4815 	/* chmod is needed because open() may not set permissions properly
4816 	 * depending on the current umask */
4817 	if (chmod(pfile, 0660) < 0) {
4818 		unlink(pfile);
4819 		sigma_dut_print(dut, DUT_MSG_ERROR,
4820 				"Error changing permissions");
4821 		return -1;
4822 	}
4823 
4824 	if (res < 0) {
4825 		sigma_dut_print(dut, DUT_MSG_ERROR,
4826 				"Error restoring conf file");
4827 		return -1;
4828 	}
4829 
4830 	return 0;
4831 }
4832 
4833 
cmd_wcn_ap_config_commit(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)4834 static int cmd_wcn_ap_config_commit(struct sigma_dut *dut,
4835 				    struct sigma_conn *conn,
4836 				    struct sigma_cmd *cmd)
4837 {
4838 	char buf[100];
4839 	struct stat s;
4840 	int num_tries = 0, ret;
4841 
4842 	if (kill_process(dut, "(netd)", 1, SIGKILL) == 0 ||
4843 	    system("killall netd") == 0) {
4844 		/* Avoid Error: Error connecting (Connection refused)
4845 		 * Wait some time to allow netd to reinitialize.
4846 		 */
4847 		usleep(1500000);
4848 	}
4849 
4850 	while (num_tries < 10) {
4851 		ret = run_ndc(dut, "ndc softap stopap");
4852 		num_tries++;
4853 		if (WIFEXITED(ret))
4854 			ret = WEXITSTATUS(ret);
4855 		/* On success, NDC exits with 0 */
4856 		if (ret == 0)
4857 			break;
4858 		sigma_dut_print(dut, DUT_MSG_INFO,
4859 				"Try No. %d: ndc softap stopap failed, exit code %d",
4860 				num_tries, ret);
4861 	}
4862 
4863 	if (ret != 0)
4864 		sigma_dut_print(dut, DUT_MSG_ERROR,
4865 				"ndc softap stopap command failed for 10 times - giving up");
4866 
4867 #ifdef ANDROID
4868 	/* Unload/Load driver to cleanup the state of the driver */
4869 	system("rmmod -f wlan");
4870 	usleep(500000);
4871 	system("insmod /system/lib/modules/wlan.ko");
4872 #else /* ANDROID */
4873 	run_ndc(dut, "ndc softap qccmd set enable_softap=0");
4874 	run_ndc(dut, "ndc softap qccmd set enable_softap=1");
4875 #endif /* ANDROID */
4876 
4877 	switch (dut->ap_mode) {
4878 	case AP_11g:
4879 		run_ndc(dut, "ndc softap qccmd set hw_mode=g-only");
4880 		break;
4881 	case AP_11b:
4882 		run_ndc(dut, "ndc softap qccmd set hw_mode=b-only");
4883 		break;
4884 	case AP_11ng:
4885 		run_ndc(dut, "ndc softap qccmd set hw_mode=n");
4886 		break;
4887 	case AP_11a:
4888 		run_ndc(dut, "ndc softap qccmd set hw_mode=a-only");
4889 		break;
4890 	case AP_11na:
4891 		run_ndc(dut, "ndc softap qccmd set hw_mode=n");
4892 		break;
4893 	case AP_11ac:
4894 		run_ndc(dut, "ndc softap qccmd set hw_mode=ac");
4895 		break;
4896 	default:
4897 		break;
4898 	}
4899 
4900 	snprintf(buf, sizeof(buf), "ndc softap qccmd set channel=%d",
4901 		 dut->ap_channel);
4902 	run_ndc(dut, buf);
4903 
4904 	/*
4905 	 * ndc doesn't support double quotes as SSID string, so re-write
4906 	 * hostapd configuration file to update SSID.
4907 	 */
4908 	if (dut->ap_ssid[0] != '\0')
4909 		sigma_write_cfg(dut, ANDROID_CONFIG_FILE, "ssid", dut->ap_ssid);
4910 
4911 	switch (dut->ap_key_mgmt) {
4912 	case AP_OPEN:
4913 		if (dut->ap_cipher == AP_WEP) {
4914 			run_ndc(dut, "ndc softap qccmd set security_mode=1");
4915 			snprintf(buf, sizeof(buf),
4916 				 "ndc softap qccmd set wep_key0=%s",
4917 				 dut->ap_wepkey);
4918 			run_ndc(dut, buf);
4919 		} else {
4920 			run_ndc(dut, "ndc softap qccmd set security_mode=0");
4921 		}
4922 		break;
4923 	case AP_WPA2_PSK:
4924 	case AP_WPA2_PSK_MIXED:
4925 	case AP_WPA_PSK:
4926 		if (dut->ap_key_mgmt == AP_WPA2_PSK)
4927 			run_ndc(dut, "ndc softap qccmd set security_mode=3");
4928 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
4929 			run_ndc(dut, "ndc softap qccmd set security_mode=4");
4930 		else
4931 			run_ndc(dut, "ndc softap qccmd set security_mode=2");
4932 
4933 		/*
4934 		 * ndc doesn't support some special characters as passphrase,
4935 		 * so re-write hostapd configuration file to update Passphrase.
4936 		 */
4937 		if (dut->ap_passphrase[0] != '\0')
4938 			sigma_write_cfg(dut, ANDROID_CONFIG_FILE,
4939 					"wpa_passphrase", dut->ap_passphrase);
4940 
4941 		if (dut->ap_cipher == AP_CCMP_TKIP)
4942 			run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4943 				"TKIP CCMP");
4944 		else if (dut->ap_cipher == AP_TKIP)
4945 			run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4946 				"TKIP");
4947 		else
4948 			run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4949 				"CCMP &");
4950 		break;
4951 	case AP_WPA2_SAE:
4952 	case AP_WPA2_PSK_SAE:
4953 	case AP_WPA2_EAP:
4954 	case AP_WPA2_EAP_MIXED:
4955 	case AP_WPA_EAP:
4956 	case AP_SUITEB:
4957 	case AP_WPA2_OWE:
4958 	case AP_WPA2_EAP_OSEN:
4959 	case AP_OSEN:
4960 	case AP_WPA2_FT_EAP:
4961 	case AP_WPA2_FT_PSK:
4962 	case AP_WPA2_EAP_SHA256:
4963 	case AP_WPA2_PSK_SHA256:
4964 	case AP_WPA2_ENT_FT_EAP:
4965 		/* Not supported */
4966 		break;
4967 	}
4968 
4969 	switch (dut->ap_pmf) {
4970 	case AP_PMF_DISABLED:
4971 		run_ndc(dut, "ndc softap qccmd set ieee80211w=0");
4972 		break;
4973 	case AP_PMF_OPTIONAL:
4974 		run_ndc(dut, "ndc softap qccmd set ieee80211w=1");
4975 		if (dut->ap_add_sha256)
4976 			run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256");
4977 		else
4978 			run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK");
4979 		break;
4980 	case AP_PMF_REQUIRED:
4981 		run_ndc(dut, "ndc softap qccmd set ieee80211w=2");
4982 		run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK-SHA256");
4983 		break;
4984 	}
4985 
4986 	if (dut->ap_countrycode[0]) {
4987 		snprintf(buf, sizeof(buf),
4988 			 "ndc softap qccmd set country_code=%s",
4989 			 dut->ap_countrycode);
4990 		run_ndc(dut, buf);
4991 	}
4992 
4993 	if (dut->ap_regulatory_mode == AP_80211D_MODE_ENABLED)
4994 		run_ndc(dut, "ndc softap qccmd set ieee80211d=1");
4995 
4996 	if (dut->ap_dfs_mode == AP_DFS_MODE_ENABLED)
4997 		run_ndc(dut, "ndc softap qccmd set ieee80211h=1");
4998 
4999 	run_ndc(dut, "ndc softap startap");
5000 
5001 	snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl,
5002 		 get_main_ifname(dut));
5003 	num_tries = 0;
5004 	while (num_tries < 10 && (ret = stat(buf, &s) != 0)) {
5005 		run_ndc(dut, "ndc softap stopap");
5006 		run_ndc(dut, "ndc softap startap");
5007 		num_tries++;
5008 	}
5009 
5010 	if (num_tries == 10) {
5011 		sigma_dut_print(dut, DUT_MSG_INFO, "Tried 10 times with ctrl "
5012 				"iface %s :: reboot the APDUT", buf);
5013 		return ret;
5014 	}
5015 
5016 	sigma_dut_print(dut, DUT_MSG_INFO, "setting ip addr %s mask %s",
5017 			ap_inet_addr, ap_inet_mask);
5018 	snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up",
5019 		 get_main_ifname(dut), ap_inet_addr, ap_inet_mask);
5020 	if (system(buf) != 0) {
5021 		sigma_dut_print(dut, DUT_MSG_ERROR,
5022 				"Failed to intialize the interface");
5023 		return -1;
5024 	}
5025 
5026 	return 1;
5027 }
5028 
5029 
append_hostapd_conf_hs2(struct sigma_dut * dut,FILE * f)5030 static int append_hostapd_conf_hs2(struct sigma_dut *dut, FILE *f)
5031 {
5032 	fprintf(f, "hs20=1\nhs20_deauth_req_timeout=3\n"
5033 		"disable_dgaf=%d\n", dut->ap_dgaf_disable);
5034 
5035 	if (dut->ap_oper_name) {
5036 		fprintf(f, "hs20_oper_friendly_name=eng:Wi-Fi Alliance\n");
5037 		fprintf(f, "hs20_oper_friendly_name=chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f\n");
5038 	}
5039 
5040 	if (dut->ap_wan_metrics == 1)
5041 		fprintf(f, "hs20_wan_metrics=01:2500:384:0:0:10\n");
5042 	else if (dut->ap_wan_metrics == 2)
5043 		fprintf(f, "hs20_wan_metrics=01:1500:384:20:20:10\n");
5044 	else if (dut->ap_wan_metrics == 3)
5045 		fprintf(f, "hs20_wan_metrics=01:2000:1000:20:20:10\n");
5046 	else if (dut->ap_wan_metrics == 4)
5047 		fprintf(f, "hs20_wan_metrics=01:8000:1000:20:20:10\n");
5048 	else if (dut->ap_wan_metrics == 5)
5049 		fprintf(f, "hs20_wan_metrics=01:9000:5000:20:20:10\n");
5050 
5051 	if (dut->ap_conn_capab == 1) {
5052 		fprintf(f, "hs20_conn_capab=1:0:0\n");
5053 		fprintf(f, "hs20_conn_capab=6:20:1\n");
5054 		fprintf(f, "hs20_conn_capab=6:22:0\n");
5055 		fprintf(f, "hs20_conn_capab=6:80:1\n");
5056 		fprintf(f, "hs20_conn_capab=6:443:1\n");
5057 		fprintf(f, "hs20_conn_capab=6:1723:0\n");
5058 		fprintf(f, "hs20_conn_capab=6:5060:0\n");
5059 		fprintf(f, "hs20_conn_capab=17:500:1\n");
5060 		fprintf(f, "hs20_conn_capab=17:5060:0\n");
5061 		fprintf(f, "hs20_conn_capab=17:4500:1\n");
5062 		fprintf(f, "hs20_conn_capab=50:0:1\n");
5063 	} else if (dut->ap_conn_capab == 2) {
5064 		fprintf(f, "hs20_conn_capab=6:80:1\n");
5065 		fprintf(f, "hs20_conn_capab=6:443:1\n");
5066 		fprintf(f, "hs20_conn_capab=17:5060:1\n");
5067 		fprintf(f, "hs20_conn_capab=6:5060:1\n");
5068 	} else if (dut->ap_conn_capab == 3) {
5069 		fprintf(f, "hs20_conn_capab=6:80:1\n");
5070 		fprintf(f, "hs20_conn_capab=6:443:1\n");
5071 	} else if (dut->ap_conn_capab == 4) {
5072 		fprintf(f, "hs20_conn_capab=6:80:1\n");
5073 		fprintf(f, "hs20_conn_capab=6:443:1\n");
5074 		fprintf(f, "hs20_conn_capab=6:5060:1\n");
5075 		fprintf(f, "hs20_conn_capab=17:5060:1\n");
5076 	}
5077 
5078 	if (dut->ap_oper_class == 1)
5079 		fprintf(f, "hs20_operating_class=51\n");
5080 	else if (dut->ap_oper_class == 2)
5081 		fprintf(f, "hs20_operating_class=73\n");
5082 	else if (dut->ap_oper_class == 3)
5083 		fprintf(f, "hs20_operating_class=5173\n");
5084 
5085 	if (dut->ap_osu_provider_list) {
5086 		char *osu_friendly_name = NULL;
5087 		char *osu_icon = NULL;
5088 		char *osu_ssid = NULL;
5089 		char *osu_nai = NULL;
5090 		char *osu_nai2 = NULL;
5091 		char *osu_service_desc = NULL;
5092 		char *hs20_icon_filename = NULL;
5093 		char hs20_icon[150];
5094 		int osu_method;
5095 
5096 		hs20_icon_filename = "icon_red_zxx.png";
5097 		if (dut->ap_osu_icon_tag == 2)
5098 			hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5099 		snprintf(hs20_icon, sizeof(hs20_icon),
5100 			 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s",
5101 			 hs20_icon_filename);
5102 		osu_icon = "icon_red_zxx.png";
5103 		osu_ssid = "OSU";
5104 		osu_friendly_name = "kor:SP 빨강 테스트 전용";
5105 		osu_service_desc = "kor:테스트 목적으로 무료 서비스";
5106 		osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0];
5107 
5108 		if (strlen(dut->ap_osu_server_uri[0]))
5109 			fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[0]);
5110 		else
5111 			fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
5112 
5113 		switch (dut->ap_osu_provider_list) {
5114 		case 1:
5115 		case 101:
5116 			fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
5117 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5118 			hs20_icon_filename = "icon_red_eng.png";
5119 			if (dut->ap_osu_icon_tag == 2)
5120 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5121 			fprintf(f, "hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s\n",
5122 				hs20_icon_filename);
5123 			fprintf(f, "osu_icon=icon_red_eng.png\n");
5124 			break;
5125 		case 2:
5126 		case 102:
5127 			fprintf(f, "osu_friendly_name=eng:Wireless Broadband Alliance\n");
5128 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5129 			hs20_icon_filename = "icon_orange_zxx.png";
5130 			if (dut->ap_osu_icon_tag == 2)
5131 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5132 			snprintf(hs20_icon, sizeof(hs20_icon),
5133 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5134 				 hs20_icon_filename);
5135 			osu_icon = "icon_orange_zxx.png";
5136 			osu_friendly_name = "kor:와이어리스 브로드밴드 얼라이언스";
5137 			break;
5138 		case 3:
5139 		case 103:
5140 			osu_friendly_name = "spa:SP Red Test Only";
5141 			osu_service_desc = "spa:Free service for test purpose";
5142 			break;
5143 		case 4:
5144 		case 104:
5145 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5146 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5147 			hs20_icon_filename = "icon_orange_eng.png";
5148 			if (dut->ap_osu_icon_tag == 2)
5149 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5150 			fprintf(f, "hs20_icon=160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s\n",
5151 				hs20_icon_filename);
5152 			fprintf(f, "osu_icon=icon_orange_eng.png\n");
5153 			osu_friendly_name = "kor:SP 오렌지 테스트 전용";
5154 
5155 			hs20_icon_filename = "icon_orange_zxx.png";
5156 			if (dut->ap_osu_icon_tag == 2)
5157 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5158 			snprintf(hs20_icon, sizeof(hs20_icon),
5159 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5160 				 hs20_icon_filename);
5161 			osu_icon = "icon_orange_zxx.png";
5162 			break;
5163 		case 5:
5164 		case 105:
5165 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5166 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5167 			osu_friendly_name = "kor:SP 오렌지 테스트 전용";
5168 			hs20_icon_filename = "icon_orange_zxx.png";
5169 			if (dut->ap_osu_icon_tag == 2)
5170 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5171 			snprintf(hs20_icon, sizeof(hs20_icon),
5172 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5173 				 hs20_icon_filename);
5174 			osu_icon = "icon_orange_zxx.png";
5175 			break;
5176 		case 6:
5177 		case 106:
5178 			fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n");
5179 			fprintf(f, "osu_friendly_name=kor:SP 초록 테스트 전용\n");
5180 			hs20_icon_filename = "icon_green_zxx.png";
5181 			if (dut->ap_osu_icon_tag == 2)
5182 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5183 			fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s\n",
5184 				hs20_icon_filename);
5185 			fprintf(f, "osu_icon=icon_green_zxx.png\n");
5186 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 : dut->ap_osu_method[0];
5187 			fprintf(f, "osu_method_list=%d\n", osu_method);
5188 
5189 			if (strlen(dut->ap_osu_server_uri[1]))
5190 				fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]);
5191 			else
5192 				fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
5193 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5194 			hs20_icon_filename = "icon_orange_zxx.png";
5195 			if (dut->ap_osu_icon_tag == 2)
5196 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5197 			snprintf(hs20_icon, sizeof(hs20_icon),
5198 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5199 				 hs20_icon_filename);
5200 			osu_icon = "icon_orange_zxx.png";
5201 			osu_friendly_name = "kor:SP 오렌지 테스트 전용";
5202 			osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 : dut->ap_osu_method[1];
5203 			osu_service_desc = NULL;
5204 			break;
5205 		case 7:
5206 		case 107:
5207 			fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n");
5208 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5209 			hs20_icon_filename = "icon_green_eng.png";
5210 			if (dut->ap_osu_icon_tag == 2)
5211 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5212 			fprintf(f, "hs20_icon=160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s\n",
5213 				hs20_icon_filename);
5214 			fprintf(f, "osu_icon=icon_green_eng.png\n");
5215 			osu_friendly_name = "kor:SP 초록 테스트 전용";
5216 
5217 			hs20_icon_filename = "icon_green_zxx.png";
5218 			if (dut->ap_osu_icon_tag == 2)
5219 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5220 			snprintf(hs20_icon, sizeof(hs20_icon),
5221 				 "128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s",
5222 				 hs20_icon_filename);
5223 			osu_icon = "icon_green_zxx.png";
5224 			break;
5225 		case 8:
5226 		case 108:
5227 			fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
5228 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5229 			osu_ssid = "OSU-Encrypted";
5230 			osu_nai = "anonymous@hotspot.net";
5231 			break;
5232 		case 9:
5233 		case 109:
5234 			osu_ssid = "OSU-OSEN";
5235 			osu_nai = "test-anonymous@wi-fi.org";
5236 			osu_friendly_name = "eng:SP Orange Test Only";
5237 			hs20_icon_filename = "icon_orange_zxx.png";
5238 			if (dut->ap_osu_icon_tag == 2)
5239 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5240 			snprintf(hs20_icon, sizeof(hs20_icon),
5241 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5242 				 hs20_icon_filename);
5243 			osu_icon = "icon_orange_zxx.png";
5244 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0];
5245 			osu_service_desc = NULL;
5246 			break;
5247 		case 10:
5248 		case 110:
5249 			/* OSU Provider #1 */
5250 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5251 			fprintf(f, "osu_friendly_name=kor:SP 오렌지 테스트 전용\n");
5252 			fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/icon_orange_zxx.png\n");
5253 			fprintf(f, "osu_icon=icon_orange_zxx.png\n");
5254 			osu_method = (dut->ap_osu_method[0] == 0xFF) ?
5255 				1 : dut->ap_osu_method[0];
5256 			fprintf(f, "osu_method_list=%d\n", osu_method);
5257 			fprintf(f, "osu_nai=test-anonymous@wi-fi.org\n");
5258 			switch (dut->ap_osu_provider_nai_list) {
5259 			case 3:
5260 				fprintf(f,
5261 					"osu_nai2=test-anonymous@wi-fi.org\n");
5262 				break;
5263 			case 4:
5264 				fprintf(f, "osu_nai2=random@hotspot.net\n");
5265 				break;
5266 			}
5267 
5268 			/* OSU Provider #2 */
5269 			/* SP Red from defaults */
5270 			if (strlen(dut->ap_osu_server_uri[1]))
5271 				fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]);
5272 			else
5273 				fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
5274 			fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
5275 			snprintf(hs20_icon, sizeof(hs20_icon),
5276 				 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/icon_red_zxx.png");
5277 			osu_method = (dut->ap_osu_method[1] == 0xFF) ?
5278 				1 : dut->ap_osu_method[1];
5279 			osu_service_desc = NULL;
5280 			osu_nai = "anonymous@hotspot.net";
5281 			break;
5282 		default:
5283 			break;
5284 		}
5285 
5286 		switch (dut->ap_osu_provider_nai_list) {
5287 		case 1:
5288 			osu_nai2 = "anonymous@hotspot.net";
5289 			break;
5290 		case 2:
5291 			osu_nai2 = "test-anonymous@wi-fi.org";
5292 			break;
5293 		case 3:
5294 			/* OSU Provider NAI #1 written above */
5295 			/* OSU Provider NAI #2 */
5296 			osu_nai2 = "anonymous@hotspot.net";
5297 			break;
5298 		case 4:
5299 			/* OSU Provider NAI #1 written above */
5300 			/* OSU Provider NAI #2 */
5301 			osu_nai2 = "anonymous@hotspot.net";
5302 			break;
5303 		}
5304 
5305 		if (strlen(dut->ap_osu_ssid)) {
5306 			if (dut->ap_tag_ssid[0][0] &&
5307 			    strcmp(dut->ap_tag_ssid[0], dut->ap_osu_ssid) &&
5308 			    strcmp(dut->ap_tag_ssid[0], osu_ssid)) {
5309 				sigma_dut_print(dut, DUT_MSG_ERROR,
5310 						"OSU_SSID and "
5311 						"WLAN_TAG2 SSID differ");
5312 				return -2;
5313 			}
5314 			fprintf(f, "osu_ssid=\"%s\"\n", dut->ap_osu_ssid);
5315 		} else
5316 			fprintf(f, "osu_ssid=\"%s\"\n", osu_ssid);
5317 
5318 
5319 		if (osu_friendly_name)
5320 			fprintf(f, "osu_friendly_name=%s\n", osu_friendly_name);
5321 
5322 		if (osu_service_desc)
5323 			fprintf(f, "osu_service_desc=%s\n", osu_service_desc);
5324 
5325 		if (osu_nai)
5326 			fprintf(f, "osu_nai=%s\n", osu_nai);
5327 		if (osu_nai2)
5328 			fprintf(f, "osu_nai2=%s\n", osu_nai2);
5329 
5330 		fprintf(f, "hs20_icon=%s\n", hs20_icon);
5331 
5332 		if (osu_icon)
5333 			fprintf(f, "osu_icon=%s\n", osu_icon);
5334 
5335 		if (dut->ap_osu_provider_list > 100)
5336 			fprintf(f, "osu_method_list=0\n");
5337 		else
5338 			fprintf(f, "osu_method_list=%d\n", osu_method);
5339 	}
5340 
5341 	switch (dut->ap_venue_url) {
5342 	case 1:
5343 		fprintf(f,
5344 			"venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5345 			"venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/directory/index.html\n");
5346 		break;
5347 	case 2:
5348 		fprintf(f,
5349 			"venue_url=1:https://the-great-mall.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5350 			"venue_url=2:https://abercrombie.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5351 			"venue_url=3:https://adidas.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5352 			"venue_url=4:https://aeropostale.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5353 			"venue_url=5:https://agaci.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5354 			"venue_url=6:https://aldo-shoes.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5355 			"venue_url=7:https://american-eagle-outfitters.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5356 			"venue_url=8:https://anderson-bakery.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5357 			"venue_url=9:https://banana-republic-factory-store.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5358 			"venue_url=10:https://bed-bath-and-beyond.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5359 			);
5360 		break;
5361 	}
5362 
5363 	switch (dut->ap_advice_of_charge) {
5364 	case 1:
5365 		fprintf(f, "anqp_elem=278:" ADV_OF_CHARGE_1 "\n");
5366 		break;
5367 	}
5368 
5369 	switch (dut->ap_oper_icon_metadata) {
5370 	case 1:
5371 		fprintf(f,
5372 			"hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/icon_red_eng.png\n"
5373 			"operator_icon=icon_red_eng.png\n");
5374 		break;
5375 	}
5376 
5377 	switch (dut->ap_tnc_file_name) {
5378 	case 1:
5379 		fprintf(f, "hs20_t_c_filename=tandc-id1-content.txt\n");
5380 		break;
5381 	}
5382 
5383 	if (dut->ap_tnc_time_stamp)
5384 		fprintf(f, "hs20_t_c_timestamp=%u\n", dut->ap_tnc_time_stamp);
5385 
5386 	return 0;
5387 }
5388 
5389 
write_ap_roaming_cons(FILE * f,const char * list)5390 static void write_ap_roaming_cons(FILE *f, const char *list)
5391 {
5392 	char *buf, *pos, *end;
5393 
5394 	if (list == NULL || list[0] == '\0')
5395 		return;
5396 
5397 	buf = strdup(list);
5398 	if (buf == NULL)
5399 		return;
5400 
5401 	pos = buf;
5402 	while (pos && *pos) {
5403 		end = strchr(pos, ';');
5404 		if (end)
5405 			*end++ = '\0';
5406 		fprintf(f, "roaming_consortium=%s\n", pos);
5407 		pos = end;
5408 	}
5409 
5410 	free(buf);
5411 }
5412 
5413 
append_hostapd_conf_interworking(struct sigma_dut * dut,FILE * f)5414 static int append_hostapd_conf_interworking(struct sigma_dut *dut, FILE *f)
5415 {
5416 	int i;
5417 	char buf[100], *temp;
5418 
5419 	if (dut->ap_gas_cb_delay > 0)
5420 		fprintf(f, "gas_comeback_delay=%d\n",
5421 			dut->ap_gas_cb_delay);
5422 
5423 	fprintf(f, "interworking=1\n"
5424 		"access_network_type=%d\n"
5425 		"internet=%d\n"
5426 		"asra=0\n"
5427 		"esr=0\n"
5428 		"uesa=0\n"
5429 		"venue_group=%d\n"
5430 		"venue_type=%d\n",
5431 		dut->ap_access_net_type,
5432 		dut->ap_internet,
5433 		dut->ap_venue_group,
5434 		dut->ap_venue_type);
5435 	if (dut->ap_hessid[0])
5436 		fprintf(f, "hessid=%s\n", dut->ap_hessid);
5437 
5438 	write_ap_roaming_cons(f, dut->ap_roaming_cons);
5439 
5440 	if (dut->ap_venue_name) {
5441 		fprintf(f, "venue_name=P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"\n");
5442 		fprintf(f, "venue_name=%s\n", ANQP_VENUE_NAME_1_CHI);
5443 	}
5444 
5445 	if (dut->ap_net_auth_type == 1)
5446 		fprintf(f, "network_auth_type=00https://tandc-server.wi-fi.org\n");
5447 	else if (dut->ap_net_auth_type == 2)
5448 		fprintf(f, "network_auth_type=01\n");
5449 
5450 	if (dut->ap_nai_realm_list == 1) {
5451 		fprintf(f, "nai_realm=0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]\n");
5452 		fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n");
5453 	} else if (dut->ap_nai_realm_list == 2) {
5454 		fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n");
5455 	} else if (dut->ap_nai_realm_list == 3) {
5456 		fprintf(f, "nai_realm=0,cisco.com;wi-fi.org,21[2:4][5:7]\n");
5457 		fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n");
5458 	} else if (dut->ap_nai_realm_list == 4) {
5459 		fprintf(f, "nai_realm=0,mail.example.com,21[2:4][5:7],13[5:6]\n");
5460 	} else if (dut->ap_nai_realm_list == 5) {
5461 		fprintf(f, "nai_realm=0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]\n");
5462 	} else if (dut->ap_nai_realm_list == 6) {
5463 		fprintf(f, "nai_realm=0,wi-fi.org;mail.example.com,21[2:4][5:7]\n");
5464 	} else if (dut->ap_nai_realm_list == 7) {
5465 		fprintf(f, "nai_realm=0,wi-fi.org,13[5:6]\n");
5466 		fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n");
5467 	}
5468 
5469 	if (dut->ap_domain_name_list[0]) {
5470 		fprintf(f, "domain_name=%s\n",
5471 			dut->ap_domain_name_list);
5472 	}
5473 
5474 	if (dut->ap_ip_addr_type_avail == 1) {
5475 		fprintf(f, "ipaddr_type_availability=0c\n");
5476 	}
5477 
5478 	temp = buf;
5479 	for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0];
5480 	     i++) {
5481 		if (i)
5482 			*temp++ = ';';
5483 
5484 		snprintf(temp,
5485 			 sizeof(dut->ap_plmn_mcc[i]) +
5486 			 sizeof(dut->ap_plmn_mnc[i]) + 1,
5487 			 "%s,%s",
5488 			 dut->ap_plmn_mcc[i],
5489 			 dut->ap_plmn_mnc[i]);
5490 
5491 		temp += strlen(dut->ap_plmn_mcc[i]) +
5492 			strlen(dut->ap_plmn_mnc[i]) + 1;
5493 	}
5494 	if (i)
5495 		fprintf(f, "anqp_3gpp_cell_net=%s\n", buf);
5496 
5497 	if (dut->ap_qos_map_set == 1)
5498 		fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_1);
5499 	else if (dut->ap_qos_map_set == 2)
5500 		fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_2);
5501 
5502 	return 0;
5503 }
5504 
5505 
ath_ap_append_hostapd_conf(struct sigma_dut * dut)5506 static int ath_ap_append_hostapd_conf(struct sigma_dut *dut)
5507 {
5508 	FILE *f;
5509 
5510 	if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
5511 	    system("killall hostapd") == 0) {
5512 		int i;
5513 
5514 		/* Wait some time to allow hostapd to complete cleanup before
5515 		 * starting a new process */
5516 		for (i = 0; i < 10; i++) {
5517 			usleep(500000);
5518 			if (system("pidof hostapd") != 0)
5519 				break;
5520 		}
5521 	}
5522 
5523 	f = fopen("/tmp/secath0", "a");
5524 	if (f == NULL)
5525 		return -2;
5526 
5527 	if (dut->ap_hs2 && append_hostapd_conf_hs2(dut, f)) {
5528 		fclose(f);
5529 		return -2;
5530 	}
5531 
5532 	if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) {
5533 		fclose(f);
5534 		return -2;
5535 	}
5536 
5537 	fflush(f);
5538 	fclose(f);
5539 	return ath_ap_start_hostapd(dut);
5540 }
5541 
5542 
ath_ap_start_hostapd(struct sigma_dut * dut)5543 static int ath_ap_start_hostapd(struct sigma_dut *dut)
5544 {
5545 	if (dut->ap_tag_key_mgmt[0] == AP2_OSEN)
5546 		run_system(dut, "hostapd -B /tmp/secath0 /tmp/secath1 -e /etc/wpa2/entropy");
5547 	else
5548 		run_system(dut, "hostapd -B /tmp/secath0 -e /etc/wpa2/entropy");
5549 
5550 	return 0;
5551 }
5552 
5553 
5554 #define LE16(a) ((((a) & 0xff) << 8) | (((a) >> 8) & 0xff))
5555 
cmd_ath_ap_anqpserver_start(struct sigma_dut * dut)5556 static int cmd_ath_ap_anqpserver_start(struct sigma_dut *dut)
5557 {
5558 	FILE *f;
5559 	int nai_realm = 0, domain_name = 0, oper_name = 0, venue_name = 0,
5560 		wan_metrics = 0, conn_cap = 0, ipaddr_avail = 0, cell_net = 0;
5561 	char buf[100];
5562 	int i;
5563 
5564 	f = fopen("/root/anqpserver.conf", "w");
5565 	if (f == NULL)
5566 		return -1;
5567 
5568 	if (dut->ap_nai_realm_list == 1) {
5569 		nai_realm = 1;
5570 		fprintf(f, "dyn_nai_home_realm=encoding=00realm=mail.example.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=cisco.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=wi-fi.org;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=example.com;eap_method=0Dauth_id=05auth_val=06encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
5571 	} else if (dut->ap_nai_realm_list == 2) {
5572 		nai_realm = 1;
5573 		fprintf(f, "dyn_nai_home_realm=encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
5574 	} else if (dut->ap_nai_realm_list == 3) {
5575 		nai_realm = 1;
5576 		fprintf(f, "dyn_nai_home_realm=encoding=00realm=cisco.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=wi-fi.org;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=example.com;eap_method=0Dauth_id=05auth_val=06encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
5577 	} else if (dut->ap_nai_realm_list == 4) {
5578 		nai_realm = 1;
5579 		fprintf(f, "dyn_nai_home_realm=encoding=00realm=mail.example.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=mail.example.com;eap_method=0Dauth_id=05auth_val=06\n");
5580 	} else
5581 		sigma_dut_print(dut, DUT_MSG_INFO, "not setting nai_realm");
5582 
5583 	if (dut->ap_domain_name_list[0]) {
5584 		char *next, *start, *dnbuf, *dn1, *anqp_dn;
5585 		int len, dn_len_max;
5586 		dnbuf = strdup(dut->ap_domain_name_list);
5587 		if (dnbuf == NULL) {
5588 			fclose(f);
5589 			return 0;
5590 		}
5591 
5592 		len = strlen(dnbuf);
5593 		dn_len_max = 50 + len*2;
5594 		anqp_dn = malloc(dn_len_max);
5595 		if (anqp_dn == NULL) {
5596 			free(dnbuf);
5597 			fclose(f);
5598 			return -1;
5599 		}
5600 		start = dnbuf;
5601 		dn1 = anqp_dn;
5602 		while (start && *start) {
5603 			char *hexstr;
5604 
5605 			next = strchr(start, ',');
5606 			if (next)
5607 				*next++ = '\0';
5608 
5609 			len = strlen(start);
5610 			hexstr = malloc(len * 2 + 1);
5611 			if (hexstr == NULL) {
5612 				free(dnbuf);
5613 				free(anqp_dn);
5614 				fclose(f);
5615 				return -1;
5616 			}
5617 			ascii2hexstr(start, hexstr);
5618 			snprintf(dn1, dn_len_max, "%02x%s", len, hexstr);
5619 			free(hexstr);
5620 			dn1 += 2 + len * 2;
5621 			dn_len_max -= 2 + len * 2;
5622 			start = next;
5623 		}
5624 		free(dnbuf);
5625 		if (dut->ap_gas_cb_delay) {
5626 			fprintf(f, "dyn_domain_name=0c01%04x%s",
5627 				LE16((unsigned int) strlen(anqp_dn)), anqp_dn);
5628 			domain_name = 1;
5629 		} else
5630 			fprintf(f, "domain_name=0c01%04x%s",
5631 				LE16((unsigned int) strlen(anqp_dn)), anqp_dn);
5632 		free(anqp_dn);
5633 	} else
5634 		sigma_dut_print(dut, DUT_MSG_INFO, "not setting domain_name");
5635 
5636 	sigma_dut_print(dut, DUT_MSG_INFO, "not setting roaming_consortium");
5637 
5638 	if (dut->ap_oper_name) {
5639 		if (dut->ap_gas_cb_delay) {
5640 			fprintf(f, "dyn_oper_friendly_name="
5641 				ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n");
5642 			oper_name = 1;
5643 		} else
5644 			fprintf(f, "oper_friendly_name="
5645 				ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n");
5646 	} else
5647 		sigma_dut_print(dut, DUT_MSG_INFO, "not setting oper_name");
5648 
5649 	if (dut->ap_venue_name) {
5650 		if (dut->ap_gas_cb_delay) {
5651 			fprintf(f, "dyn_venue_name=" ANQP_VENUE_NAME_1 "\n");
5652 			venue_name = 1;
5653 		} else
5654 			fprintf(f, "venue_name=" ANQP_VENUE_NAME_1 "\n");
5655 	} else
5656 		sigma_dut_print(dut, DUT_MSG_ERROR, "not setting venue_name");
5657 
5658 	if (dut->ap_wan_metrics) {
5659 		if (dut->ap_gas_cb_delay) {
5660 			fprintf(f, "dyn_wan_metrics=" ANQP_HS20_WAN_METRICS_1 "\n");
5661 			wan_metrics = 1;
5662 		} else
5663 			fprintf(f, "wan_metrics=" ANQP_HS20_WAN_METRICS_1
5664 				"\n");
5665 	} else
5666 		sigma_dut_print(dut, DUT_MSG_ERROR, "not setting wan_metrics");
5667 
5668 	if (dut->ap_conn_capab) {
5669 		if (dut->ap_gas_cb_delay) {
5670 			fprintf(f, "dyn_conn_capability="
5671 				ANQP_HS20_CONNECTION_CAPABILITY_1 "\n");
5672 			conn_cap = 1;
5673 		} else
5674 			fprintf(f, "conn_capability="
5675 				ANQP_HS20_CONNECTION_CAPABILITY_1 "\n");
5676 	} else
5677 		sigma_dut_print(dut, DUT_MSG_ERROR,
5678 				"not setting conn_capability");
5679 
5680 	if (dut->ap_ip_addr_type_avail) {
5681 		if (dut->ap_gas_cb_delay) {
5682 			fprintf(f, "dyn_ipaddr_type=" ANQP_IP_ADDR_TYPE_1
5683 				"\n");
5684 			ipaddr_avail = 1;
5685 		} else
5686 			fprintf(f, "ipaddr_type=" ANQP_IP_ADDR_TYPE_1 "\n");
5687 	} else
5688 		sigma_dut_print(dut, DUT_MSG_ERROR,
5689 				"not setting ipaddr_type_avail");
5690 
5691 	for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) {
5692 		snprintf(buf + i * 6, sizeof(buf) - i * 6, "%c%c%c%c%c%c",
5693 			 dut->ap_plmn_mcc[i][1],
5694 			 dut->ap_plmn_mcc[i][0],
5695 			 dut->ap_plmn_mnc[i][2] == '\0' ?
5696 			 'f' : dut->ap_plmn_mnc[i][2],
5697 			 dut->ap_plmn_mcc[i][2],
5698 			 dut->ap_plmn_mnc[i][1],
5699 			 dut->ap_plmn_mnc[i][0]);
5700 	}
5701 	if (i) {
5702 		uint16_t ie_len = (i * 3) + 5;
5703 		if (dut->ap_gas_cb_delay) {
5704 			fprintf(f, "dyn_cell_net=0801");
5705 			cell_net = 1;
5706 		} else
5707 			fprintf(f, "cell_net=0801");
5708 		fprintf(f, "%04x", LE16(ie_len));
5709 		fprintf(f, "00");                /* version */
5710 		fprintf(f, "%02x", (i * 3) + 3); /* user data hdr length */
5711 		fprintf(f, "00");                /* plmn list */
5712 		fprintf(f, "%02x", (i * 3) + 1); /* length of plmn list */
5713 		fprintf(f, "%02x", i);           /* number of plmns */
5714 		fprintf(f, "%s\n", buf);           /* plmns */
5715 	} else
5716 		sigma_dut_print(dut, DUT_MSG_ERROR,
5717 				"not setting 3gpp_cellular_network");
5718 
5719 	if (nai_realm || domain_name || oper_name || venue_name ||
5720 		wan_metrics || conn_cap || ipaddr_avail || cell_net) {
5721 		fprintf(f, "anqp_attach=");
5722 		if (venue_name)
5723 			fprintf(f, "00000104%4.4x", dut->ap_gas_cb_delay);
5724 		if (nai_realm)
5725 			fprintf(f, "00000107%4.4x", dut->ap_gas_cb_delay);
5726 		if (cell_net)
5727 			fprintf(f, "00000108%4.4x", dut->ap_gas_cb_delay);
5728 		if (domain_name)
5729 			fprintf(f, "0000010c%4.4x", dut->ap_gas_cb_delay);
5730 		if (oper_name)
5731 			fprintf(f, "00010003%4.4x", dut->ap_gas_cb_delay);
5732 		if (wan_metrics)
5733 			fprintf(f, "00010004%4.4x", dut->ap_gas_cb_delay);
5734 		if (conn_cap)
5735 			fprintf(f, "00010005%4.4x", dut->ap_gas_cb_delay);
5736 		fprintf(f, "00010006%4.4x", dut->ap_gas_cb_delay);
5737 		fprintf(f, "\n");
5738 	}
5739 
5740 	fclose(f);
5741 
5742 	run_system(dut, "anqpserver -i ath0 &");
5743 	if (!dut->ap_anqpserver_on)
5744 		run_system(dut, "killall anqpserver");
5745 
5746 	return 1;
5747 }
5748 
5749 
cmd_ath_ap_radio_config(struct sigma_dut * dut)5750 static void cmd_ath_ap_radio_config(struct sigma_dut *dut)
5751 {
5752 	char buf[100];
5753 
5754 	run_system(dut, "cfg -a AP_STARTMODE=standard");
5755 
5756 	if (sigma_radio_ifname[0] &&
5757 	    strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
5758 		run_system(dut, "cfg -a AP_RADIO_ID=1");
5759 		switch (dut->ap_mode) {
5760 		case AP_11g:
5761 			run_system(dut, "cfg -a AP_CHMODE_2=11G");
5762 			break;
5763 		case AP_11b:
5764 			run_system(dut, "cfg -a AP_CHMODE_2=11B");
5765 			break;
5766 		case AP_11ng:
5767 			run_system(dut, "cfg -a AP_CHMODE_2=11NGHT20");
5768 			break;
5769 		case AP_11a:
5770 			run_system(dut, "cfg -a AP_CHMODE_2=11A");
5771 			break;
5772 		case AP_11na:
5773 			run_system(dut, "cfg -a AP_CHMODE_2=11NAHT20");
5774 			break;
5775 		case AP_11ac:
5776 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5777 			break;
5778 		default:
5779 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5780 			break;
5781 		}
5782 
5783 		switch (dut->ap_rx_streams) {
5784 		case 1:
5785 			run_system(dut, "cfg -a RX_CHAINMASK_2=1");
5786 			break;
5787 		case 2:
5788 			run_system(dut, "cfg -a RX_CHAINMASK_2=3");
5789 			break;
5790 		case 3:
5791 			run_system(dut, "cfg -a RX_CHAINMASK_2=7");
5792 			break;
5793 		}
5794 
5795 		switch (dut->ap_tx_streams) {
5796 		case 1:
5797 			run_system(dut, "cfg -a TX_CHAINMASK_2=1");
5798 			break;
5799 		case 2:
5800 			run_system(dut, "cfg -a TX_CHAINMASK_2=3");
5801 			break;
5802 		case 3:
5803 			run_system(dut, "cfg -a TX_CHAINMASK_2=7");
5804 			break;
5805 		}
5806 
5807 		switch (dut->ap_chwidth) {
5808 		case AP_20:
5809 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT20");
5810 			break;
5811 		case AP_40:
5812 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT40");
5813 			break;
5814 		case AP_80:
5815 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5816 			break;
5817 		case AP_160:
5818 		case AP_AUTO:
5819 		default:
5820 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5821 			break;
5822 		}
5823 
5824 		if (dut->ap_tx_stbc) {
5825 			run_system(dut, "cfg -a TX_STBC_2=1");
5826 		}
5827 
5828 		snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH_2=%d",
5829 			 dut->ap_channel);
5830 
5831 		if (dut->ap_is_dual) {
5832 			switch (dut->ap_mode_1) {
5833 			case AP_11g:
5834 				run_system(dut, "cfg -a AP_CHMODE=11G");
5835 				break;
5836 			case AP_11b:
5837 				run_system(dut, "cfg -a AP_CHMODE=11B");
5838 				break;
5839 			case AP_11ng:
5840 				run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5841 				break;
5842 			case AP_11a:
5843 				run_system(dut, "cfg -a AP_CHMODE=11A");
5844 				break;
5845 			case AP_11na:
5846 				run_system(dut, "cfg -a AP_CHMODE=11NAHT20");
5847 				break;
5848 			case AP_11ac:
5849 				run_system(dut, "cfg -a AP_CHMODE=11ACVHT80");
5850 				break;
5851 			default:
5852 				run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5853 				break;
5854 			}
5855 			snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d",
5856 				 dut->ap_channel_1);
5857 		}
5858 		run_system(dut, buf);
5859 	} else {
5860 		run_system(dut, "cfg -a AP_RADIO_ID=0");
5861 		switch (dut->ap_mode) {
5862 		case AP_11g:
5863 			run_system(dut, "cfg -a AP_CHMODE=11G");
5864 			break;
5865 		case AP_11b:
5866 			run_system(dut, "cfg -a AP_CHMODE=11B");
5867 			break;
5868 		case AP_11ng:
5869 			run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5870 			break;
5871 		case AP_11a:
5872 			run_system(dut, "cfg -a AP_CHMODE=11A");
5873 			break;
5874 		case AP_11na:
5875 			run_system(dut, "cfg -a AP_CHMODE=11NAHT20");
5876 			break;
5877 		case AP_11ac:
5878 			run_system(dut, "cfg -a AP_CHMODE=11ACVHT80");
5879 			break;
5880 		default:
5881 			run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5882 			break;
5883 		}
5884 		snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d",
5885 			 dut->ap_channel);
5886 		run_system(dut, buf);
5887 	}
5888 
5889 	if (dut->ap_sgi80 == 1) {
5890 		run_system(dut, "cfg -a SHORTGI=1");
5891 		run_system(dut, "cfg -a SHORTGI_2=1");
5892 	} else if (dut->ap_sgi80 == 0) {
5893 		run_system(dut, "cfg -a SHORTGI=0");
5894 		run_system(dut, "cfg -a SHORTGI_2=0");
5895 	}
5896 
5897 	if (dut->ap_ldpc == VALUE_ENABLED)
5898 		run_system(dut, "cfg -a LDPC=1");
5899 	else if (dut->ap_ldpc == VALUE_DISABLED)
5900 		run_system(dut, "cfg -a LDPC=0");
5901 }
5902 
5903 
ath_disable_txbf(struct sigma_dut * dut,const char * intf)5904 void ath_disable_txbf(struct sigma_dut *dut, const char *intf)
5905 {
5906 	run_iwpriv(dut, intf, "vhtsubfee 0");
5907 	run_iwpriv(dut, intf, "vhtsubfer 0");
5908 	run_iwpriv(dut, intf, "vhtmubfee 0");
5909 	run_iwpriv(dut, intf, "vhtmubfer 0");
5910 }
5911 
5912 
ath_set_assoc_disallow(struct sigma_dut * dut,const char * ifname,const char * val)5913 static void ath_set_assoc_disallow(struct sigma_dut *dut, const char *ifname,
5914 				   const char *val)
5915 {
5916 	if (strcasecmp(val, "enable") == 0) {
5917 		run_iwpriv(dut, ifname, "mbo_asoc_dis 1");
5918 	} else if (strcasecmp(val, "disable") == 0) {
5919 		run_iwpriv(dut, ifname, "mbo_asoc_dis 0");
5920 	} else {
5921 		sigma_dut_print(dut, DUT_MSG_ERROR,
5922 				"Unsupported assoc_disallow");
5923 	}
5924 }
5925 
5926 
apply_mbo_pref_ap_list(struct sigma_dut * dut)5927 static void apply_mbo_pref_ap_list(struct sigma_dut *dut)
5928 {
5929 	int i;
5930 	int least_pref = 1 << 8;
5931 	char ifname[20];
5932 	uint8_t self_mac[ETH_ALEN];
5933 	char buf[200];
5934 	int ap_ne_class, ap_ne_pref, ap_ne_op_ch;
5935 
5936 	get_if_name(dut, ifname, sizeof(ifname), 1);
5937 	get_hwaddr(ifname, self_mac);
5938 
5939 	/* Clear off */
5940 	snprintf(buf, sizeof(buf),
5941 		 "wifitool %s setbssidpref 00:00:00:00:00:00 0 0 0",
5942 		 ifname);
5943 	run_system(dut, buf);
5944 
5945 	/* Find the least preference number */
5946 	for (i = 0; i < dut->mbo_pref_ap_cnt; i++) {
5947 		unsigned char *mac_addr = dut->mbo_pref_aps[i].mac_addr;
5948 
5949 		ap_ne_class = 1;
5950 		ap_ne_pref = 255;
5951 		ap_ne_op_ch = 1;
5952 		if (dut->mbo_pref_aps[i].ap_ne_pref != -1)
5953 			ap_ne_pref = dut->mbo_pref_aps[i].ap_ne_pref;
5954 		if (dut->mbo_pref_aps[i].ap_ne_class != -1)
5955 			ap_ne_class = dut->mbo_pref_aps[i].ap_ne_class;
5956 		if (dut->mbo_pref_aps[i].ap_ne_op_ch != -1)
5957 			ap_ne_op_ch = dut->mbo_pref_aps[i].ap_ne_op_ch;
5958 
5959 		if (ap_ne_pref < least_pref)
5960 			least_pref = ap_ne_pref;
5961 		snprintf(buf, sizeof(buf),
5962 			 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d",
5963 			 ifname, mac_addr[0], mac_addr[1], mac_addr[2],
5964 			 mac_addr[3], mac_addr[4], mac_addr[5],
5965 			 ap_ne_pref, ap_ne_class, ap_ne_op_ch);
5966 		run_system(dut, buf);
5967 	}
5968 
5969 	/* Now add the self AP Address */
5970 	if (dut->mbo_self_ap_tuple.ap_ne_class == -1) {
5971 		if (dut->ap_channel <= 11)
5972 			ap_ne_class = 81;
5973 		else
5974 			ap_ne_class = 115;
5975 	} else {
5976 		ap_ne_class = dut->mbo_self_ap_tuple.ap_ne_class;
5977 	}
5978 
5979 	if (dut->mbo_self_ap_tuple.ap_ne_op_ch == -1)
5980 		ap_ne_op_ch = dut->ap_channel;
5981 	else
5982 		ap_ne_op_ch = dut->mbo_self_ap_tuple.ap_ne_op_ch;
5983 
5984 	if (dut->mbo_self_ap_tuple.ap_ne_pref == -1)
5985 		ap_ne_pref = least_pref - 1;
5986 	else
5987 		ap_ne_pref = dut->mbo_self_ap_tuple.ap_ne_pref;
5988 
5989 	snprintf(buf, sizeof(buf),
5990 		 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d",
5991 		 ifname, self_mac[0], self_mac[1], self_mac[2],
5992 		 self_mac[3], self_mac[4], self_mac[5],
5993 		 ap_ne_pref,
5994 		 ap_ne_class,
5995 		 ap_ne_op_ch);
5996 	run_system(dut, buf);
5997 }
5998 
5999 
mubrp_commands(struct sigma_dut * dut,const char * ifname)6000 static void mubrp_commands(struct sigma_dut *dut, const char *ifname)
6001 {
6002 	run_iwpriv(dut, ifname, "he_subfer 1");
6003 	run_iwpriv(dut, ifname, "he_mubfer 1");
6004 	/* To enable MU_AX with MU_BRP trigger */
6005 	run_iwpriv(dut, ifname, "he_sounding_mode 13");
6006 	/* Sets g_force_1x1_peer to 1 which should be reset to zero for non MU
6007 	 * test cases */
6008 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 118 1",
6009 			   ifname);
6010 	/* Disable DL OFDMA */
6011 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 11 0",
6012 			   ifname);
6013 }
6014 
6015 
ath_ap_set_params(struct sigma_dut * dut)6016 static void ath_ap_set_params(struct sigma_dut *dut)
6017 {
6018 	const char *basedev = "wifi0";
6019 	const char *basedev_radio = "wifi1";
6020 	const char *ifname = get_main_ifname(dut);
6021 	char *ifname_dual = NULL;
6022 	int i;
6023 	char buf[300];
6024 	unsigned int he_mcsnssmap = dut->he_mcsnssmap;
6025 
6026 	if (sigma_radio_ifname[0])
6027 		basedev = sigma_radio_ifname[0];
6028 
6029 	if (dut->ap_is_dual == 1) {
6030 		basedev = sigma_radio_ifname[0];
6031 		basedev_radio = sigma_radio_ifname[1];
6032 		if (sigma_radio_ifname[0] &&
6033 		    strcmp(sigma_radio_ifname[0], "wifi0") == 0) {
6034 			ifname = "ath0";
6035 			ifname_dual = "ath1";
6036 		} else {
6037 			ifname = "ath1";
6038 			ifname_dual = "ath0";
6039 		}
6040 	}
6041 
6042 	if (dut->ap_countrycode[0]) {
6043 		run_iwpriv(dut, basedev, "setCountry %s", dut->ap_countrycode);
6044 		sigma_dut_print(dut, DUT_MSG_INFO, "Set countrycode");
6045 	}
6046 
6047 	for (i = 0; i < NUM_AP_AC; i++) {
6048 		if (dut->ap_qos[i].ac) {
6049 			run_iwpriv(dut, ifname, "cwmin %d 0 %d", i,
6050 				   dut->ap_qos[i].cwmin);
6051 			run_iwpriv(dut, ifname, "cwmax %d 0 %d", i,
6052 				   dut->ap_qos[i].cwmax);
6053 			run_iwpriv(dut, ifname, "aifs %d 0 %d", i,
6054 				   dut->ap_qos[i].aifs);
6055 			run_iwpriv(dut, ifname, "txoplimit %d 0 %d", i,
6056 				   dut->ap_qos[i].txop);
6057 			run_iwpriv(dut, ifname, "acm %d 0 %d", i,
6058 				   dut->ap_qos[i].acm);
6059 		}
6060 	}
6061 
6062 	for (i = 0; i < NUM_AP_AC; i++) {
6063 		if (dut->ap_sta_qos[i].ac) {
6064 			run_iwpriv(dut, ifname, "cwmin %d 1 %d", i,
6065 				   dut->ap_sta_qos[i].cwmin);
6066 			run_iwpriv(dut, ifname, "cwmax %d 1 %d", i,
6067 				   dut->ap_sta_qos[i].cwmax);
6068 			run_iwpriv(dut, ifname, "aifs %d 1 %d", i,
6069 				   dut->ap_sta_qos[i].aifs);
6070 			run_iwpriv(dut, ifname, "txoplimit %d 1 %d", i,
6071 				   dut->ap_sta_qos[i].txop);
6072 			run_iwpriv(dut, ifname, "acm %d 1 %d", i,
6073 				   dut->ap_sta_qos[i].acm);
6074 		}
6075 	}
6076 
6077 	if (dut->ap_disable_protection == 1) {
6078 		run_iwpriv(dut, ifname, "enablertscts 0");
6079 		sigma_dut_print(dut, DUT_MSG_INFO, "Disabled rtscts");
6080 	}
6081 
6082 	if (dut->ap_ldpc == VALUE_ENABLED)
6083 		run_iwpriv(dut, ifname, "ldpc 3");
6084 	else if (dut->ap_ldpc == VALUE_DISABLED)
6085 		run_iwpriv(dut, ifname, "ldpc 0");
6086 
6087 	if (dut->ap_ampdu == VALUE_ENABLED) {
6088 		run_iwpriv(dut, ifname, "ampdu 1");
6089 	} else if (dut->ap_ampdu == VALUE_DISABLED) {
6090 		run_iwpriv(dut, ifname, "ampdu 0");
6091 		if (dut->program == PROGRAM_HE) {
6092 			run_iwpriv(dut, ifname, "setaddbaoper 1");
6093 			run_system_wrapper(dut, "wifitool %s refusealladdbas 1",
6094 					   ifname);
6095 			if (dut->ap_amsdu == VALUE_ENABLED) {
6096 				/* disable the limit for A-MSDU */
6097 				run_system_wrapper(dut,
6098 						   "wifitool %s setUnitTestCmd 0x48 2 46 1",
6099 						   ifname);
6100 			}
6101 		}
6102 	}
6103 
6104 	if (dut->ap_ampdu_exp) {
6105 		if (dut->program == PROGRAM_VHT) {
6106 			run_iwpriv(dut, ifname, "vhtmaxampdu %d",
6107 				   dut->ap_ampdu_exp);
6108 		} else {
6109 			/* 11N */
6110 			run_iwpriv(dut, ifname, "maxampdu %d",
6111 				   dut->ap_ampdu_exp);
6112 		}
6113 	}
6114 
6115 	if (dut->ap_noack == VALUE_ENABLED) {
6116 		run_iwpriv(dut, ifname, "noackpolicy 0 0 1");
6117 		run_iwpriv(dut, ifname, "noackpolicy 1 0 1");
6118 		run_iwpriv(dut, ifname, "noackpolicy 2 0 1");
6119 		run_iwpriv(dut, ifname, "noackpolicy 3 0 1");
6120 	} else if (dut->ap_noack == VALUE_DISABLED) {
6121 		run_iwpriv(dut, ifname, "noackpolicy 0 0 0");
6122 		run_iwpriv(dut, ifname, "noackpolicy 1 0 0");
6123 		run_iwpriv(dut, ifname, "noackpolicy 2 0 0");
6124 		run_iwpriv(dut, ifname, "noackpolicy 3 0 0");
6125 	}
6126 
6127 	if (dut->device_type == AP_testbed && dut->ap_vhtmcs_map)
6128 		run_iwpriv(dut, ifname, "vht_mcsmap 0x%04x",
6129 			   dut->ap_vhtmcs_map);
6130 
6131 	if (dut->ap_amsdu == VALUE_ENABLED)
6132 		run_iwpriv(dut, ifname, "amsdu 2");
6133 	else if (dut->ap_amsdu == VALUE_DISABLED)
6134 		run_iwpriv(dut, ifname, "amsdu 1");
6135 
6136 	if (dut->ap_rx_amsdu == VALUE_ENABLED)
6137 		run_iwpriv(dut, basedev_radio, "rx_amsdu 1");
6138 	else if (dut->ap_rx_amsdu == VALUE_DISABLED)
6139 		run_iwpriv(dut, basedev_radio, "rx_amsdu 0");
6140 
6141 	/* Command sequence to generate single VHT AMSDU and MPDU */
6142 	if (dut->ap_addba_reject != VALUE_NOT_SET &&
6143 	    dut->ap_ampdu == VALUE_DISABLED &&
6144 	    dut->ap_amsdu == VALUE_ENABLED) {
6145 		run_iwpriv(dut, ifname, "setaddbaoper 1");
6146 
6147 		snprintf(buf, sizeof(buf),
6148 			 "wifitool %s senddelba 1 0 1 4", ifname);
6149 		if (system(buf) != 0) {
6150 			sigma_dut_print(dut, DUT_MSG_ERROR,
6151 					"wifitool senddelba failed");
6152 		}
6153 
6154 		snprintf(buf, sizeof(buf), "wifitool %s sendsingleamsdu 1 0",
6155 			 ifname);
6156 		if (system(buf) != 0) {
6157 			sigma_dut_print(dut, DUT_MSG_ERROR,
6158 					"wifitool sendsingleamsdu failed");
6159 		}
6160 
6161 		run_iwpriv(dut, ifname, "amsdu 10");
6162 	}
6163 
6164 	if (dut->ap_mode == AP_11ac) {
6165 		int chwidth, nss;
6166 
6167 		switch (dut->ap_chwidth) {
6168 		case AP_20:
6169 			chwidth = 0;
6170 			break;
6171 		case AP_40:
6172 			chwidth = 1;
6173 			break;
6174 		case AP_80:
6175 			chwidth = 2;
6176 			break;
6177 		case AP_160:
6178 			chwidth = 3;
6179 			break;
6180 		case AP_80_80:
6181 			chwidth = 3;
6182 			break;
6183 		default:
6184 			chwidth = 0;
6185 			break;
6186 		}
6187 
6188 		switch (dut->ap_tx_streams) {
6189 		case 1:
6190 			nss = 1;
6191 			break;
6192 		case 2:
6193 			nss = 2;
6194 			break;
6195 		case 3:
6196 			nss = 3;
6197 			break;
6198 		case 4:
6199 			nss = 4;
6200 			break;
6201 		default:
6202 			nss = 3;
6203 			break;
6204 		}
6205 
6206 		if (dut->ap_fixed_rate) {
6207 			if (nss == 4)
6208 				ath_disable_txbf(dut, ifname);
6209 
6210 			/* Set the nss */
6211 			run_iwpriv(dut, ifname, "nss %d", nss);
6212 
6213 			/* Set the channel width */
6214 			run_iwpriv(dut, ifname, "chwidth %d", chwidth);
6215 
6216 			/* Set the VHT MCS */
6217 			run_iwpriv(dut, ifname, "vhtmcs %d", dut->ap_mcs);
6218 		}
6219 	}
6220 
6221 	if (dut->ap_dyn_bw_sig == VALUE_ENABLED)
6222 		run_iwpriv(dut, ifname, "cwmenable 1");
6223 	else if (dut->ap_dyn_bw_sig == VALUE_DISABLED)
6224 		run_iwpriv(dut, ifname, "cwmenable 0");
6225 
6226 	if (dut->ap_sig_rts == VALUE_ENABLED) {
6227 		snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname);
6228 		if (system(buf) != 0) {
6229 			sigma_dut_print(dut, DUT_MSG_ERROR,
6230 					"iwconfig rts 64 failed");
6231 		}
6232 	} else if (dut->ap_sig_rts == VALUE_DISABLED) {
6233 		snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname);
6234 		if (system(buf) != 0) {
6235 			sigma_dut_print(dut, DUT_MSG_ERROR,
6236 					"iwconfig rts 2347 failed");
6237 		}
6238 	}
6239 
6240 	if (dut->ap_hs2) {
6241 		run_iwpriv(dut, ifname, "qbssload 1");
6242 		sigma_dut_print(dut, DUT_MSG_INFO, "Enabled qbssload");
6243 	}
6244 
6245 	if (dut->ap_bss_load && dut->ap_bss_load != -1) {
6246 		unsigned int bssload = 0;
6247 
6248 		if (dut->ap_bss_load == 1) {
6249 			/* STA count: 1, CU: 50, AAC: 65535 */
6250 			bssload = 0x0132ffff;
6251 		} else if (dut->ap_bss_load == 2) {
6252 			/* STA count: 1, CU: 200, AAC: 65535 */
6253 			bssload = 0x01c8ffff;
6254 		} else if (dut->ap_bss_load == 3) {
6255 			/* STA count: 1, CU: 75, AAC: 65535 */
6256 			bssload = 0x014bffff;
6257 		}
6258 
6259 		run_iwpriv(dut, ifname, "hcbssload %u", bssload);
6260 	} else if (dut->ap_bss_load == 0) {
6261 		run_iwpriv(dut, ifname, "qbssload 0");
6262 		sigma_dut_print(dut, DUT_MSG_INFO, "Disabled qbssload");
6263 	}
6264 
6265 	if (dut->ap_dgaf_disable) {
6266 		run_iwpriv(dut, ifname, "dgaf_disable 1");
6267 		sigma_dut_print(dut, DUT_MSG_INFO, "Enabled dgaf_disable");
6268 	}
6269 
6270 	if (dut->ap_l2tif) {
6271 		run_iwpriv(dut, ifname, "l2tif 1");
6272 		snprintf(buf, sizeof(buf),
6273 			"echo 1 > /sys/class/net/br0/brif/ath0/hotspot_l2tif");
6274 		if (system(buf) != 0)
6275 			sigma_dut_print(dut, DUT_MSG_ERROR,
6276 				"l2tif br failed");
6277 
6278 		snprintf(buf, sizeof(buf),
6279 			"echo 1 > /sys/class/net/br0/brif/eth0/hotspot_wan");
6280 		if (system(buf) != 0)
6281 			sigma_dut_print(dut, DUT_MSG_ERROR,
6282 				"l2tif brif failed");
6283 		sigma_dut_print(dut, DUT_MSG_INFO, "Enabled l2tif");
6284 	}
6285 
6286 	if (dut->ap_ndpa_frame == 0) {
6287 		snprintf(buf, sizeof(buf),
6288 			 "wifitool %s beeliner_fw_test 117 192", ifname);
6289 		if (system(buf) != 0) {
6290 			sigma_dut_print(dut, DUT_MSG_ERROR,
6291 					"wifitool beeliner_fw_test 117 192 failed");
6292 		}
6293 		snprintf(buf, sizeof(buf),
6294 			 "wifitool %s beeliner_fw_test 118 192", ifname);
6295 		if (system(buf) != 0) {
6296 			sigma_dut_print(dut, DUT_MSG_ERROR,
6297 					"wifitool beeliner_fw_test 117 192 failed");
6298 		}
6299 	} else if (dut->ap_ndpa_frame == 1) {
6300 		/* Driver default - no changes needed */
6301 	} else if (dut->ap_ndpa_frame == 2) {
6302 		snprintf(buf, sizeof(buf),
6303 			 "wifitool %s beeliner_fw_test 115 1", ifname);
6304 		if (system(buf) != 0) {
6305 			sigma_dut_print(dut, DUT_MSG_ERROR,
6306 					"wifitool beeliner_fw_test 117 192 failed");
6307 		}
6308 		snprintf(buf, sizeof(buf),
6309 			 "wifitool %s beeliner_fw_test 116 1", ifname);
6310 		if (system(buf) != 0) {
6311 			sigma_dut_print(dut, DUT_MSG_ERROR,
6312 					"wifitool beeliner_fw_test 117 192 failed");
6313 		}
6314 	}
6315 
6316 	if (dut->ap_rtt == 1)
6317 		run_iwpriv(dut, ifname, "enable_rtt 1");
6318 
6319 	if (dut->ap_lci == 1)
6320 		run_iwpriv(dut, ifname, "enable_lci 1");
6321 
6322 	if (dut->ap_lcr == 1)
6323 		run_iwpriv(dut, ifname, "enable_lcr 1");
6324 
6325 	if (dut->ap_rrm == 1)
6326 		run_iwpriv(dut, ifname, "enable_rmm 1");
6327 
6328 	if (dut->ap_lci == 1 || dut->ap_lcr == 1) {
6329 		run_system(dut, "wpc -l /tmp/lci_cfg.txt");
6330 	}
6331 
6332 	if (dut->ap_neighap >= 1 && dut->ap_lci == 0) {
6333 		FILE *f;
6334 
6335 		f = fopen("/tmp/nbr_report.txt", "w");
6336 		if (!f) {
6337 			sigma_dut_print(dut, DUT_MSG_ERROR,
6338 					"Failed to open /tmp/nbr_report.txt");
6339 			return;
6340 		}
6341 
6342 		fprintf(f,
6343 			"ap_1 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x2a 0x00\n",
6344 			dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1],
6345 			dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3],
6346 			dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5],
6347 			dut->ap_val_opchannel[0]);
6348 		fclose(f);
6349 
6350 		f = fopen("/tmp/ftmrr.txt", "w");
6351 		if (!f) {
6352 			sigma_dut_print(dut, DUT_MSG_ERROR,
6353 					"Failed to open /tmp/ftmrr.txt");
6354 			return;
6355 		}
6356 
6357 		fprintf(f,
6358 			"ap_1 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x2a 0x00\n",
6359 			dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1],
6360 			dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3],
6361 			dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5],
6362 			dut->ap_val_opchannel[0]);
6363 		fclose(f);
6364 	}
6365 
6366 	if (dut->ap_neighap >= 2 && dut->ap_lci == 0) {
6367 		FILE *f;
6368 
6369 		f = fopen("/tmp/nbr_report.txt", "a");
6370 		if (!f) {
6371 			sigma_dut_print(dut, DUT_MSG_ERROR,
6372 					"Failed to open /tmp/nbr_report.txt");
6373 			return;
6374 		}
6375 		fprintf(f,
6376 			"ap_2 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x6a 0x00\n",
6377 			dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1],
6378 			dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3],
6379 			dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5],
6380 			dut->ap_val_opchannel[1]);
6381 		fclose(f);
6382 
6383 		f = fopen("/tmp/ftmrr.txt", "a");
6384 		if (!f) {
6385 			sigma_dut_print(dut, DUT_MSG_ERROR,
6386 					"Failed to open /tmp/ftmrr.txt");
6387 			return;
6388 		}
6389 		fprintf(f,
6390 			"ap_2 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x6a 0x00\n",
6391 			dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1],
6392 			dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3],
6393 			dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5],
6394 			dut->ap_val_opchannel[1]);
6395 		fclose(f);
6396 	}
6397 
6398 	if (dut->ap_neighap >= 3 && dut->ap_lci == 0) {
6399 		FILE *f;
6400 
6401 		f = fopen("/tmp/nbr_report.txt", "a");
6402 		if (!f) {
6403 			sigma_dut_print(dut, DUT_MSG_ERROR,
6404 					"Failed to open /tmp/nbr_report.txt");
6405 			return;
6406 		}
6407 
6408 		fprintf(f,
6409 			"ap_3 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x9b 0x00\n",
6410 			dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1],
6411 			dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3],
6412 			dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5],
6413 			dut->ap_val_opchannel[2]);
6414 		fclose(f);
6415 
6416 		f = fopen("/tmp/ftmrr.txt", "a");
6417 		if (!f) {
6418 			sigma_dut_print(dut, DUT_MSG_ERROR,
6419 					"Failed to open /tmp/ftmrr.txt");
6420 			return;
6421 		}
6422 
6423 		fprintf(f,
6424 			"ap_3 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x9b 0x00\n",
6425 			dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1],
6426 			dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3],
6427 			dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5],
6428 			dut->ap_val_opchannel[2]);
6429 		fclose(f);
6430 	}
6431 
6432 	if (dut->ap_neighap) {
6433 		run_iwpriv(dut, ifname, "enable_rtt 1");
6434 		run_iwpriv(dut, ifname, "enable_lci 1");
6435 		run_iwpriv(dut, ifname, "enable_lcr 1");
6436 		run_iwpriv(dut, ifname, "enable_rrm 1");
6437 	}
6438 
6439 	if (dut->ap_scan == 1) {
6440 		run_iwpriv(dut, ifname, "scanentryage 600");
6441 		snprintf(buf, sizeof(buf), "iwlist %s scan", ifname);
6442 		run_system(dut, buf);
6443 	}
6444 
6445 	if (dut->ap_set_bssidpref) {
6446 		snprintf(buf, sizeof(buf),
6447 			 "wifitool %s setbssidpref 00:00:00:00:00:00 0 00 00",
6448 			 ifname);
6449 		if (system(buf) != 0) {
6450 			sigma_dut_print(dut, DUT_MSG_ERROR,
6451 					"wifitool clear bssidpref failed");
6452 		}
6453 	}
6454 
6455 	if (dut->wnm_bss_max_feature != VALUE_NOT_SET) {
6456 		int feature_enable;
6457 
6458 		feature_enable = dut->wnm_bss_max_feature == VALUE_ENABLED;
6459 		run_iwpriv(dut, ifname, "wnm %d", feature_enable);
6460 		run_iwpriv(dut, ifname, "wnm_bss %d", feature_enable);
6461 		if (feature_enable) {
6462 			const char *extra = "";
6463 
6464 			if (dut->wnm_bss_max_protection != VALUE_NOT_SET) {
6465 				if (dut->wnm_bss_max_protection ==
6466 				    VALUE_ENABLED)
6467 					extra = " 1";
6468 				else
6469 					extra = " 0";
6470 			}
6471 			snprintf(buf, sizeof(buf),
6472 				 "wlanconfig %s wnm setbssmax %d%s",
6473 				 ifname, dut->wnm_bss_max_idle_time, extra);
6474 			run_system(dut, buf);
6475 		}
6476 	}
6477 
6478 	if (dut->program == PROGRAM_MBO) {
6479 		apply_mbo_pref_ap_list(dut);
6480 		run_iwpriv(dut, ifname, "mbo_cel_pref %d",
6481 			   dut->ap_cell_cap_pref);
6482 		run_iwpriv(dut, ifname, "mbocap 0x40");
6483 		ath_set_assoc_disallow(dut, ifname, "disable");
6484 	}
6485 
6486 	if (dut->ap_oce == VALUE_ENABLED)
6487 		run_iwpriv(dut, ifname, "set_bpr_enable 1");
6488 
6489 	if (dut->ap_oce == VALUE_ENABLED && dut->ap_channel <= 11) {
6490 		run_iwpriv(dut, ifname, "prb_rate 5500");
6491 		run_iwpriv(dut, ifname, "set_bcn_rate 5500");
6492 	}
6493 
6494 	if (dut->ap_oce == VALUE_DISABLED)
6495 		run_iwpriv(dut, ifname, "set_bpr_enable 0");
6496 
6497 	if (dut->ap_oce == VALUE_DISABLED && dut->ap_channel <= 11) {
6498 		run_iwpriv(dut, ifname, "mgmt_rate 1000");
6499 		run_iwpriv(dut, ifname, "set_bcn_rate 1000");
6500 	}
6501 
6502 	if (dut->ap_bcnint)
6503 		run_iwpriv(dut, ifname, "bintval %d", dut->ap_bcnint);
6504 
6505 	if (dut->ap_filsdscv == VALUE_DISABLED)
6506 		run_iwpriv(dut, ifname, "enable_fils 0 0");
6507 
6508 	if (dut->ap_filshlp == VALUE_ENABLED)
6509 		run_iwpriv(dut, ifname, "oce_hlp 1");
6510 	else if (dut->ap_filshlp == VALUE_DISABLED)
6511 		run_iwpriv(dut, ifname, "oce_hlp 0");
6512 
6513 	/*  When RNR is enabled, also enable apchannelreport, background scan */
6514 	if (dut->ap_rnr == VALUE_ENABLED) {
6515 		run_iwpriv(dut, ifname, "rnr 1");
6516 		run_iwpriv(dut, ifname, "rnr_tbtt 1");
6517 		run_iwpriv(dut, ifname, "apchanrpt 1");
6518 		run_iwpriv(dut, basedev, "acs_ctrlflags 0x4");
6519 		run_iwpriv(dut, basedev, "acs_scanintvl 60");
6520 		run_iwpriv(dut, basedev, "acs_bkscanen 1");
6521 		if (dut->ap_is_dual == 1) {
6522 			run_iwpriv(dut, ifname_dual, "rnr 1");
6523 			run_iwpriv(dut, ifname_dual, "rnr_tbtt 1");
6524 			run_iwpriv(dut, ifname_dual, "apchanrpt 1");
6525 			run_iwpriv(dut, basedev_radio, "acs_ctrlflags 0x4");
6526 			run_iwpriv(dut, basedev_radio, "acs_scanintvl 60");
6527 			run_iwpriv(dut, basedev_radio, "acs_bkscanen 1");
6528 		}
6529 	}
6530 
6531 	if (dut->ap_blechanutil || dut->ap_ble_admit_cap || dut->ap_blestacnt) {
6532 		run_iwpriv(dut, ifname, "qbssload 0");
6533 		snprintf(buf, sizeof(buf),
6534 			 "wlanconfig %s addie ftype 0 len 7 data 0b05%02x%02x%02x%02x%02x ",
6535 			 ifname, dut->ap_blestacnt & 0xFF,
6536 			 dut->ap_blestacnt >> 8, dut->ap_blechanutil,
6537 			 dut->ap_ble_admit_cap & 0xFF,
6538 			 dut->ap_ble_admit_cap >> 8);
6539 		run_system(dut, buf);
6540 		snprintf(buf, sizeof(buf),
6541 			 "wlanconfig %s addie ftype 2 len 7 data 0b05%02x%02x%02x%02x%02x ",
6542 			 ifname, dut->ap_blestacnt & 0xFF,
6543 			 dut->ap_blestacnt >> 8, dut->ap_blechanutil,
6544 			 dut->ap_ble_admit_cap & 0xFF,
6545 			 dut->ap_ble_admit_cap >> 8);
6546 		run_system(dut, buf);
6547 	}
6548 
6549 	if (dut->ap_esp == VALUE_ENABLED)
6550 		run_iwpriv(dut, basedev, "esp_period 5");
6551 	else if (dut->ap_esp == VALUE_DISABLED)
6552 		run_iwpriv(dut, basedev, "esp_period 0");
6553 
6554 	if (dut->ap_datappdudura)
6555 		run_iwpriv(dut, basedev, "esp_ppdu_dur %d",
6556 			   dut->ap_datappdudura);
6557 
6558 	if (dut->ap_airtimefract)
6559 		run_iwpriv(dut, basedev, "esp_airtime %d",
6560 			   dut->ap_airtimefract);
6561 
6562 	if (dut->ap_dhcp_stop) {
6563 		snprintf(buf, sizeof(buf), "/etc/init.d/dnsmasq stop");
6564 		run_system(dut, buf);
6565 	}
6566 
6567 	if (dut->ap_bawinsize)
6568 		run_iwpriv(dut, basedev, "esp_ba_window %d", dut->ap_bawinsize);
6569 
6570 	if (dut->program == PROGRAM_DPP) {
6571 		if (dut->ap_interface_2g == 1) {
6572 			run_iwpriv(dut, ifname, "set_bcn_rate 5500");
6573 			run_iwpriv(dut, ifname, "prb_rate 5500");
6574 			run_iwpriv(dut, ifname, "mgmt_rate 5500");
6575 		}
6576 
6577 		run_iwpriv(dut, basedev, "set_rxfilter 0xffffffff");
6578 		dut->hostapd_running = 1;
6579 	}
6580 
6581 	if (dut->program == PROGRAM_HE) {
6582 		/* disable sending basic triggers */
6583 		run_system_wrapper(dut,
6584 				   "wifitool %s setUnitTestCmd 0x47 2 42 0",
6585 				   ifname);
6586 		/* disable MU BAR */
6587 		run_system_wrapper(dut,
6588 				   "wifitool %s setUnitTestCmd 0x47 2 64 1",
6589 				   ifname);
6590 		/* disable PSD Boost */
6591 		run_system_wrapper(dut,
6592 				   "wifitool %s setUnitTestCmd 0x48 2 142 1",
6593 				   ifname);
6594 		/* Enable mix bw */
6595 		run_system_wrapper(dut,
6596 				   "wifitool %s setUnitTestCmd 0x47 2 141 1",
6597 				   ifname);
6598 		/* Disable preferred AC */
6599 		run_system_wrapper(dut,
6600 				   "wifitool %s setUnitTestCmd 0x48 2 186 0",
6601 				   ifname);
6602 		run_iwpriv(dut, basedev, "he_muedca_mode 0");
6603 		run_iwpriv(dut, ifname, "he_ul_ofdma 0");
6604 		run_iwpriv(dut, ifname, "he_dl_ofdma 0");
6605 		if (dut->he_set_sta_1x1 == VALUE_ENABLED) {
6606 			/* sets g_force_1x1_peer to 1 */
6607 			run_system_wrapper(dut,
6608 					   "wifitool %s setUnitTestCmd 0x48 2 118 1",
6609 					    ifname);
6610 		}
6611 		if (dut->ap_txBF) {
6612 			/* Enable SU_AX sounding */
6613 			run_iwpriv(dut, ifname, "he_sounding_mode 1");
6614 			/* Ignore TBTT for NDP */
6615 			run_system_wrapper(dut,
6616 					   "wifitool %s setUnitTestCmd 0x48 2 2 1",
6617 					   ifname);
6618 			/* g_cv_query_enable=1, i.e., cv query enable */
6619 			run_system_wrapper(dut,
6620 					   "wifitool %s setUnitTestCmd 0x47 2 7 1",
6621 					   ifname);
6622 			/* Override TPC calculations and set TxBF flag to True
6623  */
6624 			run_system_wrapper(dut,
6625 					   "wifitool %s setUnitTestCmd 0x47 2 47 1",
6626 					   ifname);
6627 		}
6628 		if (dut->device_type == AP_testbed) {
6629 			run_iwpriv(dut, ifname, "tx_stbc 0");
6630 			run_iwpriv(dut, ifname, "he_txmcsmap 0x0");
6631 			run_iwpriv(dut, ifname, "he_rxmcsmap 0x0");
6632 			run_iwpriv(dut, ifname, "he_amsdu_in_ampdu_supp 0");
6633 			run_iwpriv(dut, ifname, "he_bfee_sts_supp 0 0");
6634 			run_iwpriv(dut, ifname, "he_4xltf_800nsgi_rx 0");
6635 			run_iwpriv(dut, ifname, "he_1xltf_800nsgi_rx 0");
6636 			run_iwpriv(dut, ifname, "he_max_nc 0");
6637 			run_iwpriv(dut, ifname, "he_bsr_supp 0");
6638 			run_iwpriv(dut, ifname, "rx_stbc 0");
6639 			if (dut->ap_he_dlofdma == VALUE_DISABLED)
6640 				run_iwpriv(dut, ifname, "he_dlofdma 0");
6641 			if (dut->ap_channel <= 11) {
6642 				dut->ap_bcc = VALUE_ENABLED;
6643 				run_iwpriv(dut, ifname, "vht_11ng 0");
6644 			}
6645 			if (!dut->ap_txBF) {
6646 				run_iwpriv(dut, ifname, "he_subfer 0");
6647 				run_iwpriv(dut, ifname, "he_subfee 0");
6648 			}
6649 			if (!dut->ap_mu_txBF) {
6650 				run_iwpriv(dut, ifname, "he_mubfer 0");
6651 				run_iwpriv(dut, ifname, "he_mubfee 0");
6652 			}
6653 			if (dut->ap_cipher == AP_WEP ||
6654 			    dut->ap_cipher == AP_TKIP)
6655 				run_iwpriv(dut, ifname, "htweptkip 1");
6656 			if (dut->ap_rx_streams || dut->ap_tx_streams)
6657 				run_iwpriv(dut, ifname, "nss %d",
6658 					   dut->ap_rx_streams);
6659 		}
6660 	}
6661 
6662 	if (dut->ap_he_ulofdma == VALUE_ENABLED) {
6663 		run_iwpriv(dut, ifname, "he_ul_ofdma 1");
6664 		run_iwpriv(dut, ifname, "he_mu_edca 1");
6665 
6666 		/* Disable sounding for UL OFDMA */
6667 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0",
6668 				   ifname);
6669 
6670 		if ((dut->ap_rx_streams || dut->ap_tx_streams) &&
6671 		    dut->device_type == AP_testbed) {
6672 			unsigned int txchainmask = 0x00;
6673 
6674 			switch (dut->ap_rx_streams) {
6675 			case 1:
6676 				txchainmask = 0x01;
6677 				break;
6678 			case 2:
6679 				txchainmask = 0x03;
6680 				break;
6681 			case 3:
6682 				txchainmask = 0x07;
6683 				break;
6684 			case 4:
6685 				txchainmask = 0x0f;
6686 				break;
6687 			case 5:
6688 				txchainmask = 0x1f;
6689 				break;
6690 			case 6:
6691 				txchainmask = 0x3f;
6692 				break;
6693 			case 7:
6694 				txchainmask = 0x7f;
6695 				break;
6696 			case 8:
6697 				txchainmask = 0xff;
6698 				break;
6699 			}
6700 
6701 			run_iwpriv(dut, ifname, "he_ul_nss %d",
6702 				   dut->ap_rx_streams);
6703 			run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
6704 			run_iwpriv(dut, basedev, "rxchainmask %d", txchainmask);
6705 		}
6706 
6707 		if (dut->ap_channel == 100 && dut->device_type == AP_testbed)
6708 			run_system_wrapper(dut, "iwpriv %s inact 1000", ifname);
6709 
6710 		if (dut->he_ul_mcs)
6711 			run_iwpriv(dut, ifname, "he_ul_mcs %d", dut->he_ul_mcs);
6712 
6713 		run_iwpriv(dut, ifname, "he_ul_ltf 3");
6714 		run_iwpriv(dut, ifname, "he_ul_shortgi 3");
6715 		run_iwpriv(dut, basedev, "he_ul_trig_int 2");
6716 
6717 		/* Disable efficiency check for UL OFDMA. We do not send TBPPDU
6718 		 * for one user. With this command, we would send UL OFDMA even
6719 		 * for one user to allow testing to be done without requiring
6720 		 * more than one station. */
6721 		run_system_wrapper(dut,
6722 				   "wifitool %s setUnitTestCmd 0x47 2 131 0",
6723 				   ifname);
6724 		/* Set random RU allocation */
6725 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 9 1",
6726 				   ifname);
6727 		/* To set TBTT PPDU duration (us) */
6728 		run_system_wrapper(dut,
6729 				   "wifitool %s setUnitTestCmd 0x48 2 63 1908",
6730 				   ifname);
6731 	}
6732 
6733 	if (dut->ap_he_dlofdma == VALUE_ENABLED) {
6734 		run_iwpriv(dut, ifname, "he_dl_ofdma 1", ifname);
6735 
6736 		/* For fixed MCS */
6737 		novap_reset(dut, ifname, 0);
6738 		run_iwpriv(dut, ifname,
6739 			   "cfg80211tool %s setratemask 3 0x80f80f80 0x0f80f80f 0xf80f80f8");
6740 	}
6741 
6742 	if (dut->ap_he_ppdu == PPDU_MU && dut->ap_he_dlofdma == VALUE_ENABLED) {
6743 		/* Increase the min TX time limit for MU MIMO to disable MU MIMO
6744 		 * scheduling */
6745 		run_system_wrapper(dut,
6746 				   "wifitool %s setUnitTestCmd 0x47 2 11 1000000",
6747 				   ifname);
6748 		/* Increase the max TX time limit for DL OFDMA to enable OFDMA
6749 		 * scheduling */
6750 		run_system_wrapper(dut,
6751 				   "wifitool %s setUnitTestCmd 0x47 2 17 1000000",
6752 				   ifname);
6753 		/* Disable 'force SU schedule' to enable MU sch */
6754 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 8 0",
6755 				   ifname);
6756 		/* Enable MU 11ax support in sch algo */
6757 		run_system_wrapper(dut,
6758 				   "wifitool %s setUnitTestCmd 0x47 2 29 0",
6759 				   ifname);
6760 		/* Enable to sort RU allocation */
6761 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x4b 2 2 1",
6762 				   ifname);
6763 	}
6764 
6765 	if (dut->ap_numsounddim) {
6766 		unsigned int txchainmask = 0;
6767 
6768 		switch (dut->ap_numsounddim) {
6769 		case 1:
6770 			txchainmask = 0x01;
6771 			break;
6772 		case 2:
6773 			txchainmask = 0x03;
6774 			break;
6775 		case 3:
6776 			txchainmask = 0x07;
6777 			break;
6778 		case 4:
6779 			txchainmask = 0x0f;
6780 			break;
6781 		case 5:
6782 			txchainmask = 0x1f;
6783 			break;
6784 		case 6:
6785 			txchainmask = 0x3f;
6786 			break;
6787 		case 7:
6788 			txchainmask = 0x7f;
6789 			break;
6790 		case 8:
6791 			txchainmask = 0xff;
6792 			break;
6793 		}
6794 		run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
6795 	}
6796 
6797 	if (dut->ap_numsounddim && dut->device_type == AP_testbed) {
6798 		/* Sets g_force_1x1_peer to 1 which should be reset to zero
6799 		 * for non-MU test cases */
6800 		run_system_wrapper(dut,
6801 				   "wifitool %s setUnitTestCmd 0x48 2 118 1",
6802 				   ifname);
6803 		if (dut->ap_mu_txBF) {
6804 			/* Disable DL OFDMA */
6805 			run_system_wrapper(dut,
6806 					   "wifitool %s setUnitTestCmd 0x47 2 11 0",
6807 					   ifname);
6808 		}
6809 	}
6810 
6811 	if (dut->ap_bcc == VALUE_ENABLED) {
6812 		run_iwpriv(dut, ifname, "mode 11AHE20");
6813 		run_iwpriv(dut, ifname, "nss 2");
6814 		run_iwpriv(dut, ifname, "he_txmcsmap 0x0");
6815 		run_iwpriv(dut, ifname, "he_rxmcsmap 0x0");
6816 	}
6817 
6818 	if (dut->ap_he_frag == VALUE_ENABLED)
6819 		run_iwpriv(dut, ifname, "he_frag 1");
6820 	else if (dut->ap_he_frag == VALUE_DISABLED)
6821 		run_iwpriv(dut, ifname, "he_frag 0");
6822 
6823 	if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) {
6824 		if (dut->ap_ba_bufsize == BA_BUFSIZE_64)
6825 			run_iwpriv(dut, ifname, "ba_bufsize 0");
6826 		else
6827 			run_iwpriv(dut, ifname, "ba_bufsize 1");
6828 	}
6829 
6830 	if (dut->ap_mu_edca == VALUE_ENABLED)
6831 		run_iwpriv(dut, ifname, "he_mu_edca 1");
6832 
6833 	if (dut->ap_he_mimo == MIMO_DL) {
6834 		mubrp_commands(dut, ifname);
6835 		if (dut->device_type != AP_testbed)
6836 			run_system_wrapper(
6837 				dut, "wifitool %s setUnitTestCmd 0x48 2 100 2",
6838 				ifname);
6839 	}
6840 
6841 	if (dut->ap_he_mimo == MIMO_UL)
6842 		run_iwpriv(dut, ifname, "he_mubfee 1");
6843 
6844 	if (dut->ap_he_rtsthrshld == VALUE_ENABLED)
6845 		run_iwpriv(dut, ifname, "he_rtsthrshld 512");
6846 	else if (dut->ap_he_rtsthrshld == VALUE_DISABLED)
6847 		run_iwpriv(dut, ifname, "he_rtsthrshld 1024");
6848 
6849 	if (dut->ap_mbssid == VALUE_ENABLED &&
6850 	    (dut->ap_rx_streams || dut->ap_tx_streams) &&
6851 	    dut->device_type == AP_testbed) {
6852 		const char *ifname_1;
6853 
6854 		ifname_1= dut->ap_channel >= 36 ? "ath01" : "ath11";
6855 
6856 		/* NSS is not set in Secondary VAP for MBSSID case,
6857 		 * hence it is explicitly set here. For primary VAP
6858 		 * NSS is set during AP configuration */
6859 		run_iwpriv(dut, ifname_1, "nss %d", dut->ap_rx_streams);
6860 	}
6861 
6862 	if (dut->ap_twtresp == VALUE_ENABLED)
6863 		run_iwpriv(dut, ifname, "twt_responder 1");
6864 	else if (dut->ap_twtresp == VALUE_DISABLED)
6865 		run_iwpriv(dut, ifname, "twt_responder 0");
6866 
6867 	if (dut->program == PROGRAM_HE && dut->ap_fixed_rate) {
6868 		int nss = 0, mcs = 0;
6869 		uint16_t mcsnssmap = 0;
6870 
6871 		/* MCS 7 is used - set only nss and he_mcs.
6872 		 * Do not set mcsnssmap unless MCS is 9 or 11. */
6873 		if (dut->ap_mcs >= 9) {
6874 			if (dut->ap_mcs == 9) {
6875 				if (dut->ap_tx_streams == 1) {
6876 					nss = 1;
6877 					mcs = dut->ap_mcs;
6878 				} else if (dut->ap_tx_streams == 2) {
6879 					nss = 2;
6880 					mcs = dut->ap_mcs;
6881 				}
6882 			} else if (dut->ap_mcs == 11) {
6883 				if (dut->ap_tx_streams == 1) {
6884 					nss = 1;
6885 					mcs = dut->ap_mcs;
6886 				} else if (dut->ap_tx_streams == 2) {
6887 					nss = 2;
6888 					mcs = dut->ap_mcs;
6889 				}
6890 			}
6891 
6892 			get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs);
6893 			he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap;
6894 		}
6895 
6896 		run_iwpriv(dut, ifname, "nss %d", dut->ap_tx_streams);
6897 		run_iwpriv(dut, ifname, "he_mcs %d", dut->ap_mcs);
6898 	}
6899 
6900 	if (he_mcsnssmap) {
6901 		run_iwpriv(dut, ifname, "he_rxmcsmap %lu", he_mcsnssmap);
6902 		run_iwpriv(dut, ifname, "he_txmcsmap %lu", he_mcsnssmap);
6903 	}
6904 
6905 	if (dut->he_sounding == VALUE_ENABLED)
6906 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0",
6907 				   ifname);
6908 
6909 	if (dut->he_mmss)
6910 		run_iwpriv(dut, ifname, "ampduden_ovrd %d", dut->he_mmss);
6911 
6912 	if (dut->he_srctrl_allow == 0) {
6913 		/* This is a special testbed AP case to enable SR for protocol
6914 		 * testing when SRCtrl_SRValue15Allowed is specified.
6915 		 */
6916 		run_iwpriv(dut, ifname, "he_sr_enable 1");
6917 	}
6918 }
6919 
6920 
cmd_ath_ap_config_commit(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)6921 static int cmd_ath_ap_config_commit(struct sigma_dut *dut,
6922 				    struct sigma_conn *conn,
6923 				    struct sigma_cmd *cmd)
6924 {
6925 	/* const char *name = get_param(cmd, "NAME"); */
6926 	char buf[100];
6927 	struct stat s;
6928 	const char *ifname = dut->ap_is_dual ? "ath1" : "ath0";
6929 	int res;
6930 
6931 	if (stat("/proc/athversion", &s) == 0) {
6932 		sigma_dut_print(dut, DUT_MSG_INFO, "Run apdown");
6933 		run_system(dut, "apdown");
6934 	}
6935 
6936 	cmd_ath_ap_radio_config(dut);
6937 
6938 	snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID=%s'", dut->ap_ssid);
6939 	run_system(dut, buf);
6940 
6941 	switch (dut->ap_key_mgmt) {
6942 	case AP_OPEN:
6943 		if (dut->ap_cipher == AP_WEP) {
6944 			run_system(dut, "cfg -a AP_SECMODE=WEP");
6945 			run_system(dut, "cfg -a AP_SECFILE=NONE");
6946 			/* shared auth mode not supported */
6947 			run_system(dut, "cfg -a AP_WEP_MODE_0=1");
6948 			run_system(dut, "cfg -a AP_WEP_MODE_1=1");
6949 			snprintf(buf, sizeof(buf),
6950 				 "cfg -a WEP_RADIO_NUM0_KEY_1=%s",
6951 				 dut->ap_wepkey);
6952 			run_system(dut, buf);
6953 			snprintf(buf, sizeof(buf),
6954 				 "cfg -a WEP_RADIO_NUM1_KEY_1=%s",
6955 				 dut->ap_wepkey);
6956 			run_system(dut, buf);
6957 		} else {
6958 			run_system(dut, "cfg -a AP_SECMODE=None");
6959 		}
6960 		break;
6961 	case AP_WPA2_PSK:
6962 	case AP_WPA2_PSK_MIXED:
6963 	case AP_WPA_PSK:
6964 		case AP_WPA2_SAE:
6965 		case AP_WPA2_PSK_SAE:
6966 		if (dut->ap_key_mgmt == AP_WPA2_PSK ||
6967 		    dut->ap_key_mgmt == AP_WPA2_SAE ||
6968 		    dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
6969 			run_system(dut, "cfg -a AP_WPA=2");
6970 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
6971 			run_system(dut, "cfg -a AP_WPA=3");
6972 		else
6973 			run_system(dut, "cfg -a AP_WPA=1");
6974 		/* TODO: SAE configuration */
6975 		run_system(dut, "cfg -a AP_SECMODE=WPA");
6976 		run_system(dut, "cfg -a AP_SECFILE=PSK");
6977 		res = snprintf(buf, sizeof(buf), "cfg -a 'PSK_KEY=%s'",
6978 			       dut->ap_passphrase);
6979 		if (res < 0 || res >= sizeof(buf))
6980 			return ERROR_SEND_STATUS;
6981 		run_system(dut, buf);
6982 		if (dut->ap_cipher == AP_CCMP_TKIP)
6983 			run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\"");
6984 		else if (dut->ap_cipher == AP_TKIP)
6985 			run_system(dut, "cfg -a AP_CYPHER=TKIP");
6986 		else
6987 			run_system(dut, "cfg -a AP_CYPHER=CCMP");
6988 		break;
6989 	case AP_WPA2_EAP:
6990 	case AP_WPA2_EAP_MIXED:
6991 	case AP_WPA_EAP:
6992 		if (dut->ap_key_mgmt == AP_WPA2_EAP)
6993 			run_system(dut, "cfg -a AP_WPA=2");
6994 		else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
6995 			run_system(dut, "cfg -a AP_WPA=3");
6996 		else
6997 			run_system(dut, "cfg -a AP_WPA=1");
6998 		run_system(dut, "cfg -a AP_SECMODE=WPA");
6999 		run_system(dut, "cfg -a AP_SECFILE=EAP");
7000 		if (dut->ap_cipher == AP_CCMP_TKIP)
7001 			run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\"");
7002 		else if (dut->ap_cipher == AP_TKIP)
7003 			run_system(dut, "cfg -a AP_CYPHER=TKIP");
7004 		else
7005 			run_system(dut, "cfg -a AP_CYPHER=CCMP");
7006 		snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER=%s",
7007 			 dut->ap_radius_ipaddr);
7008 		run_system(dut, buf);
7009 		snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT=%d",
7010 			 dut->ap_radius_port);
7011 		run_system(dut, buf);
7012 		res = snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SECRET=%s",
7013 			       dut->ap_radius_password);
7014 		if (res < 0 || res >= sizeof(buf))
7015 			return ERROR_SEND_STATUS;
7016 		run_system(dut, buf);
7017 		break;
7018 	case AP_WPA2_EAP_OSEN:
7019 		/* TODO */
7020 		sigma_dut_print(dut, DUT_MSG_ERROR, "EAP+OSEN not supported");
7021 		break;
7022 	case AP_SUITEB:
7023 		/* TODO */
7024 		sigma_dut_print(dut, DUT_MSG_ERROR, "SuiteB not supported");
7025 		break;
7026 	case AP_WPA2_OWE:
7027 		/* TODO */
7028 		sigma_dut_print(dut, DUT_MSG_ERROR, "OWE not supported");
7029 		break;
7030 	case AP_WPA2_FT_EAP:
7031 	case AP_WPA2_FT_PSK:
7032 	case AP_WPA2_EAP_SHA256:
7033 	case AP_WPA2_PSK_SHA256:
7034 	case AP_WPA2_ENT_FT_EAP:
7035 	case AP_OSEN:
7036 		/* TODO */
7037 		send_resp(dut, conn, SIGMA_ERROR,
7038 			  "errorCode,Unsupported KeyMgnt value");
7039 		return 0;
7040 	}
7041 
7042 	if (dut->ap_is_dual) {
7043 		/* ath1 settings in case of dual */
7044 		snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID_2=%s'",
7045 			 dut->ap_ssid);
7046 		run_system(dut, buf);
7047 
7048 		switch (dut->ap_key_mgmt) {
7049 		case AP_OPEN:
7050 			if (dut->ap_cipher == AP_WEP) {
7051 				run_system(dut, "cfg -a AP_SECMODE_2=WEP");
7052 				run_system(dut, "cfg -a AP_SECFILE_2=NONE");
7053 				/* shared auth mode not supported */
7054 				run_system(dut, "cfg -a AP_WEP_MODE_0=1");
7055 				run_system(dut, "cfg -a AP_WEP_MODE_1=1");
7056 				snprintf(buf, sizeof(buf),
7057 					 "cfg -a WEP_RADIO_NUM0_KEY_1=%s",
7058 					 dut->ap_wepkey);
7059 				run_system(dut, buf);
7060 				snprintf(buf, sizeof(buf),
7061 					 "cfg -a WEP_RADIO_NUM1_KEY_1=%s",
7062 					 dut->ap_wepkey);
7063 				run_system(dut, buf);
7064 			} else {
7065 				run_system(dut, "cfg -a AP_SECMODE_2=None");
7066 			}
7067 			break;
7068 		case AP_WPA2_PSK:
7069 		case AP_WPA2_PSK_MIXED:
7070 		case AP_WPA_PSK:
7071 		case AP_WPA2_SAE:
7072 		case AP_WPA2_PSK_SAE:
7073 			if (dut->ap_key_mgmt == AP_WPA2_PSK ||
7074 			    dut->ap_key_mgmt == AP_WPA2_SAE ||
7075 			    dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
7076 				run_system(dut, "cfg -a AP_WPA_2=2");
7077 			else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
7078 				run_system(dut, "cfg -a AP_WPA_2=3");
7079 			else
7080 				run_system(dut, "cfg -a AP_WPA_2=1");
7081 			// run_system(dut, "cfg -a AP_WPA_2=2");
7082 			/* TODO: SAE configuration */
7083 			run_system(dut, "cfg -a AP_SECMODE_2=WPA");
7084 			run_system(dut, "cfg -a AP_SECFILE_2=PSK");
7085 			res = snprintf(buf, sizeof(buf),
7086 				       "cfg -a 'PSK_KEY_2=%s'",
7087 				       dut->ap_passphrase);
7088 			if (res < 0 || res >= sizeof(buf))
7089 				return ERROR_SEND_STATUS;
7090 			run_system(dut, buf);
7091 			if (dut->ap_cipher == AP_CCMP_TKIP)
7092 				run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\"");
7093 			else if (dut->ap_cipher == AP_TKIP)
7094 				run_system(dut, "cfg -a AP_CYPHER_2=TKIP");
7095 			else
7096 				run_system(dut, "cfg -a AP_CYPHER_2=CCMP");
7097 			break;
7098 		case AP_WPA2_EAP:
7099 		case AP_WPA2_EAP_MIXED:
7100 		case AP_WPA_EAP:
7101 			if (dut->ap_key_mgmt == AP_WPA2_EAP)
7102 				run_system(dut, "cfg -a AP_WPA_2=2");
7103 			else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
7104 				run_system(dut, "cfg -a AP_WPA_2=3");
7105 			else
7106 				run_system(dut, "cfg -a AP_WPA_2=1");
7107 			run_system(dut, "cfg -a AP_SECMODE_2=WPA");
7108 			run_system(dut, "cfg -a AP_SECFILE_2=EAP");
7109 			if (dut->ap_cipher == AP_CCMP_TKIP)
7110 				run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\"");
7111 			else if (dut->ap_cipher == AP_TKIP)
7112 				run_system(dut, "cfg -a AP_CYPHER_2=TKIP");
7113 			else
7114 				run_system(dut, "cfg -a AP_CYPHER_2=CCMP");
7115 
7116 			snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER_2=%s",
7117 				 dut->ap_radius_ipaddr);
7118 			run_system(dut, buf);
7119 			snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT_2=%d",
7120 				 dut->ap_radius_port);
7121 			run_system(dut, buf);
7122 			res = snprintf(buf, sizeof(buf),
7123 				       "cfg -a AP_AUTH_SECRET_2=%s",
7124 				       dut->ap_radius_password);
7125 			if (res < 0 || res >= sizeof(buf))
7126 				return ERROR_SEND_STATUS;
7127 			run_system(dut, buf);
7128 			break;
7129 		case AP_WPA2_EAP_OSEN:
7130 			/* TODO */
7131 			sigma_dut_print(dut, DUT_MSG_ERROR,
7132 					"EAP+OSEN not supported");
7133 			break;
7134 		case AP_SUITEB:
7135 			/* TODO */
7136 			sigma_dut_print(dut, DUT_MSG_ERROR,
7137 					"SuiteB not supported");
7138 			break;
7139 		case AP_WPA2_OWE:
7140 			/* TODO */
7141 			sigma_dut_print(dut, DUT_MSG_ERROR,
7142 					"OWE not supported");
7143 			break;
7144 		case AP_WPA2_FT_EAP:
7145 		case AP_WPA2_FT_PSK:
7146 		case AP_WPA2_EAP_SHA256:
7147 		case AP_WPA2_PSK_SHA256:
7148 		case AP_WPA2_ENT_FT_EAP:
7149 		case AP_OSEN:
7150 			/* TODO */
7151 			send_resp(dut, conn, SIGMA_ERROR,
7152 				  "errorCode,Unsupported KeyMgnt value");
7153 			return 0;
7154 		}
7155 
7156 		/* wifi0 settings in case of dual */
7157 		run_system(dut, "cfg -a AP_RADIO_ID=0");
7158 		run_system(dut, "cfg -a AP_PRIMARY_CH=6");
7159 		run_system(dut, "cfg -a AP_STARTMODE=dual");
7160 		run_system(dut, "cfg -a AP_CHMODE=11NGHT40PLUS");
7161 		run_system(dut, "cfg -a TX_CHAINMASK=7");
7162 		run_system(dut, "cfg -a RX_CHAINMASK=7");
7163 	}
7164 
7165 	switch (dut->ap_pmf) {
7166 	case AP_PMF_DISABLED:
7167 		snprintf(buf, sizeof(buf), "cfg -a AP_PMF=0");
7168 		run_system(dut, buf);
7169 		break;
7170 	case AP_PMF_OPTIONAL:
7171 		snprintf(buf, sizeof(buf), "cfg -a AP_PMF=1");
7172 		run_system(dut, buf);
7173 		break;
7174 	case AP_PMF_REQUIRED:
7175 		snprintf(buf, sizeof(buf), "cfg -a AP_PMF=2");
7176 		run_system(dut, buf);
7177 		break;
7178 	}
7179 	if (dut->ap_add_sha256) {
7180 		snprintf(buf, sizeof(buf), "cfg -a AP_WPA_SHA256=1");
7181 		run_system(dut, buf);
7182 	} else {
7183 		snprintf(buf, sizeof(buf), "cfg -r AP_WPA_SHA256");
7184 		run_system(dut, buf);
7185 	}
7186 
7187 	if (dut->ap_hs2)
7188 		run_system(dut, "cfg -a AP_HOTSPOT=1");
7189 	else
7190 		run_system(dut, "cfg -r AP_HOTSPOT");
7191 
7192 	if (dut->ap_interworking) {
7193 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_ANT=%d",
7194 			 dut->ap_access_net_type);
7195 		run_system(dut, buf);
7196 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_INTERNET=%d",
7197 			 dut->ap_internet);
7198 		run_system(dut, buf);
7199 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUEGROUP=%d",
7200 			 dut->ap_venue_group);
7201 		run_system(dut, buf);
7202 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUETYPE=%d",
7203 			 dut->ap_venue_type);
7204 		run_system(dut, buf);
7205 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=%s",
7206 			 dut->ap_hessid);
7207 		run_system(dut, buf);
7208 
7209 		if (dut->ap_roaming_cons[0]) {
7210 			char *second, *rc;
7211 			rc = strdup(dut->ap_roaming_cons);
7212 			if (rc == NULL)
7213 				return 0;
7214 
7215 			second = strchr(rc, ';');
7216 			if (second)
7217 				*second++ = '\0';
7218 
7219 			snprintf(buf, sizeof(buf),
7220 				 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=%s", rc);
7221 			run_system(dut, buf);
7222 
7223 			if (second) {
7224 				snprintf(buf, sizeof(buf),
7225 					 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2"
7226 					 "=%s", second);
7227 				run_system(dut, buf);
7228 			}
7229 			free(rc);
7230 		} else {
7231 			run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM");
7232 			run_system(dut,
7233 				   "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2");
7234 		}
7235 	} else {
7236 		run_system(dut, "cfg -r AP_HOTSPOT_ANT");
7237 		run_system(dut, "cfg -r AP_HOTSPOT_INTERNET");
7238 		run_system(dut, "cfg -r AP_HOTSPOT_VENUEGROUP");
7239 		run_system(dut, "cfg -r AP_HOTSPOT_VENUETYPE");
7240 		run_system(dut, "cfg -r AP_HOTSPOT_HESSID");
7241 		run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM");
7242 		run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2");
7243 	}
7244 
7245 	if (dut->ap_proxy_arp)
7246 		run_system(dut, "cfg -a IEEE80211V_PROXYARP=1");
7247 	else
7248 		run_system(dut, "cfg -a IEEE80211V_PROXYARP=0");
7249 	if (dut->ap_dgaf_disable)
7250 		run_system(dut, "cfg -a AP_HOTSPOT_DISABLE_DGAF=1");
7251 	else
7252 		run_system(dut, "cfg -r AP_HOTSPOT_DISABLE_DGAF");
7253 
7254 	if (strlen(dut->ap_tag_ssid[0])) {
7255 		snprintf(buf, sizeof(buf),
7256 			 "cfg -a AP_SSID_2=%s", dut->ap_tag_ssid[0]);
7257 		run_system(dut, buf);
7258 
7259 		if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) {
7260 			run_system(dut, "cfg -a AP_SECMODE_2=WPA");
7261 			run_system(dut, "cfg -a AP_SECFILE_2=OSEN");
7262 
7263 			res = snprintf(buf, sizeof(buf),
7264 				       "cfg -a AP_AUTH_SERVER_2=%s",
7265 				       dut->ap2_radius_ipaddr);
7266 			if (res < 0 || res >= sizeof(buf))
7267 				return ERROR_SEND_STATUS;
7268 			run_system(dut, buf);
7269 
7270 			res = snprintf(buf, sizeof(buf),
7271 				       "cfg -a AP_AUTH_PORT_2=%d",
7272 				       dut->ap2_radius_port);
7273 			if (res < 0 || res >= sizeof(buf))
7274 				return ERROR_SEND_STATUS;
7275 			run_system(dut, buf);
7276 
7277 			res = snprintf(buf, sizeof(buf),
7278 				       "cfg -a AP_AUTH_SECRET_2=%s",
7279 				       dut->ap2_radius_password);
7280 			if (res < 0 || res >= sizeof(buf))
7281 				return ERROR_SEND_STATUS;
7282 			run_system(dut, buf);
7283 		} else {
7284 			run_system(dut, "cfg -a AP_SECMODE_2=None");
7285 			run_system(dut, "cfg -r AP_AUTH_SERVER_2");
7286 			run_system(dut, "cfg -r AP_AUTH_PORT_2");
7287 			run_system(dut, "cfg -r AP_AUTH_SECRET_2");
7288 		}
7289 
7290 		run_system(dut, "cfg -a AP_STARTMODE=multi");
7291 	}
7292 
7293 	run_system(dut, "cfg -c");
7294 
7295 	sigma_dut_print(dut, DUT_MSG_INFO, "Starting AP");
7296 	if (system("apup") != 0) {
7297 		/* to be debugged why apup returns error
7298 		send_resp(dut, conn, SIGMA_ERROR,
7299 			  "errorCode,apup failed");
7300 		return 0;
7301 		*/
7302 	}
7303 	sigma_dut_print(dut, DUT_MSG_INFO, "AP started");
7304 
7305 	if (dut->ap_key_mgmt != AP_OPEN) {
7306 		int res;
7307 		/* allow some time for hostapd to start before returning
7308 		 * success */
7309 		usleep(500000);
7310 		if (run_hostapd_cli(dut, "ping") != 0) {
7311 			send_resp(dut, conn, SIGMA_ERROR,
7312 				  "errorCode,Failed to talk to hostapd");
7313 			return 0;
7314 		}
7315 
7316 		if (dut->ap_hs2 && !dut->ap_anqpserver) {
7317 			/* the cfg app doesn't like ";" in the variables */
7318 			res = ath_ap_append_hostapd_conf(dut);
7319 			if (res < 0)
7320 				return res;
7321 
7322 			/* wait for hostapd to be ready */
7323 			usleep(500000);
7324 			if (run_hostapd_cli(dut, "ping") != 0) {
7325 				send_resp(dut, conn, SIGMA_ERROR,
7326 					  "errorCode,Failed to talk to "
7327 					  "hostapd");
7328 				return 0;
7329 			}
7330 		}
7331 	}
7332 
7333 	ath_ap_set_params(dut);
7334 
7335 	if (dut->ap_anqpserver)
7336 		return cmd_ath_ap_anqpserver_start(dut);
7337 
7338 	if (dut->ap2_proxy_arp)
7339 		run_iwpriv(dut, ifname, "proxy_arp 1");
7340 
7341 	if (dut->ap_allow_vht_wep || dut->ap_allow_vht_tkip)
7342 		run_iwpriv(dut, ifname, "htweptkip 1");
7343 
7344 	return 1;
7345 }
7346 
7347 
set_ebtables_proxy_arp(struct sigma_dut * dut,const char * chain,const char * ifname)7348 static int set_ebtables_proxy_arp(struct sigma_dut *dut, const char *chain,
7349 				  const char *ifname)
7350 {
7351 	char buf[200];
7352 
7353 	if (!chain || !ifname)
7354 		return -2;
7355 
7356 	snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain);
7357 	if (system(buf) != 0) {
7358 		sigma_dut_print(dut, DUT_MSG_ERROR,
7359 				"Failed to set ebtables rules, RULE-1, %s",
7360 				chain);
7361 		return -2;
7362 	}
7363 
7364 	snprintf(buf, sizeof(buf),
7365 		 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP",
7366 		 chain, ifname);
7367 	if (system(buf) != 0) {
7368 		sigma_dut_print(dut, DUT_MSG_ERROR,
7369 				"Failed to set ebtables rules, RULE-2, %s",
7370 				chain);
7371 		return -2;
7372 	}
7373 
7374 	snprintf(buf, sizeof(buf),
7375 		 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-solicitation -o %s -j DROP",
7376 		 chain, ifname);
7377 	if (system(buf) != 0) {
7378 		sigma_dut_print(dut, DUT_MSG_ERROR,
7379 				"Failed to set ebtables rules, RULE-3, %s",
7380 				chain);
7381 		return -2;
7382 	}
7383 
7384 	snprintf(buf, sizeof(buf),
7385 		 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-advertisement -o %s -j DROP",
7386 		 chain, ifname);
7387 	if (system(buf) != 0) {
7388 		sigma_dut_print(dut, DUT_MSG_ERROR,
7389 				"Failed to set ebtables rules, RULE-4, %s",
7390 				chain);
7391 		return -2;
7392 	}
7393 
7394 	return 0;
7395 }
7396 
7397 
set_ebtables_disable_dgaf(struct sigma_dut * dut,const char * chain,const char * ifname)7398 static int set_ebtables_disable_dgaf(struct sigma_dut *dut,
7399 				     const char *chain,
7400 				     const char *ifname)
7401 {
7402 	char buf[200];
7403 
7404 	if (!chain || !ifname)
7405 		return -2;
7406 
7407 	snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain);
7408 	if (system(buf) != 0) {
7409 		sigma_dut_print(dut, DUT_MSG_ERROR,
7410 				"Failed to set ebtables rules, RULE-5, %s",
7411 				chain);
7412 		return -2;
7413 	}
7414 
7415 	snprintf(buf, sizeof(buf),
7416 		 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP",
7417 		 chain, ifname);
7418 	if (system(buf) != 0) {
7419 		sigma_dut_print(dut, DUT_MSG_ERROR,
7420 				"Failed to set ebtables rules, RULE-6, %s",
7421 				chain);
7422 		return -2;
7423 	}
7424 
7425 	snprintf(buf, sizeof(buf),
7426 		 "ebtables -A %s -p IPv4 -d Multicast -o %s -j DROP",
7427 		 chain, ifname);
7428 	if (system(buf) != 0) {
7429 		sigma_dut_print(dut, DUT_MSG_ERROR,
7430 				"Failed to set ebtables rules, RULE-7, %s",
7431 				chain);
7432 		return -2;
7433 	}
7434 
7435 	snprintf(buf, sizeof(buf),
7436 		 "ebtables -A %s -p IPv6 -d Multicast -o %s -j DROP",
7437 		 chain, ifname);
7438 	if (system(buf) != 0) {
7439 		sigma_dut_print(dut, DUT_MSG_ERROR,
7440 				"Failed to set ebtables rules, RULE-8, %s",
7441 				chain);
7442 		return -2;
7443 	}
7444 
7445 	return 0;
7446 }
7447 
7448 
set_ebtables_forward_drop(struct sigma_dut * dut,const char * ifname,const char * ifname2)7449 static void set_ebtables_forward_drop(struct sigma_dut *dut,
7450 				      const char *ifname, const char *ifname2)
7451 {
7452 	char buf[128];
7453 
7454 	snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP",
7455 		 ifname, ifname2);
7456 	if (system(buf) != 0)
7457 		sigma_dut_print(dut, DUT_MSG_ERROR,
7458 				"Failed to set ebtables rule");
7459 
7460 	snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP",
7461 		 ifname2, ifname);
7462 	if (system(buf) != 0)
7463 		sigma_dut_print(dut, DUT_MSG_ERROR,
7464 				"Failed to set ebtables rule");
7465 }
7466 
7467 
check_channel(int channel)7468 static int check_channel(int channel)
7469 {
7470 	int channel_list[] = { 36, 40, 44, 48, 52, 60, 64, 100, 104, 108, 112,
7471 			       116, 120, 124, 128, 132, 140, 144, 149, 153, 157,
7472 			       161, 165 };
7473 	int num_chan = sizeof(channel_list) / sizeof(int);
7474 	int i;
7475 
7476 	for (i = 0; i < num_chan; i++) {
7477 		if (channel == channel_list[i])
7478 			return i;
7479 	}
7480 
7481 	return -1;
7482 }
7483 
7484 
get_oper_centr_freq_seq_idx(int chwidth,int channel)7485 static int get_oper_centr_freq_seq_idx(int chwidth, int channel)
7486 {
7487 	int ch_base;
7488 	int period;
7489 
7490 	if (check_channel(channel) < 0)
7491 		return -1;
7492 
7493 	if (channel >= 36 && channel <= 64)
7494 		ch_base = 36;
7495 	else if (channel >= 100 && channel <= 144)
7496 		ch_base = 100;
7497 	else
7498 		ch_base = 149;
7499 
7500 	period = channel % ch_base * 5 / chwidth;
7501 	return ch_base + period * chwidth / 5 + (chwidth - 20) / 10;
7502 }
7503 
7504 
is_ht40plus_chan(int chan)7505 static int is_ht40plus_chan(int chan)
7506 {
7507 	return chan == 36 || chan == 44 || chan == 52 || chan == 60 ||
7508 		chan == 100 || chan == 108 || chan == 116 || chan == 124 ||
7509 		chan == 132 || chan == 149 || chan == 157;
7510 }
7511 
7512 
is_ht40minus_chan(int chan)7513 static int is_ht40minus_chan(int chan)
7514 {
7515 	return chan == 40 || chan == 48 || chan == 56 || chan == 64 ||
7516 		chan == 104 || chan == 112 || chan == 120 || chan == 128 ||
7517 		chan == 136 || chan == 144 || chan == 153 || chan == 161;
7518 }
7519 
7520 
get_5g_channel_freq(int chan)7521 static int get_5g_channel_freq(int chan)
7522 {
7523 	return 5000 + chan * 5;
7524 }
7525 
7526 
hostapd_cipher_name(enum ap_cipher cipher)7527 static const char * hostapd_cipher_name(enum ap_cipher cipher)
7528 {
7529 	switch (cipher) {
7530 	case AP_CCMP:
7531 		return "CCMP";
7532 	case AP_TKIP:
7533 		return "TKIP";
7534 	case AP_CCMP_TKIP:
7535 		return "CCMP TKIP";
7536 	case AP_GCMP_256:
7537 		return "GCMP-256";
7538 	case AP_GCMP_128:
7539 		return "GCMP";
7540 	case AP_CCMP_256:
7541 		return "CCMP-256";
7542 	case AP_CCMP_128_GCMP_256:
7543 		return "CCMP GCMP-256";
7544 	default:
7545 		return "UNKNOWN";
7546 	}
7547 }
7548 
7549 
7550 static const char *
hostapd_group_mgmt_cipher_name(enum ap_group_mgmt_cipher cipher)7551 hostapd_group_mgmt_cipher_name(enum ap_group_mgmt_cipher cipher)
7552 {
7553 	switch (cipher) {
7554 	case AP_BIP_GMAC_256:
7555 		return "BIP-GMAC-256";
7556 	case AP_BIP_CMAC_256:
7557 		return "BIP-CMAC-256";
7558 	case AP_BIP_GMAC_128:
7559 		return "BIP-GMAC-128";
7560 	case AP_BIP_CMAC_128:
7561 		return "AES-128-CMAC";
7562 	default:
7563 		return "UNKNOWN";
7564 	}
7565 }
7566 
7567 
ap_set_60g_ese(struct sigma_dut * dut,int count,struct sigma_ese_alloc * allocs)7568 static int ap_set_60g_ese(struct sigma_dut *dut, int count,
7569 			  struct sigma_ese_alloc *allocs)
7570 {
7571 	switch (get_driver_type(dut)) {
7572 #ifdef __linux__
7573 	case DRIVER_WIL6210:
7574 		return wil6210_set_ese(dut, count, allocs);
7575 #endif /* __linux__ */
7576 	default:
7577 		sigma_dut_print(dut, DUT_MSG_ERROR,
7578 				"Unsupported ap_set_60g_ese with the current driver");
7579 		return -1;
7580 	}
7581 }
7582 
7583 
ap_set_force_mcs(struct sigma_dut * dut,int force,int mcs)7584 static int ap_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7585 {
7586 	switch (get_driver_type(dut)) {
7587 #ifdef __linux__
7588 	case DRIVER_WIL6210:
7589 		return wil6210_set_force_mcs(dut, force, mcs);
7590 #endif /* __linux__ */
7591 	default:
7592 		sigma_dut_print(dut, DUT_MSG_ERROR,
7593 				"Unsupported ap_set_force_mcs with the current driver");
7594 		return -1;
7595 	}
7596 }
7597 
7598 
write_hostapd_conf_password(struct sigma_dut * dut,FILE * f,int sae)7599 static int write_hostapd_conf_password(struct sigma_dut *dut, FILE *f, int sae)
7600 {
7601 	if (sae && dut->ap_sae_pk) {
7602 		if (!dut->ap_sae_pk_modifier) {
7603 			sigma_dut_print(dut, DUT_MSG_ERROR,
7604 					"SAE-PK modifier not configured");
7605 			return -1;
7606 		}
7607 		if (!dut->ap_sae_pk_keypair) {
7608 			sigma_dut_print(dut, DUT_MSG_ERROR,
7609 					"SAE-PK keypair not configured");
7610 			return -1;
7611 		}
7612 		if (dut->ap_sae_pk_keypair_sig)
7613 			fprintf(f, "sae_password=%s|pk=%s:%s:%s\n",
7614 				dut->ap_passphrase,
7615 				dut->ap_sae_pk_modifier,
7616 				dut->ap_sae_pk_keypair,
7617 				dut->ap_sae_pk_keypair_sig);
7618 		else
7619 			fprintf(f, "sae_password=%s|pk=%s:%s\n",
7620 				dut->ap_passphrase,
7621 				dut->ap_sae_pk_modifier,
7622 				dut->ap_sae_pk_keypair);
7623 	} else if (sae) {
7624 		fprintf(f, "sae_password=%s\n", dut->ap_passphrase);
7625 	} else if (!dut->ap_passphrase[0] && dut->ap_psk[0]) {
7626 		fprintf(f, "wpa_psk=%s", dut->ap_psk);
7627 	} else if (dut->ap_passphrase[0]) {
7628 		fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase);
7629 	}
7630 
7631 	return 0;
7632 }
7633 
7634 
fwtest_set_he_params(struct sigma_dut * dut,const char * ifname)7635 static void fwtest_set_he_params(struct sigma_dut *dut, const char *ifname)
7636 {
7637 	/* disable sending basic triggers */
7638 	fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 42 0", ifname);
7639 	/* disable MU BAR */
7640 	fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 64 1", ifname);
7641 	/* disable PSD Boost */
7642 	fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 142 1", ifname);
7643 	/* Enable mix bw */
7644 	fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 141 1", ifname);
7645 	/* Disable preferred AC */
7646 	fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 186 0", ifname);
7647 	/* enable full_band_probing */
7648 	fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 194 0", ifname);
7649 	/* enable the equal RU allocation */
7650 	fwtest_cmd_wrapper(dut, "-m 0x4b -v 0 0 1", ifname);
7651 
7652 	if (dut->ap_he_ulofdma == VALUE_ENABLED) {
7653 		/* Disable sounding for UL OFDMA */
7654 		fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 7 0", ifname);
7655 		/* Set random RU allocation */
7656 		fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 9 1", ifname);
7657 		/* To set TBTT PPDU duration (us) */
7658 		fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 63 1908", ifname);
7659 		/* disable enable_ul_ofdma_efficiency_check */
7660 		fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 131 0", ifname);
7661 	}
7662 
7663 	if (dut->ap_he_ppdu == PPDU_MU &&
7664 	    dut->ap_he_dlofdma == VALUE_ENABLED) {
7665 		/* Increase the min TX time limit for MU MIMO to
7666 		 * disable MU MIMO scheduling.
7667 		 */
7668 		fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 11 1000000", ifname);
7669 		/* Increase the max TX time limit for DL OFDMA
7670 		 * to enable OFDMA scheduling.
7671 		 */
7672 		fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 17 1000000", ifname);
7673 		/* Disable 'force SU schedule' to enable MU sch */
7674 		fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 8 0", ifname);
7675 		/* Enable MU 11ax support in sch algo */
7676 		fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 29 0", ifname);
7677 		/* Enable to sort RU allocation */
7678 		fwtest_cmd_wrapper(dut, "-m 0x4b -v 0 2 1", ifname);
7679 	}
7680 
7681 	if (dut->ap_txBF) {
7682 		/* Ignore TBTT for NDP */
7683 		fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 2 1", ifname);
7684 		/* cv query enable */
7685 		fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 7 1", ifname);
7686 		/* override TPC calculations & set TxBF flag to true */
7687 		fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 47 1", ifname);
7688 	}
7689 
7690 	if (dut->he_sounding == VALUE_ENABLED)
7691 		fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 7 0", ifname);
7692 }
7693 
7694 
7695 #define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895                    0x0
7696 #define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991                    0x1
7697 #define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454                   0x2
7698 #define IEEE80211_VHT_CAP_MAX_MPDU_MASK                           0x3
7699 #define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT        23
7700 #define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK         \
7701 	(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT)
7702 
find_ap_ampdu_exp_and_max_mpdu_len(struct sigma_dut * dut)7703 static void find_ap_ampdu_exp_and_max_mpdu_len(struct sigma_dut *dut)
7704 {
7705 
7706 #ifdef NL80211_SUPPORT
7707 	int ampdu_exp = 0;
7708 	int max_mpdu_len = 0;
7709 	u32 vht_caps = dut->hw_modes.vht_capab;
7710 
7711 	ampdu_exp = (vht_caps &
7712 		     IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
7713 		IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
7714 
7715 	if (ampdu_exp >= 0 && ampdu_exp <= 7)
7716 		dut->ap_ampdu_exp = ampdu_exp;
7717 
7718 	max_mpdu_len = vht_caps & IEEE80211_VHT_CAP_MAX_MPDU_MASK;
7719 
7720 	if (max_mpdu_len == IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454)
7721 		dut->ap_max_mpdu_len = 11454;
7722 	else if (max_mpdu_len == IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991)
7723 		dut->ap_max_mpdu_len = 7991;
7724 	else if (max_mpdu_len == IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895)
7725 		dut->ap_max_mpdu_len = 3895;
7726 #else /* NL80211_SUPPORT */
7727 	sigma_dut_print(dut, DUT_MSG_DEBUG,
7728 			"nl80211 is not supported to get A-MPDU parameters");
7729 #endif /* NL80211_SUPPORT */
7730 }
7731 
7732 
cmd_ap_config_commit(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)7733 enum sigma_cmd_result cmd_ap_config_commit(struct sigma_dut *dut,
7734 					   struct sigma_conn *conn,
7735 					   struct sigma_cmd *cmd)
7736 {
7737 	/* const char *name = get_param(cmd, "NAME"); */
7738 	FILE *f;
7739 	const char *ifname;
7740 	char buf[500];
7741 	char path[100];
7742 	char ap_conf_path[100];
7743 	enum driver_type drv;
7744 	const char *key_mgmt;
7745 #ifdef ANDROID
7746 	struct group *gr;
7747 #endif /* ANDROID */
7748 
7749 	drv = get_driver_type(dut);
7750 
7751 	if (dut->mode == SIGMA_MODE_STATION) {
7752 		stop_sta_mode(dut);
7753 		sleep(1);
7754 	}
7755 
7756 	if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) {
7757 		snprintf(buf, sizeof(buf), "ifconfig %s down",
7758 			 dut->sniffer_ifname);
7759 		if (system(buf) != 0) {
7760 			sigma_dut_print(dut, DUT_MSG_INFO,
7761 					"Failed to run '%s'", buf);
7762 		}
7763 		snprintf(buf, sizeof(buf), "iw dev %s set type station",
7764 			 dut->sniffer_ifname);
7765 		if (system(buf) != 0) {
7766 			sigma_dut_print(dut, DUT_MSG_INFO,
7767 					"Failed to run '%s'", buf);
7768 		}
7769 	}
7770 
7771 	dut->mode = SIGMA_MODE_AP;
7772 
7773 	if (drv == DRIVER_ATHEROS)
7774 		return cmd_ath_ap_config_commit(dut, conn, cmd);
7775 	if (drv == DRIVER_WCN)
7776 		return cmd_wcn_ap_config_commit(dut, conn, cmd);
7777 	if (drv == DRIVER_OPENWRT)
7778 		return cmd_owrt_ap_config_commit(dut, conn, cmd);
7779 
7780 	concat_sigma_tmpdir(dut, "/sigma_dut-ap.conf", ap_conf_path,
7781 			    sizeof(ap_conf_path));
7782 	f = fopen(ap_conf_path, "w");
7783 	if (f == NULL) {
7784 		sigma_dut_print(dut, DUT_MSG_ERROR,
7785 				"%s: Failed to open sigma_dut-ap.conf",
7786 				__func__);
7787 		return -2;
7788 	}
7789 
7790 	ifname = get_hostapd_ifname(dut);
7791 
7792 	switch (dut->ap_mode) {
7793 	case AP_11g:
7794 	case AP_11b:
7795 	case AP_11ng:
7796 		fprintf(f, "hw_mode=g\n");
7797 		break;
7798 	case AP_11a:
7799 	case AP_11na:
7800 	case AP_11ac:
7801 		fprintf(f, "hw_mode=a\n");
7802 		break;
7803 	case AP_11ad:
7804 		fprintf(f, "hw_mode=ad\n");
7805 		break;
7806 	case AP_11ax:
7807 		if (dut->use_5g)
7808 			fprintf(f, "hw_mode=a\n");
7809 		else
7810 			fprintf(f, "hw_mode=g\n");
7811 		break;
7812 	default:
7813 		fclose(f);
7814 		return -1;
7815 	}
7816 
7817 	if (drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN)
7818 		fprintf(f, "driver=nl80211\n");
7819 
7820 	if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7821 	     drv == DRIVER_LINUX_WCN) &&
7822 	    (dut->ap_mode == AP_11ng || dut->ap_mode == AP_11na ||
7823 	     (dut->ap_mode == AP_11ax && !dut->use_5g))) {
7824 		int ht40plus = 0, ht40minus = 0, tx_stbc = 0;
7825 
7826 		fprintf(f, "ieee80211n=1\n");
7827 		if (dut->ap_mode == AP_11ax)
7828 			fprintf(f, "ieee80211ax=1\n");
7829 		if (dut->ap_mode == AP_11ng &&
7830 		    (dut->ap_chwidth == AP_40 ||
7831 		     (dut->ap_chwidth == AP_AUTO &&
7832 		      dut->default_11ng_ap_chwidth == AP_40))) {
7833 			if (dut->ap_channel >= 1 && dut->ap_channel <= 7)
7834 				ht40plus = 1;
7835 			else if (dut->ap_channel >= 8 && dut->ap_channel <= 11)
7836 				ht40minus = 1;
7837 			fprintf(f, "obss_interval=300\n");
7838 		}
7839 
7840 		/* configure ht_capab based on channel width */
7841 		if (dut->ap_mode == AP_11na &&
7842 		    (dut->ap_chwidth == AP_40 ||
7843 		     (dut->ap_chwidth == AP_AUTO &&
7844 		      dut->default_11na_ap_chwidth == AP_40))) {
7845 			if (is_ht40plus_chan(dut->ap_channel))
7846 				ht40plus = 1;
7847 			else if (is_ht40minus_chan(dut->ap_channel))
7848 				ht40minus = 1;
7849 		}
7850 
7851 		if (dut->ap_tx_stbc)
7852 			tx_stbc = 1;
7853 
7854 		/* Overwrite the ht_capab with offset value if configured */
7855 		if (dut->ap_chwidth == AP_40 &&
7856 		    dut->ap_chwidth_offset == SEC_CH_40ABOVE) {
7857 			ht40plus = 1;
7858 			ht40minus = 0;
7859 		} else if (dut->ap_chwidth == AP_40 &&
7860 			   dut->ap_chwidth_offset == SEC_CH_40BELOW) {
7861 			ht40minus = 1;
7862 			ht40plus = 0;
7863 		}
7864 
7865 		fprintf(f, "ht_capab=%s%s%s\n",
7866 			ht40plus ? "[HT40+]" : "",
7867 			ht40minus ? "[HT40-]" : "",
7868 			tx_stbc ? "[TX-STBC]" : "");
7869 	}
7870 
7871 	if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7872 	     drv == DRIVER_LINUX_WCN) &&
7873 	    (dut->ap_mode == AP_11ac ||
7874 	    (dut->ap_mode == AP_11ax && dut->use_5g))) {
7875 		int ht40plus = 0, ht40minus = 0;
7876 
7877 		fprintf(f, "ieee80211ac=1\n"
7878 			"ieee80211n=1\n");
7879 		if (dut->ap_mode == AP_11ax)
7880 			fprintf(f, "ieee80211ax=1\n");
7881 
7882 		/* configure ht_capab based on channel width */
7883 		if (dut->ap_chwidth != AP_20) {
7884 			if (is_ht40plus_chan(dut->ap_channel))
7885 				ht40plus = 1;
7886 			else if (is_ht40minus_chan(dut->ap_channel))
7887 				ht40minus = 1;
7888 
7889 			fprintf(f, "ht_capab=%s%s\n",
7890 				ht40plus ? "[HT40+]" : "",
7891 				ht40minus ? "[HT40-]" : "");
7892 		}
7893 	}
7894 
7895 	if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7896 	     drv == DRIVER_LINUX_WCN) &&
7897 	    (dut->ap_mode == AP_11ac || dut->ap_mode == AP_11na)) {
7898 		if (dut->ap_countrycode[0]) {
7899 			fprintf(f, "country_code=%s\n", dut->ap_countrycode);
7900 			fprintf(f, "ieee80211d=1\n");
7901 			fprintf(f, "ieee80211h=1\n");
7902 		}
7903 	}
7904 
7905 	if (drv == DRIVER_LINUX_WCN && dut->ap_mode == AP_11ax) {
7906 		if (dut->ap_txBF) {
7907 			fprintf(f, "he_su_beamformer=1\n");
7908 			fprintf(f, "he_su_beamformee=1\n");
7909 			if (dut->ap_mu_txBF)
7910 				fprintf(f, "he_mu_beamformer=1\n");
7911 		} else {
7912 			fprintf(f, "he_su_beamformer=0\n");
7913 			fprintf(f, "he_su_beamformee=0\n");
7914 			fprintf(f, "he_mu_beamformer=0\n");
7915 		}
7916 	}
7917 
7918 	fprintf(f, "interface=%s\n", ifname);
7919 	if (dut->bridge)
7920 		fprintf(f, "bridge=%s\n", dut->bridge);
7921 	fprintf(f, "channel=%d\n", dut->ap_channel);
7922 
7923 	if (sigma_hapd_ctrl)
7924 		fprintf(f, "ctrl_interface=%s\n", sigma_hapd_ctrl);
7925 	else
7926 		fprintf(f, "ctrl_interface=/var/run/hostapd\n");
7927 
7928 	if (dut->ap_ssid[0])
7929 		fprintf(f, "ssid=%s\n", dut->ap_ssid);
7930 	else
7931 		fprintf(f, "ssid=QCA AP OOB\n");
7932 	if (dut->ap_bcnint)
7933 		fprintf(f, "beacon_int=%d\n", dut->ap_bcnint);
7934 	if (dut->ap_start_disabled)
7935 		fprintf(f, "start_disabled=1\n");
7936 
7937 	if (dut->ap_akm_values) {
7938 		struct {
7939 			int akm;
7940 			const char *str;
7941 		} akms[] = {
7942 			{ AKM_WPA_EAP, "WPA-EAP" },
7943 			{ AKM_WPA_PSK, "WPA-PSK" },
7944 			{ AKM_FT_EAP, "FT-EAP" },
7945 			{ AKM_FT_PSK, "FT-PSK" },
7946 			{ AKM_EAP_SHA256, "WPA-EAP-SHA256" },
7947 			{ AKM_PSK_SHA256, "WPA-PSK-SHA256" },
7948 			{ AKM_SAE, "SAE" },
7949 			{ AKM_FT_SAE, "FT-SAE" },
7950 			{ AKM_SUITE_B, "WPA-EAP-SUITE-B-192" },
7951 			{ AKM_FT_SUITE_B, "FT-EAP-SHA384" },
7952 			{ AKM_FILS_SHA256, "FILS-SHA256" },
7953 			{ AKM_FILS_SHA384, "FILS-SHA384" },
7954 			{ AKM_FT_FILS_SHA256, "FT-FILS-SHA256" },
7955 			{ AKM_FT_FILS_SHA384, "FT-FILS-SHA384" },
7956 		};
7957 		int first = 1;
7958 		unsigned int i;
7959 
7960 		fprintf(f, "wpa_key_mgmt=");
7961 		for (i = 0; i < ARRAY_SIZE(akms); i++) {
7962 			if (dut->ap_akm_values & (1 << akms[i].akm)) {
7963 				fprintf(f, "%s%s", first ? "" : " ",
7964 					akms[i].str);
7965 				first = 0;
7966 			}
7967 		}
7968 		fprintf(f, "\n");
7969 		/* TODO: mixed mode and WPAv1 only */
7970 		fprintf(f, "wpa=2\n");
7971 		fprintf(f, "wpa_pairwise=%s\n",
7972 			hostapd_cipher_name(dut->ap_cipher));
7973 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7974 			fprintf(f, "group_cipher=%s\n",
7975 				hostapd_cipher_name(dut->ap_group_cipher));
7976 		if (write_hostapd_conf_password(
7977 			    dut, f,
7978 			    (dut->ap_akm_values &
7979 			     ((1 << AKM_SAE) | (1 << AKM_FT_SAE))) &&
7980 			    !(dut->ap_akm_values &
7981 			      ((1 << AKM_WPA_PSK) | (1 << AKM_FT_PSK))) &&
7982 			    dut->ap_passphrase[0]) < 0) {
7983 			fclose(f);
7984 			return ERROR_SEND_STATUS;
7985 		}
7986 		if (dut->ap_akm_values & ((1 << AKM_WPA_EAP) |
7987 					  (1 << AKM_FT_EAP) |
7988 					  (1 << AKM_EAP_SHA256) |
7989 					  (1 << AKM_SUITE_B) |
7990 					  (1 << AKM_FT_SUITE_B) |
7991 					  (1 << AKM_FILS_SHA256) |
7992 					  (1 << AKM_FILS_SHA384) |
7993 					  (1 << AKM_FT_FILS_SHA256) |
7994 					  (1 << AKM_FT_FILS_SHA384))) {
7995 			fprintf(f, "ieee8021x=1\n");
7996 			fprintf(f, "auth_server_addr=%s\n",
7997 				dut->ap_radius_ipaddr);
7998 			if (dut->ap_radius_port)
7999 				fprintf(f, "auth_server_port=%d\n",
8000 					dut->ap_radius_port);
8001 			fprintf(f, "auth_server_shared_secret=%s\n",
8002 				dut->ap_radius_password);
8003 		}
8004 		goto skip_key_mgmt;
8005 	}
8006 
8007 	switch (dut->ap_key_mgmt) {
8008 	case AP_OPEN:
8009 		if (dut->ap_cipher == AP_WEP)
8010 			fprintf(f, "wep_key0=%s\n", dut->ap_wepkey);
8011 		break;
8012 	case AP_WPA2_PSK:
8013 	case AP_WPA2_PSK_MIXED:
8014 	case AP_WPA_PSK:
8015 	case AP_WPA2_SAE:
8016 	case AP_WPA2_PSK_SAE:
8017 	case AP_WPA2_PSK_SHA256:
8018 	case AP_WPA2_FT_PSK:
8019 		if (dut->ap_key_mgmt == AP_WPA2_PSK ||
8020 		    dut->ap_key_mgmt == AP_WPA2_SAE ||
8021 		    dut->ap_key_mgmt == AP_WPA2_PSK_SAE ||
8022 		    dut->ap_key_mgmt == AP_WPA2_PSK_SHA256 ||
8023 		    dut->ap_key_mgmt == AP_WPA2_FT_PSK)
8024 			fprintf(f, "wpa=2\n");
8025 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
8026 			fprintf(f, "wpa=3\n");
8027 		else
8028 			fprintf(f, "wpa=1\n");
8029 		if (dut->ap_key_mgmt == AP_WPA2_SAE)
8030 			key_mgmt = "SAE";
8031 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
8032 			key_mgmt = "WPA-PSK SAE";
8033 		else
8034 			key_mgmt = "WPA-PSK";
8035 		switch (dut->ap_pmf) {
8036 		case AP_PMF_DISABLED:
8037 			fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt,
8038 				dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
8039 			break;
8040 		case AP_PMF_OPTIONAL:
8041 			fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt,
8042 				dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
8043 			break;
8044 		case AP_PMF_REQUIRED:
8045 			if (dut->ap_key_mgmt == AP_WPA2_SAE)
8046 				key_mgmt = "SAE";
8047 			else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
8048 				key_mgmt = "WPA-PSK-SHA256 SAE";
8049 			else
8050 				key_mgmt = "WPA-PSK-SHA256";
8051 			fprintf(f, "wpa_key_mgmt=%s\n", key_mgmt);
8052 			break;
8053 		}
8054 		if (dut->ap_key_mgmt == AP_WPA2_PSK_SHA256)
8055 			fprintf(f, "wpa_key_mgmt=WPA-PSK-SHA256\n");
8056 		else if (dut->ap_key_mgmt == AP_WPA2_FT_PSK)
8057 			fprintf(f, "wpa_key_mgmt=FT-PSK\n");
8058 		fprintf(f, "wpa_pairwise=%s\n",
8059 			hostapd_cipher_name(dut->ap_cipher));
8060 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
8061 			fprintf(f, "group_cipher=%s\n",
8062 				hostapd_cipher_name(dut->ap_group_cipher));
8063 		if (write_hostapd_conf_password(
8064 			    dut, f, dut->ap_key_mgmt == AP_WPA2_SAE) < 0) {
8065 			fclose(f);
8066 			return ERROR_SEND_STATUS;
8067 		}
8068 		break;
8069 	case AP_WPA2_EAP:
8070 	case AP_WPA2_EAP_MIXED:
8071 	case AP_WPA_EAP:
8072 	case AP_WPA2_EAP_OSEN:
8073 	case AP_WPA2_EAP_SHA256:
8074 	case AP_WPA2_FT_EAP:
8075 	case AP_WPA2_ENT_FT_EAP:
8076 		fprintf(f, "ieee8021x=1\n");
8077 		if (dut->ap_key_mgmt == AP_WPA2_EAP ||
8078 		    dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ||
8079 		    dut->ap_key_mgmt == AP_WPA2_EAP_SHA256 ||
8080 		    dut->ap_key_mgmt == AP_WPA2_FT_EAP ||
8081 		    dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP)
8082 			fprintf(f, "wpa=2\n");
8083 		else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
8084 			fprintf(f, "wpa=3\n");
8085 		else
8086 			fprintf(f, "wpa=1\n");
8087 		switch (dut->ap_pmf) {
8088 		case AP_PMF_DISABLED:
8089 			fprintf(f, "wpa_key_mgmt=WPA-EAP%s\n",
8090 				dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "");
8091 			break;
8092 		case AP_PMF_OPTIONAL:
8093 			fprintf(f, "wpa_key_mgmt=WPA-EAP%s%s\n",
8094 				dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "",
8095 				dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" :
8096 				"");
8097 			break;
8098 		case AP_PMF_REQUIRED:
8099 			fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256%s\n",
8100 				dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" :
8101 				"");
8102 			break;
8103 		}
8104 		if (dut->ap_key_mgmt == AP_WPA2_EAP_SHA256)
8105 			fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256\n");
8106 		else if (dut->ap_key_mgmt == AP_WPA2_FT_EAP)
8107 			fprintf(f, "wpa_key_mgmt=FT-EAP\n");
8108 		else if (dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP)
8109 			fprintf(f, "wpa_key_mgmt=FT-EAP WPA-EAP\n");
8110 		fprintf(f, "wpa_pairwise=%s\n",
8111 			hostapd_cipher_name(dut->ap_cipher));
8112 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
8113 			fprintf(f, "group_cipher=%s\n",
8114 				hostapd_cipher_name(dut->ap_group_cipher));
8115 		fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
8116 		if (dut->ap_radius_port)
8117 			fprintf(f, "auth_server_port=%d\n",
8118 				dut->ap_radius_port);
8119 		fprintf(f, "auth_server_shared_secret=%s\n",
8120 			dut->ap_radius_password);
8121 		if (dut->program == PROGRAM_HS2_R3) {
8122 			fprintf(f, "radius_das_port=3799\n");
8123 			fprintf(f, "radius_das_client=0.0.0.0 %s\n",
8124 				dut->ap_radius_password);
8125 			fprintf(f, "radius_das_require_event_timestamp=1\n");
8126 		}
8127 		break;
8128 	case AP_SUITEB:
8129 		fprintf(f, "ieee8021x=1\n");
8130 		fprintf(f, "wpa=2\n");
8131 		fprintf(f, "wpa_key_mgmt=WPA-EAP-SUITE-B-192\n");
8132 		fprintf(f, "wpa_pairwise=%s\n",
8133 			hostapd_cipher_name(dut->ap_cipher));
8134 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
8135 			fprintf(f, "group_cipher=%s\n",
8136 				hostapd_cipher_name(dut->ap_group_cipher));
8137 		if (dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET)
8138 			fprintf(f, "group_mgmt_cipher=%s\n",
8139 				hostapd_group_mgmt_cipher_name(
8140 					dut->ap_group_mgmt_cipher));
8141 		fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
8142 		if (dut->ap_radius_port)
8143 			fprintf(f, "auth_server_port=%d\n",
8144 				dut->ap_radius_port);
8145 		fprintf(f, "auth_server_shared_secret=%s\n",
8146 			dut->ap_radius_password);
8147 		break;
8148 	case AP_WPA2_OWE:
8149 		fprintf(f, "wpa=2\n");
8150 		fprintf(f, "wpa_key_mgmt=OWE\n");
8151 		fprintf(f, "rsn_pairwise=%s\n",
8152 			hostapd_cipher_name(dut->ap_cipher));
8153 		if (dut->ap_sae_groups)
8154 			fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups);
8155 		if (dut->owe_ptk_workaround)
8156 			fprintf(f, "owe_ptk_workaround=1\n");
8157 		break;
8158 	case AP_OSEN:
8159 		fprintf(f, "osen=1\n");
8160 		fprintf(f, "disable_dgaf=1\n");
8161 		fprintf(f, "wpa_pairwise=%s\n",
8162 			hostapd_cipher_name(dut->ap_cipher));
8163 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
8164 			fprintf(f, "group_cipher=%s\n",
8165 				hostapd_cipher_name(dut->ap_group_cipher));
8166 		fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
8167 		if (dut->ap_radius_port)
8168 			fprintf(f, "auth_server_port=%d\n",
8169 				dut->ap_radius_port);
8170 		fprintf(f, "auth_server_shared_secret=%s\n",
8171 			dut->ap_radius_password);
8172 		break;
8173 	}
8174 skip_key_mgmt:
8175 
8176 	if (dut->ap_sae_passwords) {
8177 		char *tmp, *pos, *end, *id;
8178 
8179 		tmp = strdup(dut->ap_sae_passwords);
8180 		if (!tmp) {
8181 			fclose(f);
8182 			return ERROR_SEND_STATUS;
8183 		}
8184 
8185 		pos = tmp;
8186 		while (*pos) {
8187 			end = strchr(pos, ';');
8188 			if (end)
8189 				*end = '\0';
8190 			id = strchr(pos, ':');
8191 			if (id)
8192 				*id++ = '\0';
8193 
8194 			fprintf(f, "sae_password=%s%s%s\n",
8195 				pos, id ? "|id=" : "", id ? id : "");
8196 			if (!end)
8197 				break;
8198 			pos = end + 1;
8199 		}
8200 
8201 		free(tmp);
8202 	}
8203 
8204 	if (dut->ap_rsn_preauth)
8205 		fprintf(f, "rsn_preauth=1\n");
8206 
8207 	if (dut->ap_pmksa && dut->ap_pmksa_caching)
8208 		fprintf(f, "disable_pmksa_caching=1\n");
8209 
8210 	if (dut->ap_beacon_prot)
8211 		fprintf(f, "beacon_prot=1\n");
8212 
8213 	if (dut->ap_transition_disable)
8214 		fprintf(f, "transition_disable=0x%02x\n",
8215 			dut->ap_transition_disable);
8216 
8217 	if (dut->ap_ocvc == 1 || dut->ap_ocvc == 0)
8218 		fprintf(f, "ocv=%d\n", dut->ap_ocvc);
8219 
8220 	switch (dut->ap_pmf) {
8221 	case AP_PMF_DISABLED:
8222 		break;
8223 	case AP_PMF_OPTIONAL:
8224 		fprintf(f, "ieee80211w=1\n");
8225 		if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE ||
8226 		    (dut->ap_akm_values & (AKM_SAE | AKM_WPA_PSK)) ==
8227 		    (AKM_SAE | AKM_WPA_PSK))
8228 			fprintf(f, "sae_require_mfp=1\n");
8229 		break;
8230 	case AP_PMF_REQUIRED:
8231 		fprintf(f, "ieee80211w=2\n");
8232 		break;
8233 	}
8234 
8235 	if (dut->ap_pmf != AP_PMF_DISABLED &&
8236 	    dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET)
8237 		fprintf(f, "group_mgmt_cipher=%s\n",
8238 			hostapd_group_mgmt_cipher_name(
8239 				dut->ap_group_mgmt_cipher));
8240 
8241 	if (ap_ft_enabled(dut)) {
8242 		unsigned char own_addr[ETH_ALEN];
8243 
8244 		fprintf(f, "mobility_domain=%s\n", dut->ap_mobility_domain);
8245 		fprintf(f, "ft_over_ds=%d\n", dut->ap_ft_ds == VALUE_ENABLED);
8246 		if (get_hwaddr(ifname, own_addr) < 0) {
8247 			memset(own_addr, 0, ETH_ALEN);
8248 			own_addr[0] = 0x02;
8249 		}
8250 		fprintf(f,
8251 			"nas_identifier=%02x%02x%02x%02x%02x%02x.nas.example.com\n",
8252 			own_addr[0], own_addr[1], own_addr[2],
8253 			own_addr[3], own_addr[4], own_addr[5]);
8254 		fprintf(f, "r1_key_holder=%02x%02x%02x%02x%02x%02x\n",
8255 			own_addr[0], own_addr[1], own_addr[2],
8256 			own_addr[3], own_addr[4], own_addr[5]);
8257 		fprintf(f, "ft_psk_generate_local=1\n");
8258 		fprintf(f, "pmk_r1_push=0\n");
8259 		fprintf(f,
8260 			"r0kh=ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n");
8261 		fprintf(f,
8262 			"r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n");
8263 	}
8264 
8265 	if (dut->rsne_override)
8266 		fprintf(f, "own_ie_override=%s\n", dut->rsne_override);
8267 	if (dut->rsnxe_override_eapol)
8268 		fprintf(f, "rsnxe_override_eapol=%s\n",
8269 			dut->rsnxe_override_eapol);
8270 
8271 	if (dut->sae_commit_override)
8272 		fprintf(f, "sae_commit_override=%s\n",
8273 			dut->sae_commit_override);
8274 
8275 	if (dut->ap_sae_groups)
8276 		fprintf(f, "sae_groups=%s\n", dut->ap_sae_groups);
8277 
8278 	if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) {
8279 		const char *sae_pwe = NULL;
8280 
8281 		if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut))
8282 			sae_pwe = "3";
8283 		else if (dut->sae_pwe == SAE_PWE_LOOP)
8284 			sae_pwe = "0";
8285 		else if (dut->sae_pwe == SAE_PWE_H2E)
8286 			sae_pwe = "1";
8287 		else if (dut->sae_h2e_default)
8288 			sae_pwe = "2";
8289 		if (sae_pwe)
8290 			fprintf(f, "sae_pwe=%s\n", sae_pwe);
8291 	}
8292 
8293 	if (dut->sae_anti_clogging_threshold >= 0)
8294 		fprintf(f, "sae_anti_clogging_threshold=%d\n",
8295 			dut->sae_anti_clogging_threshold);
8296 	if (dut->sae_reflection)
8297 		fprintf(f, "sae_reflection_attack=1\n");
8298 	if (dut->ap_sae_commit_status >= 0)
8299 		fprintf(f, "sae_commit_status=%d\n", dut->ap_sae_commit_status);
8300 	if (dut->ap_sae_pk_omit)
8301 		fprintf(f, "sae_pk_omit=1\n");
8302 	if (dut->sae_confirm_immediate)
8303 		fprintf(f, "sae_confirm_immediate=2\n");
8304 
8305 	if (dut->ap_p2p_mgmt)
8306 		fprintf(f, "manage_p2p=1\n");
8307 
8308 	if (dut->ap_tdls_prohibit || dut->ap_l2tif)
8309 		fprintf(f, "tdls_prohibit=1\n");
8310 	if (dut->ap_tdls_prohibit_chswitch || dut->ap_l2tif)
8311 		fprintf(f, "tdls_prohibit_chan_switch=1\n");
8312 	if (dut->ap_p2p_cross_connect >= 0) {
8313 		fprintf(f, "manage_p2p=1\n"
8314 			"allow_cross_connection=%d\n",
8315 			dut->ap_p2p_cross_connect);
8316 	}
8317 
8318 	if (dut->ap_l2tif || dut->ap_proxy_arp ||
8319 	    dut->ap_key_mgmt == AP_WPA2_EAP_OSEN) {
8320 		if (!dut->bridge) {
8321 			sigma_dut_print(dut, DUT_MSG_ERROR,
8322 					"Bridge must be configured. Run with -b <brname>.");
8323 			fclose(f);
8324 			return -2;
8325 		}
8326 		fprintf(f, "ap_isolate=1\n");
8327 	}
8328 
8329 	if (dut->ap_proxy_arp)
8330 		fprintf(f, "proxy_arp=1\n");
8331 
8332 	if (dut->ap_wme)
8333 		fprintf(f, "wmm_enabled=1\n");
8334 
8335 	if (dut->ap_wmmps == AP_WMMPS_ON)
8336 		fprintf(f, "uapsd_advertisement_enabled=1\n");
8337 
8338 	if (dut->ap_hs2) {
8339 		if (dut->ap_bss_load) {
8340 			char *bss_load;
8341 
8342 			switch (dut->ap_bss_load) {
8343 			case -1:
8344 				bss_load = "bss_load_update_period=10";
8345 				break;
8346 			case 1:
8347 				/* STA count: 1, CU: 50, AAC: 65535 */
8348 				bss_load = "bss_load_test=1:50:65535";
8349 				break;
8350 			case 2:
8351 				/* STA count: 1, CU: 200, AAC: 65535 */
8352 				bss_load = "bss_load_test=1:200:65535";
8353 				break;
8354 			case 3:
8355 				/* STA count: 1, CU: 75, AAC: 65535 */
8356 				bss_load = "bss_load_test=1:75:65535";
8357 				break;
8358 			default:
8359 				bss_load = NULL;
8360 				break;
8361 			}
8362 
8363 			if (!bss_load) {
8364 				fclose(f);
8365 				return -2;
8366 			}
8367 			fprintf(f, "%s\n", bss_load);
8368 		}
8369 
8370 		if (append_hostapd_conf_hs2(dut, f)) {
8371 			fclose(f);
8372 			return -2;
8373 		}
8374 	}
8375 
8376 	if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) {
8377 		fclose(f);
8378 		return -2;
8379 	}
8380 
8381 	if (dut->ap_hs2 && strlen(dut->ap_tag_ssid[0])) {
8382 		unsigned char bssid[6];
8383 		char ifname2[50];
8384 
8385 		if (get_hwaddr(ifname, bssid)) {
8386 			fclose(f);
8387 			return -2;
8388 		}
8389 		if (bssid[0] & 0x02)
8390 			bssid[5] ^= 0x01;
8391 		else
8392 			bssid[0] |= 0x02;
8393 
8394 		snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8395 		fprintf(f, "bss=%s\n", ifname2);
8396 		fprintf(f, "ssid=%s\n", dut->ap_tag_ssid[0]);
8397 		if (dut->bridge)
8398 			fprintf(f, "bridge=%s\n", dut->bridge);
8399 
8400 		if (drv == DRIVER_LINUX_WCN)
8401 			fprintf(f, "use_driver_iface_addr=1\n");
8402 		else
8403 			fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8404 				bssid[0], bssid[1], bssid[2], bssid[3],
8405 				bssid[4], bssid[5]);
8406 
8407 		if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) {
8408 			fprintf(f, "osen=1\n");
8409 			/* Disable DGAF for OSEN BSS */
8410 			fprintf(f, "disable_dgaf=1\n");
8411 			fprintf(f, "ap_isolate=1\n");
8412 			if (strlen(dut->ap2_radius_ipaddr))
8413 				fprintf(f, "auth_server_addr=%s\n",
8414 					dut->ap2_radius_ipaddr);
8415 			if (dut->ap2_radius_port)
8416 				fprintf(f, "auth_server_port=%d\n",
8417 					dut->ap2_radius_port);
8418 			if (strlen(dut->ap2_radius_password))
8419 				fprintf(f, "auth_server_shared_secret=%s\n",
8420 					dut->ap2_radius_password);
8421 
8422 			set_ebtables_forward_drop(dut, ifname, ifname2);
8423 		} else if (dut->ap2_osu) {
8424 			fprintf(f, "ap_isolate=1\n");
8425 			set_ebtables_forward_drop(dut, ifname, ifname2);
8426 		}
8427 
8428 		if (dut->ap2_proxy_arp) {
8429 			if (!dut->bridge) {
8430 				sigma_dut_print(dut, DUT_MSG_ERROR,
8431 						"Bridge must be configured. Run with -b <brname>.");
8432 				fclose(f);
8433 				return -2;
8434 			}
8435 			fprintf(f, "ap_isolate=1\n");
8436 			fprintf(f, "proxy_arp=1\n");
8437 
8438 			if (set_ebtables_proxy_arp(dut, "FORWARD", ifname2) ||
8439 			    set_ebtables_proxy_arp(dut, "OUTPUT", ifname2)) {
8440 				fclose(f);
8441 				return -2;
8442 			}
8443 
8444 		}
8445 	}
8446 
8447 	if (dut->program == PROGRAM_WPS) {
8448 		/* 60G WPS tests requires wps_state of 2 (configured) */
8449 		int wps_state = is_60g_sigma_dut(dut) ? 2 : 1;
8450 
8451 		fprintf(f, "eap_server=1\n"
8452 			"wps_state=%d\n"
8453 			"device_name=QCA AP\n"
8454 			"manufacturer=QCA\n"
8455 			"device_type=6-0050F204-1\n"
8456 			"config_methods=label virtual_display %s"
8457 			"virtual_push_button keypad%s\n"
8458 			"ap_pin=12345670\n"
8459 			"friendly_name=QCA Access Point\n"
8460 			"upnp_iface=%s\n",
8461 			wps_state,
8462 			is_60g_sigma_dut(dut) ? "physical_display " : "",
8463 			dut->ap_wpsnfc ? " nfc_interface ext_nfc_token" : "",
8464 			dut->bridge ? dut->bridge : ifname);
8465 		if (dut->wsc_fragment) {
8466 			fprintf(f, "device_name=%s\n"
8467 				"manufacturer=%s\n"
8468 				"model_name=%s\n"
8469 				"model_number=%s\n"
8470 				"serial_number=%s\n",
8471 				WPS_LONG_DEVICE_NAME,
8472 				WPS_LONG_MANUFACTURER,
8473 				WPS_LONG_MODEL_NAME,
8474 				WPS_LONG_MODEL_NUMBER,
8475 				WPS_LONG_SERIAL_NUMBER);
8476 		} else {
8477 			fprintf(f, "device_name=QCA AP\n"
8478 				"manufacturer=QCA\n");
8479 		}
8480 		if (dut->eap_fragment)
8481 			fprintf(f, "fragment_size=128\n");
8482 	}
8483 
8484 	if (dut->ap_dpp_conf_addr && dut->ap_dpp_conf_pkhash)
8485 		fprintf(f, "dpp_controller=ipaddr=%s pkhash=%s\n",
8486 			dut->ap_dpp_conf_addr, dut->ap_dpp_conf_pkhash);
8487 
8488 	if (dut->ap_he_rtsthrshld == VALUE_ENABLED)
8489 		fprintf(f, "he_rts_threshold=512\n");
8490 	else if (dut->ap_he_rtsthrshld == VALUE_DISABLED)
8491 		fprintf(f, "he_rts_threshold=1024\n");
8492 
8493 	if ((dut->program == PROGRAM_VHT) ||
8494 	    (dut->program == PROGRAM_HE && dut->use_5g)) {
8495 		int vht_oper_centr_freq_idx;
8496 
8497 		if (check_channel(dut->ap_channel) < 0) {
8498 			send_resp(dut, conn, SIGMA_INVALID,
8499 				  "errorCode,Invalid channel");
8500 			fclose(f);
8501 			return 0;
8502 		}
8503 
8504 		switch (dut->ap_chwidth) {
8505 		case AP_20:
8506 			dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH;
8507 			vht_oper_centr_freq_idx =
8508 				get_oper_centr_freq_seq_idx(20,
8509 							    dut->ap_channel);
8510 			break;
8511 		case AP_40:
8512 			dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH;
8513 			vht_oper_centr_freq_idx =
8514 				get_oper_centr_freq_seq_idx(40,
8515 							    dut->ap_channel);
8516 			break;
8517 		case AP_80:
8518 			dut->ap_vht_chwidth = AP_80_VHT_OPER_CHWIDTH;
8519 			vht_oper_centr_freq_idx =
8520 				get_oper_centr_freq_seq_idx(80,
8521 							    dut->ap_channel);
8522 			break;
8523 		case AP_160:
8524 			dut->ap_vht_chwidth = AP_160_VHT_OPER_CHWIDTH;
8525 			vht_oper_centr_freq_idx =
8526 				get_oper_centr_freq_seq_idx(160,
8527 							    dut->ap_channel);
8528 			break;
8529 		default:
8530 			dut->ap_vht_chwidth = VHT_DEFAULT_OPER_CHWIDTH;
8531 			vht_oper_centr_freq_idx =
8532 				get_oper_centr_freq_seq_idx(80,
8533 							    dut->ap_channel);
8534 			break;
8535 		}
8536 		fprintf(f, "vht_oper_centr_freq_seg0_idx=%d\n",
8537 			vht_oper_centr_freq_idx);
8538 		fprintf(f, "vht_oper_chwidth=%d\n", dut->ap_vht_chwidth);
8539 		if (dut->ap_mode == AP_11ax) {
8540 			fprintf(f, "he_oper_chwidth=%d\n", dut->ap_vht_chwidth);
8541 			fprintf(f, "he_oper_centr_freq_seg0_idx=%d\n",
8542 				vht_oper_centr_freq_idx);
8543 		}
8544 
8545 		find_ap_ampdu_exp_and_max_mpdu_len(dut);
8546 
8547 		if (dut->ap_sgi80 || dut->ap_txBF ||
8548 		    dut->ap_ldpc != VALUE_NOT_SET ||
8549 		    dut->ap_tx_stbc || dut->ap_mu_txBF ||
8550 		    dut->ap_ampdu_exp || dut->ap_max_mpdu_len ||
8551 		    dut->ap_chwidth == AP_160 || dut->ap_chwidth == AP_80_80) {
8552 			fprintf(f, "vht_capab=%s%s%s%s%s%s",
8553 				dut->ap_sgi80 ? "[SHORT-GI-80]" : "",
8554 				dut->ap_txBF ?
8555 				"[SU-BEAMFORMER][SU-BEAMFORMEE][BF-ANTENNA-2][SOUNDING-DIMENSION-2]" : "",
8556 				(dut->ap_ldpc == VALUE_ENABLED) ?
8557 				"[RXLDPC]" : "",
8558 				dut->ap_tx_stbc ? "[TX-STBC-2BY1]" : "",
8559 				dut->ap_mu_txBF ? "[MU-BEAMFORMER]" : "",
8560 				dut->ap_chwidth == AP_160 ? "[VHT160]" :
8561 				(dut->ap_chwidth == AP_80_80 ?
8562 				 "[VHT160-80PLUS80]" : ""));
8563 
8564 			if (dut->ap_ampdu_exp)
8565 				fprintf(f, "[MAX-A-MPDU-LEN-EXP%d]",
8566 					dut->ap_ampdu_exp);
8567 
8568 			if (dut->ap_max_mpdu_len)
8569 				fprintf(f, "[MAX-MPDU-%d]",
8570 					dut->ap_max_mpdu_len);
8571 
8572 			fprintf(f, "\n");
8573 		}
8574 	}
8575 
8576 	if (dut->ap_key_mgmt == AP_WPA2_OWE && dut->ap_tag_ssid[0][0] &&
8577 	    dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
8578 		/* OWE transition mode */
8579 		unsigned char bssid[6];
8580 		char ifname2[50];
8581 		unsigned long val;
8582 		FILE *f2;
8583 
8584 		snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8585 
8586 		fprintf(f, "owe_transition_ifname=%s\n", ifname2);
8587 		val = 0x12345678; /* default to something */
8588 		f2 = fopen("/dev/urandom", "r");
8589 		if (f2) {
8590 			if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) {
8591 				sigma_dut_print(dut, DUT_MSG_ERROR,
8592 						"Could not read /dev/urandom");
8593 			}
8594 			fclose(f2);
8595 		}
8596 		fprintf(f, "ssid=owe-%lx\n", val);
8597 		fprintf(f, "ignore_broadcast_ssid=1\n");
8598 
8599 		if (get_hwaddr(ifname, bssid)) {
8600 			fclose(f);
8601 			return -2;
8602 		}
8603 		if (bssid[0] & 0x02)
8604 			bssid[5] ^= 0x01;
8605 		else
8606 			bssid[0] |= 0x02;
8607 
8608 		fprintf(f, "bss=%s\n", ifname2);
8609 		fprintf(f, "ssid=%s\n", dut->ap_ssid);
8610 		if (dut->bridge)
8611 			fprintf(f, "bridge=%s\n", dut->bridge);
8612 		if (drv == DRIVER_LINUX_WCN)
8613 			fprintf(f, "use_driver_iface_addr=1\n");
8614 		else
8615 			fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8616 				bssid[0], bssid[1], bssid[2], bssid[3],
8617 				bssid[4], bssid[5]);
8618 		fprintf(f, "owe_transition_ifname=%s\n", ifname);
8619 	}
8620 
8621 	if (dut->ap_key_mgmt == AP_OPEN &&
8622 	    dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
8623 		/* OWE transition mode */
8624 		unsigned char bssid[6];
8625 		char ifname2[50];
8626 		unsigned long val;
8627 		FILE *f2;
8628 
8629 		snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8630 
8631 		fprintf(f, "owe_transition_ifname=%s\n", ifname2);
8632 		fprintf(f, "ssid=%s\n", dut->ap_ssid);
8633 
8634 		if (get_hwaddr(ifname, bssid)) {
8635 			fclose(f);
8636 			return -2;
8637 		}
8638 		if (bssid[0] & 0x02)
8639 			bssid[5] ^= 0x01;
8640 		else
8641 			bssid[0] |= 0x02;
8642 
8643 		fprintf(f, "bss=%s\n", ifname2);
8644 		val = 0x12345678; /* default to something */
8645 		f2 = fopen("/dev/urandom", "r");
8646 		if (f2) {
8647 			if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) {
8648 				sigma_dut_print(dut, DUT_MSG_ERROR,
8649 						"Could not read /dev/urandom");
8650 			}
8651 			fclose(f2);
8652 		}
8653 		fprintf(f, "ssid=owe-%lx\n", val);
8654 		if (dut->bridge)
8655 			fprintf(f, "bridge=%s\n", dut->bridge);
8656 		if (drv == DRIVER_LINUX_WCN)
8657 			fprintf(f, "use_driver_iface_addr=1\n");
8658 		else
8659 			fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8660 				bssid[0], bssid[1], bssid[2], bssid[3],
8661 				bssid[4], bssid[5]);
8662 		fprintf(f, "owe_transition_ifname=%s\n", ifname);
8663 		fprintf(f, "wpa=2\n");
8664 		fprintf(f, "wpa_key_mgmt=OWE\n");
8665 		fprintf(f, "rsn_pairwise=CCMP\n");
8666 		fprintf(f, "ieee80211w=2\n");
8667 		fprintf(f, "ignore_broadcast_ssid=1\n");
8668 		if (dut->ap_sae_groups)
8669 			fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups);
8670 		if (dut->owe_ptk_workaround)
8671 			fprintf(f, "owe_ptk_workaround=1\n");
8672 	}
8673 
8674 	if (dut->program == PROGRAM_OCE) {
8675 		fprintf(f, "oce=%d\n",
8676 			dut->dev_role == DEVROLE_STA_CFON ? 2 : 1);
8677 	}
8678 	fclose(f);
8679 	if (dut->use_hostapd_pid_file)
8680 		kill_hostapd_process_pid(dut);
8681 #ifdef __QNXNTO__
8682 	if (system("slay hostapd") == 0)
8683 #else /* __QNXNTO__ */
8684 	if (!dut->use_hostapd_pid_file &&
8685 	    (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
8686 	     system("killall hostapd") == 0))
8687 #endif /* __QNXNTO__ */
8688 	{
8689 		int i;
8690 		/* Wait some time to allow hostapd to complete cleanup before
8691 		 * starting a new process */
8692 		for (i = 0; i < 10; i++) {
8693 			usleep(500000);
8694 #ifdef __QNXNTO__
8695 			if (system("pidin | grep hostapd") != 0)
8696 				break;
8697 #else /* __QNXNTO__ */
8698 			if (system("pidof hostapd") != 0)
8699 				break;
8700 #endif /* __QNXNTO__ */
8701 		}
8702 	}
8703 	dut->hostapd_running = 0;
8704 
8705 #ifdef ANDROID
8706 	/* Set proper conf file permissions so that hostapd process
8707 	 * can access it.
8708 	 */
8709 	if (chmod(ap_conf_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0)
8710 		sigma_dut_print(dut, DUT_MSG_ERROR,
8711 				"Error changing permissions");
8712 
8713 	gr = getgrnam("wifi");
8714 	if (!gr || chown(ap_conf_path, -1, gr->gr_gid) < 0)
8715 		sigma_dut_print(dut, DUT_MSG_ERROR, "Error changing groupid");
8716 #endif /* ANDROID */
8717 
8718 	f = fopen(ap_conf_path, "r");
8719 	if (f) {
8720 		size_t len;
8721 
8722 		len = fread(buf, 1, sizeof(buf), f);
8723 		fclose(f);
8724 		if (len >= sizeof(buf))
8725 			len = sizeof(buf) - 1;
8726 		buf[len] = '\0';
8727 		sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd debug log:\n%s",
8728 				buf);
8729 	}
8730 
8731 	if (drv == DRIVER_QNXNTO) {
8732 		snprintf(buf, sizeof(buf),
8733 			 "hostapd -B %s%s%s %s%s %s/sigma_dut-ap.conf",
8734 			 dut->hostapd_debug_log ? "-dddKt " : "",
8735 			 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ?
8736 			 "-f " : "",
8737 			 dut->hostapd_debug_log ? dut->hostapd_debug_log : "",
8738 			 dut->hostapd_entropy_log ? " -e" : "",
8739 			 dut->hostapd_entropy_log ? dut->hostapd_entropy_log :
8740 			 "",
8741 			 dut->sigma_tmpdir);
8742 	} else {
8743 		/*
8744 		 * It looks like a monitor interface can cause some issues for
8745 		 * beaconing, so remove it (if injection was used) before
8746 		 * starting hostapd.
8747 		 */
8748 		if (if_nametoindex("sigmadut") > 0 &&
8749 		    system("iw dev sigmadut del") != 0)
8750 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove "
8751 					"monitor interface");
8752 
8753 		snprintf(path, sizeof(path), "%shostapd",
8754 			 file_exists("hostapd") ? "./" : "");
8755 		snprintf(buf, sizeof(buf),
8756 			 "%s -B%s%s%s%s%s%s %s/sigma_dut-ap.conf",
8757 			 dut->hostapd_bin ? dut->hostapd_bin : path,
8758 			 dut->hostapd_debug_log ? " -dddKt" : "",
8759 			 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ?
8760 			 " -f " : "",
8761 			 dut->hostapd_debug_log ? dut->hostapd_debug_log : "",
8762 			 dut->hostapd_entropy_log ? " -e" : "",
8763 			 dut->hostapd_entropy_log ? dut->hostapd_entropy_log :
8764 			 "",
8765 			 dut->use_hostapd_pid_file ?
8766 			 " -P " SIGMA_DUT_HOSTAPD_PID_FILE : "",
8767 			 dut->sigma_tmpdir);
8768 	}
8769 
8770 	sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd command: %s", buf);
8771 	if (system(buf) != 0) {
8772 		send_resp(dut, conn, SIGMA_ERROR,
8773 			  "errorCode,Failed to start hostapd");
8774 		return 0;
8775 	}
8776 
8777 	/* allow some time for hostapd to start before returning success */
8778 	usleep(500000);
8779 	if (run_hostapd_cli(dut, "ping") != 0) {
8780 		send_resp(dut, conn, SIGMA_ERROR,
8781 			  "errorCode,Failed to talk to hostapd");
8782 		return 0;
8783 	}
8784 
8785 	if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) {
8786 		int buf_size;
8787 
8788 		if (dut->ap_ba_bufsize == BA_BUFSIZE_256)
8789 			buf_size = 256;
8790 		else
8791 			buf_size = 64;
8792 
8793 		if ((drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) &&
8794 		    sta_set_addba_buf_size(dut, ifname, buf_size)) {
8795 			send_resp(dut, conn, SIGMA_ERROR,
8796 				  "ErrorCode,set_addba_buf_size failed");
8797 			return STATUS_SENT_ERROR;
8798 		}
8799 
8800 		sigma_dut_print(dut, DUT_MSG_INFO,
8801 				"setting addba buf_size=%d", buf_size);
8802 	}
8803 
8804 	if (drv == DRIVER_LINUX_WCN) {
8805 		const char *ifname_ptr = ifname;
8806 
8807 		if ((dut->ap_key_mgmt == AP_OPEN &&
8808 		     dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) ||
8809 		    (dut->ap_key_mgmt == AP_WPA2_OWE &&
8810 		     dut->ap_tag_ssid[0][0] &&
8811 		     dut->ap_tag_key_mgmt[0] == AP2_OPEN)) {
8812 			/* OWE transition mode */
8813 			if (dut->bridge)
8814 				ifname_ptr = dut->bridge;
8815 		}
8816 
8817 		sigma_dut_print(dut, DUT_MSG_INFO,
8818 				"setting ip addr %s mask %s ifname %s",
8819 				ap_inet_addr, ap_inet_mask, ifname_ptr);
8820 		snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up",
8821 			 ifname_ptr, ap_inet_addr, ap_inet_mask);
8822 		if (system(buf) != 0) {
8823 			sigma_dut_print(dut, DUT_MSG_ERROR,
8824 					"Failed to initialize the interface");
8825 			return -1;
8826 		}
8827 	}
8828 
8829 	/* Configure the driver with LDPC setting for AP mode as a new vdev is
8830 	 * created when hostapd is started.
8831 	 */
8832 	if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN)
8833 		wcn_config_ap_ldpc(dut, ifname);
8834 
8835 	if ((drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) &&
8836 	     dut->program == PROGRAM_OCE && dut->dev_role == DEVROLE_STA_CFON &&
8837 	     wcn_config_ap_fils_dscv(dut, ifname))
8838 		return ERROR_SEND_STATUS;
8839 
8840 	if (dut->ap_l2tif) {
8841 		snprintf(path, sizeof(path),
8842 			 "/sys/class/net/%s/brport/hairpin_mode",
8843 			 ifname);
8844 		if (!file_exists(path)) {
8845 			sigma_dut_print(dut, DUT_MSG_ERROR,
8846 					"%s must be binded to the bridge for L2TIF",
8847 					ifname);
8848 			return -2;
8849 		}
8850 
8851 		snprintf(buf, sizeof(buf), "echo 1 > %s", path);
8852 		if (system(buf) != 0) {
8853 			sigma_dut_print(dut, DUT_MSG_ERROR,
8854 				"Failed to enable hairpin_mode for L2TIF");
8855 			return -2;
8856 		}
8857 
8858 		snprintf(buf, sizeof(buf), "ebtables -P FORWARD ACCEPT");
8859 		if (system(buf) != 0) {
8860 			sigma_dut_print(dut, DUT_MSG_ERROR,
8861 					"Failed to set ebtables rules, RULE-9");
8862 			return -2;
8863 		}
8864 
8865 		snprintf(buf, sizeof(buf),
8866 			 "ebtables -A FORWARD -p IPv4 --ip-proto icmp -i %s -j DROP",
8867 			 ifname);
8868 		if (system(buf) != 0) {
8869 			sigma_dut_print(dut, DUT_MSG_ERROR,
8870 					"Failed to set ebtables rules, RULE-11");
8871 			return -2;
8872 		}
8873 	}
8874 
8875 	if (dut->ap_proxy_arp) {
8876 		if (dut->ap_dgaf_disable) {
8877 			if (set_ebtables_disable_dgaf(dut, "FORWARD", ifname) ||
8878 			    set_ebtables_disable_dgaf(dut, "OUTPUT", ifname))
8879 				return -2;
8880 		} else {
8881 			if (set_ebtables_proxy_arp(dut, "FORWARD", ifname) ||
8882 			    set_ebtables_proxy_arp(dut, "OUTPUT", ifname))
8883 				return -2;
8884 		}
8885 
8886 		/* For 4.5-(c) */
8887 		snprintf(buf, sizeof(buf),
8888 			 "ebtables -A FORWARD -p ARP --arp-opcode 2 -i %s -j DROP",
8889 			 ifname);
8890 		if (system(buf) != 0) {
8891 			sigma_dut_print(dut, DUT_MSG_ERROR,
8892 					"Failed to set ebtables rules, RULE-10");
8893 			return -2;
8894 		}
8895 	}
8896 
8897 	if (dut->ap_tdls_prohibit || dut->ap_l2tif) {
8898 		/* Drop TDLS frames */
8899 		snprintf(buf, sizeof(buf),
8900 			 "ebtables -A FORWARD -p 0x890d -i %s -j DROP", ifname);
8901 		if (system(buf) != 0) {
8902 			sigma_dut_print(dut, DUT_MSG_ERROR,
8903 					"Failed to set ebtables rules, RULE-13");
8904 			return -2;
8905 		}
8906 	}
8907 
8908 	if (dut->ap_fake_pkhash &&
8909 	    run_hostapd_cli(dut, "set wps_corrupt_pkhash 1") != 0) {
8910 		send_resp(dut, conn, SIGMA_ERROR,
8911 			  "errorCode,Could not enable FakePubKey");
8912 		return 0;
8913 	}
8914 
8915 	if (dut->program == PROGRAM_60GHZ) {
8916 		if (dut->ap_num_ese_allocs > 0) {
8917 			/* wait extra time for AP to start */
8918 			sleep(2);
8919 			if (ap_set_60g_ese(dut, dut->ap_num_ese_allocs,
8920 					   dut->ap_ese_allocs)) {
8921 				send_resp(dut, conn, SIGMA_ERROR,
8922 					  "errorCode,Could not set ExtSch");
8923 				return 0;
8924 			}
8925 		}
8926 		if (dut->ap_fixed_rate) {
8927 			sigma_dut_print(dut, DUT_MSG_DEBUG,
8928 					"forcing TX MCS index %d",
8929 					dut->ap_mcs);
8930 			if (ap_set_force_mcs(dut, 1, dut->ap_mcs)) {
8931 				send_resp(dut, conn, SIGMA_ERROR,
8932 					  "errorCode,Could not force MCS");
8933 				return -2;
8934 			}
8935 		}
8936 	}
8937 
8938 	if (dut->wps_forced_version) {
8939 		snprintf(buf, sizeof(buf), "SET wps_version_number %d",
8940 			 dut->wps_forced_version);
8941 		if (hapd_command(ifname, buf) < 0) {
8942 			send_resp(dut, conn, SIGMA_ERROR,
8943 				  "errorCode,Fail to set wps_version_number");
8944 			return STATUS_SENT;
8945 		}
8946 	}
8947 
8948 	if (drv == DRIVER_MAC80211 && dut->program == PROGRAM_HE)
8949 		fwtest_set_he_params(dut, ifname);
8950 
8951 	dut->hostapd_running = 1;
8952 	return 1;
8953 }
8954 
8955 
parse_qos_params(struct sigma_dut * dut,struct sigma_conn * conn,struct qos_params * qos,const char * cwmin,const char * cwmax,const char * aifs,const char * txop,const char * acm)8956 static int parse_qos_params(struct sigma_dut *dut, struct sigma_conn *conn,
8957 			    struct qos_params *qos, const char *cwmin,
8958 			    const char *cwmax, const char *aifs,
8959 			    const char *txop, const char *acm)
8960 {
8961 	int val;
8962 
8963 	if (cwmin) {
8964 		qos->ac = 1;
8965 		val = atoi(cwmin);
8966 		if (val < 0 || val > 15) {
8967 			send_resp(dut, conn, SIGMA_INVALID,
8968 				  "errorCode,Invalid cwMin");
8969 			return 0;
8970 		}
8971 		qos->cwmin = val;
8972 	}
8973 
8974 	if (cwmax) {
8975 		qos->ac = 1;
8976 		val = atoi(cwmax);
8977 		if (val < 0 || val > 15) {
8978 			send_resp(dut, conn, SIGMA_INVALID,
8979 				  "errorCode,Invalid cwMax");
8980 			return 0;
8981 		}
8982 		qos->cwmax = val;
8983 	}
8984 
8985 	if (aifs) {
8986 		qos->ac = 1;
8987 		val = atoi(aifs);
8988 		if (val < 1 || val > 255) {
8989 			send_resp(dut, conn, SIGMA_INVALID,
8990 				  "errorCode,Invalid AIFS");
8991 			return 0;
8992 		}
8993 		qos->aifs = val;
8994 	}
8995 
8996 	if (txop) {
8997 		qos->ac = 1;
8998 		val = atoi(txop);
8999 		if (val < 0 || val > 0xffff) {
9000 			send_resp(dut, conn, SIGMA_INVALID,
9001 				  "errorCode,Invalid txop");
9002 			return 0;
9003 		}
9004 		qos->txop = val * 32;
9005 	}
9006 
9007 	if (acm) {
9008 		qos->ac = 1;
9009 		qos->acm = strcasecmp(acm, "on") == 0;
9010 	}
9011 
9012 	return 1;
9013 }
9014 
9015 
cmd_ap_set_apqos(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9016 static enum sigma_cmd_result cmd_ap_set_apqos(struct sigma_dut *dut,
9017 					      struct sigma_conn *conn,
9018 					      struct sigma_cmd *cmd)
9019 {
9020 	/* TXOP: The values provided here for VHT5G only */
9021 	if (!parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VO],
9022 			      get_param(cmd, "cwmin_VO"),
9023 			      get_param(cmd, "cwmax_VO"),
9024 			      get_param(cmd, "AIFS_VO"),
9025 			      get_param(cmd, "TXOP_VO"),
9026 			      get_param(cmd, "ACM_VO")) ||
9027 	    !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VI],
9028 			      get_param(cmd, "cwmin_VI"),
9029 			      get_param(cmd, "cwmax_VI"),
9030 			      get_param(cmd, "AIFS_VI"),
9031 			      get_param(cmd, "TXOP_VI"),
9032 			      get_param(cmd, "ACM_VI")) ||
9033 	    !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BE],
9034 			      get_param(cmd, "cwmin_BE"),
9035 			      get_param(cmd, "cwmax_BE"),
9036 			      get_param(cmd, "AIFS_BE"),
9037 			      get_param(cmd, "TXOP_BE"),
9038 			      get_param(cmd, "ACM_BE")) ||
9039 	    !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BK],
9040 			      get_param(cmd, "cwmin_BK"),
9041 			      get_param(cmd, "cwmax_BK"),
9042 			      get_param(cmd, "AIFS_BK"),
9043 			      get_param(cmd, "TXOP_BK"),
9044 			      get_param(cmd, "ACM_BK")))
9045 		return 0;
9046 
9047 	return 1;
9048 }
9049 
9050 
cmd_ap_set_staqos(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9051 static enum sigma_cmd_result cmd_ap_set_staqos(struct sigma_dut *dut,
9052 					       struct sigma_conn *conn,
9053 					       struct sigma_cmd *cmd)
9054 {
9055 	if (!parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VO],
9056 			      get_param(cmd, "cwmin_VO"),
9057 			      get_param(cmd, "cwmax_VO"),
9058 			      get_param(cmd, "AIFS_VO"),
9059 			      get_param(cmd, "TXOP_VO"),
9060 			      get_param(cmd, "ACM_VO")) ||
9061 	    !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VI],
9062 			      get_param(cmd, "cwmin_VI"),
9063 			      get_param(cmd, "cwmax_VI"),
9064 			      get_param(cmd, "AIFS_VI"),
9065 			      get_param(cmd, "TXOP_VI"),
9066 			      get_param(cmd, "ACM_VI")) ||
9067 	    !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BE],
9068 			      get_param(cmd, "cwmin_BE"),
9069 			      get_param(cmd, "cwmax_BE"),
9070 			      get_param(cmd, "AIFS_BE"),
9071 			      get_param(cmd, "TXOP_BE"),
9072 			      get_param(cmd, "ACM_BE")) ||
9073 	    !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BK],
9074 			      get_param(cmd, "cwmin_BK"),
9075 			      get_param(cmd, "cwmax_BK"),
9076 			      get_param(cmd, "AIFS_BK"),
9077 			      get_param(cmd, "TXOP_BK"),
9078 			      get_param(cmd, "ACM_BK")))
9079 		return 0;
9080 
9081 	return 1;
9082 }
9083 
9084 
cmd_ath_ap_hs2_reset(struct sigma_dut * dut)9085 static void cmd_ath_ap_hs2_reset(struct sigma_dut *dut)
9086 {
9087 	unsigned char bssid[6];
9088 	char buf[100];
9089 	run_system(dut, "cfg -a AP_SSID=\"Hotspot 2.0\"");
9090 	run_system(dut, "cfg -a AP_PRIMARY_CH=1");
9091 	run_system(dut, "cfg -a AP_SECMODE=WPA");
9092 	run_system(dut, "cfg -a AP_SECFILE=EAP");
9093 	run_system(dut, "cfg -a AP_WPA=2");
9094 	run_system(dut, "cfg -a AP_CYPHER=CCMP");
9095 	run_system(dut, "cfg -a AP_HOTSPOT=1");
9096 	run_system(dut, "cfg -a AP_HOTSPOT_ANT=2");
9097 	run_system(dut, "cfg -a AP_HOTSPOT_INTERNET=0");
9098 	run_system(dut, "cfg -a AP_HOTSPOT_VENUEGROUP=2");
9099 	run_system(dut, "cfg -a AP_HOTSPOT_VENUETYPE=8");
9100 	run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=506f9a");
9101 	run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2=001bc504bd");
9102 	if (!get_hwaddr("ath0", bssid)) {
9103 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID="
9104 			"%02x:%02x:%02x:%02x:%02x:%02x",
9105 			bssid[0], bssid[1], bssid[2], bssid[3],
9106 			bssid[4], bssid[5]);
9107 		run_system(dut, buf);
9108 		snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
9109 			"%02x:%02x:%02x:%02x:%02x:%02x",
9110 			bssid[0], bssid[1], bssid[2], bssid[3],
9111 			bssid[4], bssid[5]);
9112 	} else {
9113 		if (!get_hwaddr("wifi0", bssid)) {
9114 			snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID="
9115 				"%02x:%02x:%02x:%02x:%02x:%02x",
9116 				bssid[0], bssid[1], bssid[2], bssid[3],
9117 				bssid[4], bssid[5]);
9118 			run_system(dut, buf);
9119 			snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
9120 				"%02x:%02x:%02x:%02x:%02x:%02x",
9121 				bssid[0], bssid[1], bssid[2], bssid[3],
9122 				bssid[4], bssid[5]);
9123 		} else {
9124 			/* load the driver and try again */
9125 			run_system(dut, "/etc/rc.d/rc.wlan up");
9126 
9127 			if (!get_hwaddr("wifi0", bssid)) {
9128 				snprintf(buf, sizeof(buf),
9129 					 "cfg -a AP_HOTSPOT_HESSID="
9130 					 "%02x:%02x:%02x:%02x:%02x:%02x",
9131 					 bssid[0], bssid[1], bssid[2],
9132 					 bssid[3], bssid[4], bssid[5]);
9133 				run_system(dut, buf);
9134 				snprintf(dut->ap_hessid,
9135 					 sizeof(dut->ap_hessid),
9136 					 "%02x:%02x:%02x:%02x:%02x:%02x",
9137 					 bssid[0], bssid[1], bssid[2],
9138 					 bssid[3], bssid[4], bssid[5]);
9139 			}
9140 		}
9141 	}
9142 
9143 	run_system(dut, "cfg -r AP_SSID_2");
9144 	run_system(dut, "cfg -c");
9145 	/* run_system(dut, "cfg -s"); */
9146 }
9147 
9148 
ath_reset_vht_defaults(struct sigma_dut * dut)9149 static void ath_reset_vht_defaults(struct sigma_dut *dut)
9150 {
9151 	run_system(dut, "cfg -x");
9152 	run_system(dut, "cfg -a AP_RADIO_ID=1");
9153 	run_system(dut, "cfg -a AP_PRIMARY_CH_2=36");
9154 	run_system(dut, "cfg -a AP_STARTMODE=standard");
9155 	run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
9156 	run_system(dut, "cfg -a TX_CHAINMASK_2=7");
9157 	run_system(dut, "cfg -a RX_CHAINMASK_2=7");
9158 	run_system(dut, "cfg -a ATH_countrycode=0x348");
9159 	/* NOTE: For Beeliner we have to turn off MU-MIMO */
9160 	if (system("rm /tmp/secath*") != 0) {
9161 		sigma_dut_print(dut, DUT_MSG_ERROR,
9162 				"Failed to remove secath file");
9163 	}
9164 }
9165 
9166 
9167 #ifdef NL80211_SUPPORT
9168 
9169 #define IEEE80211_HT_AMPDU_PARAM_FACTOR        0x3
9170 #define IEEE80211_HT_AMPDU_PARAM_DENSITY_SHIFT	2
9171 
phy_info_ht_capa(struct dut_hw_modes * mode,struct nlattr * capa,struct nlattr * ampdu_factor,struct nlattr * ampdu_density,struct nlattr * mcs_set)9172 static void phy_info_ht_capa(struct dut_hw_modes *mode, struct nlattr *capa,
9173 			     struct nlattr *ampdu_factor,
9174 			     struct nlattr *ampdu_density,
9175 			     struct nlattr *mcs_set)
9176 {
9177 	if (capa)
9178 		mode->ht_capab = nla_get_u16(capa);
9179 
9180 	if (ampdu_factor)
9181 		mode->ampdu_params |= nla_get_u8(ampdu_factor) &
9182 			IEEE80211_HT_AMPDU_PARAM_FACTOR;
9183 
9184 	if (ampdu_density)
9185 		mode->ampdu_params |= nla_get_u8(ampdu_density) <<
9186 			IEEE80211_HT_AMPDU_PARAM_DENSITY_SHIFT;
9187 
9188 	if (mcs_set && nla_len(mcs_set) >= sizeof(mode->mcs_set))
9189 		memcpy(mode->mcs_set, nla_data(mcs_set), sizeof(mode->mcs_set));
9190 }
9191 
9192 
phy_info_vht_capa(struct dut_hw_modes * mode,struct nlattr * capa,struct nlattr * mcs_set)9193 static void phy_info_vht_capa(struct dut_hw_modes *mode,
9194 			      struct nlattr *capa,
9195 			      struct nlattr *mcs_set)
9196 {
9197 	if (capa)
9198 		mode->vht_capab = nla_get_u32(capa);
9199 
9200 	if (mcs_set && nla_len(mcs_set) >= sizeof(mode->vht_mcs_set))
9201 		memcpy(mode->vht_mcs_set, nla_data(mcs_set),
9202 		       sizeof(mode->vht_mcs_set));
9203 }
9204 
9205 
phy_info_band(struct dut_hw_modes * mode,struct nlattr * nl_band)9206 static int phy_info_band(struct dut_hw_modes *mode, struct nlattr *nl_band)
9207 {
9208 	struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
9209 
9210 	nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
9211 		  nla_len(nl_band), NULL);
9212 
9213 	phy_info_ht_capa(mode, tb_band[NL80211_BAND_ATTR_HT_CAPA],
9214 			 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR],
9215 			 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY],
9216 			 tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
9217 
9218 	phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
9219 			  tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
9220 
9221 	/* Other nl80211 band attributes can be parsed here, if required */
9222 
9223 	return NL_OK;
9224 }
9225 
9226 
antenna_mask_to_nss(unsigned int mask)9227 static int antenna_mask_to_nss(unsigned int mask)
9228 {
9229 	unsigned int i;
9230 	int msb = 0;
9231 
9232 	for (i = 0; i < sizeof(mask) * 8; i++)
9233 		if ((mask >> i) & 1)
9234 			msb = i;
9235 
9236 	return msb + 1;
9237 }
9238 
9239 
wiphy_info_handler(struct nl_msg * msg,void * arg)9240 static int wiphy_info_handler(struct nl_msg *msg, void *arg)
9241 {
9242 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
9243 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9244 	struct sigma_dut *dut = arg;
9245 	unsigned int tx_antenna_mask;
9246 	struct nlattr *nl_band;
9247 	int rem_band;
9248 
9249 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9250 		  genlmsg_attrlen(gnlh, 0), NULL);
9251 
9252 	if (tb[NL80211_ATTR_WIPHY_ANTENNA_TX]) {
9253 		tx_antenna_mask =
9254 			nla_get_u32(tb[NL80211_ATTR_WIPHY_ANTENNA_TX]);
9255 		dut->ap_tx_streams = antenna_mask_to_nss(tx_antenna_mask);
9256 	}
9257 
9258 	if (!tb[NL80211_ATTR_WIPHY_BANDS])
9259 		return 1;
9260 
9261 	nla_for_each_nested(nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) {
9262 		int res = phy_info_band(&dut->hw_modes, nl_band);
9263 
9264 		if (res != NL_OK)
9265 			return res;
9266 	}
9267 
9268 	return 0;
9269 }
9270 
9271 
mac80211_get_wiphy(struct sigma_dut * dut)9272 static int mac80211_get_wiphy(struct sigma_dut *dut)
9273 {
9274 	struct nl_msg *msg;
9275 	int ret = 0;
9276 	int ifindex;
9277 
9278 	ifindex = if_nametoindex(dut->main_ifname);
9279 	if (ifindex == 0) {
9280 		sigma_dut_print(dut, DUT_MSG_DEBUG,
9281 				"%s: Index for interface %s failed",
9282 				__func__, dut->main_ifname);
9283 		return -1;
9284 	}
9285 
9286 	if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9287 				    NL80211_CMD_GET_WIPHY)) ||
9288 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex)) {
9289 		sigma_dut_print(dut, DUT_MSG_DEBUG,
9290 				"%s: could not build get wiphy cmd", __func__);
9291 		nlmsg_free(msg);
9292 		return -1;
9293 	}
9294 
9295 	ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, wiphy_info_handler,
9296 				 dut);
9297 	if (ret)
9298 		sigma_dut_print(dut, DUT_MSG_DEBUG,
9299 				"%s: err in send_and_recv_msgs, ret=%d",
9300 				__func__, ret);
9301 
9302 	return ret;
9303 }
9304 
9305 #endif /* NL80211_SUPPORT */
9306 
9307 
cmd_ap_reset_default(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9308 static enum sigma_cmd_result cmd_ap_reset_default(struct sigma_dut *dut,
9309 						  struct sigma_conn *conn,
9310 						  struct sigma_cmd *cmd)
9311 {
9312 	const char *type, *program;
9313 	enum driver_type drv;
9314 	char buf[128];
9315 	int i;
9316 
9317 	for (i = 0; i < MAX_WLAN_TAGS - 1; i++) {
9318 		/*
9319 		 * Reset all tagged SSIDs to NULL-string and all key management
9320 		 * to open.
9321 		 */
9322 		dut->ap_tag_ssid[i][0] = '\0';
9323 		dut->ap_tag_key_mgmt[i] = AP2_OPEN;
9324 	}
9325 
9326 	drv = get_driver_type(dut);
9327 
9328 	program = get_param(cmd, "program");
9329 	if (!program)
9330 		program = get_param(cmd, "prog");
9331 	dut->program = sigma_program_to_enum(program);
9332 	dut->device_type = AP_unknown;
9333 	type = get_param(cmd, "type");
9334 	if (type && strcasecmp(type, "Testbed") == 0)
9335 		dut->device_type = AP_testbed;
9336 	if (type && strcasecmp(type, "DUT") == 0)
9337 		dut->device_type = AP_dut;
9338 
9339 	dut->ap_rts = 0;
9340 	dut->ap_frgmnt = 0;
9341 	dut->ap_bcnint = 0;
9342 	dut->ap_key_mgmt = AP_OPEN;
9343 	dut->ap_ssid[0] = '\0';
9344 	dut->ap_fake_pkhash = 0;
9345 	memset(dut->ap_qos, 0, sizeof(dut->ap_qos));
9346 	memset(dut->ap_sta_qos, 0, sizeof(dut->ap_sta_qos));
9347 	dut->ap_addba_reject = VALUE_NOT_SET;
9348 	dut->ap_noack = VALUE_NOT_SET;
9349 	dut->ap_is_dual = 0;
9350 	dut->ap_mode = AP_inval;
9351 	dut->ap_mode_1 = AP_inval;
9352 
9353 	dut->ap_allow_vht_wep = 0;
9354 	dut->ap_allow_vht_tkip = 0;
9355 	dut->ap_disable_protection = 0;
9356 	memset(dut->ap_countrycode, 0, sizeof(dut->ap_countrycode));
9357 	dut->ap_dyn_bw_sig = VALUE_NOT_SET;
9358 	dut->ap_ldpc = VALUE_NOT_SET;
9359 	dut->ap_sig_rts = VALUE_NOT_SET;
9360 	dut->ap_rx_amsdu = VALUE_NOT_SET;
9361 	dut->ap_txBF = 0;
9362 	dut->ap_mu_txBF = 0;
9363 	dut->ap_chwidth = AP_AUTO;
9364 	dut->ap_ampdu_exp = 0;
9365 	dut->ap_max_mpdu_len = 0;
9366 
9367 	dut->ap_rsn_preauth = 0;
9368 	dut->ap_wpsnfc = 0;
9369 	dut->ap_bss_load = -1;
9370 	dut->ap_p2p_cross_connect = -1;
9371 
9372 	dut->ap_regulatory_mode = AP_80211D_MODE_DISABLED;
9373 	dut->ap_dfs_mode = AP_DFS_MODE_DISABLED;
9374 	dut->ap_chwidth_offset = SEC_CH_NO;
9375 
9376 	dut->mbo_pref_ap_cnt = 0;
9377 	dut->ft_bss_mac_cnt = 0;
9378 	dut->ap_interface_5g = 0;
9379 	dut->ap_interface_2g = 0;
9380 	dut->ap_pmf = AP_PMF_DISABLED;
9381 
9382 	dut->wsc_fragment = 0;
9383 	dut->eap_fragment = 0;
9384 	dut->wps_forced_version = 0;
9385 
9386 	if (dut->program == PROGRAM_HT || dut->program == PROGRAM_VHT) {
9387 		dut->ap_wme = AP_WME_ON;
9388 		dut->ap_wmmps = AP_WMMPS_ON;
9389 	} else {
9390 		dut->ap_wme = AP_WME_OFF;
9391 		dut->ap_wmmps = AP_WMMPS_OFF;
9392 	}
9393 
9394 	dut->ap_venue_url = 0;
9395 	dut->ap_advice_of_charge = 0;
9396 	dut->ap_oper_icon_metadata = 0;
9397 	dut->ap_tnc_file_name = 0;
9398 	dut->ap_tnc_time_stamp = 0;
9399 
9400 	dut->ap_akm_values = 0;
9401 	free(dut->ap_sae_passwords);
9402 	dut->ap_sae_passwords = NULL;
9403 	dut->ap_sae_pk = 0;
9404 	free(dut->ap_sae_pk_modifier);
9405 	dut->ap_sae_pk_modifier = NULL;
9406 	free(dut->ap_sae_pk_keypair);
9407 	dut->ap_sae_pk_keypair = NULL;
9408 	free(dut->ap_sae_pk_keypair_sig);
9409 	dut->ap_sae_pk_keypair_sig = NULL;
9410 
9411 	dut->ap_ocvc = -1;
9412 
9413 	if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
9414 	    dut->program == PROGRAM_HS2_R3 ||
9415 	    dut->program == PROGRAM_IOTLP) {
9416 		int i;
9417 
9418 		if (drv == DRIVER_ATHEROS)
9419 			cmd_ath_ap_hs2_reset(dut);
9420 		else if (drv == DRIVER_OPENWRT)
9421 			cmd_owrt_ap_hs2_reset(dut);
9422 
9423 		dut->ap_interworking = 1;
9424 		dut->ap_access_net_type = 2;
9425 		dut->ap_internet = 0;
9426 		dut->ap_venue_group = 2;
9427 		dut->ap_venue_type = 8;
9428 		dut->ap_domain_name_list[0] = '\0';
9429 		dut->ap_hs2 = 1;
9430 		snprintf(dut->ap_roaming_cons, sizeof(dut->ap_roaming_cons),
9431 			 "506f9a;001bc504bd");
9432 		dut->ap_l2tif = 0;
9433 		dut->ap_proxy_arp = 0;
9434 		if (dut->bridge) {
9435 			char buf[50];
9436 
9437 			snprintf(buf, sizeof(buf), "ip neigh flush dev %s",
9438 				 dut->bridge);
9439 			if (system(buf) != 0) {
9440 				sigma_dut_print(dut, DUT_MSG_DEBUG,
9441 						"%s ip neigh table flushing failed",
9442 						dut->bridge);
9443 			}
9444 
9445 			snprintf(buf, sizeof(buf), "ebtables -F");
9446 			if (system(buf) != 0) {
9447 				sigma_dut_print(dut, DUT_MSG_DEBUG,
9448 						"%s ebtables flushing failed",
9449 						dut->bridge);
9450 			}
9451 		}
9452 		dut->ap_dgaf_disable = 0;
9453 		dut->ap_p2p_cross_connect = 0;
9454 		dut->ap_gas_cb_delay = 0;
9455 		dut->ap_nai_realm_list = 0;
9456 		dut->ap_oper_name = 0;
9457 		dut->ap_venue_name = 0;
9458 		for (i = 0; i < 10; i++) {
9459 			dut->ap_plmn_mcc[i][0] = '\0';
9460 			dut->ap_plmn_mnc[i][0] = '\0';
9461 		}
9462 		dut->ap_wan_metrics = 0;
9463 		dut->ap_conn_capab = 0;
9464 		dut->ap_ip_addr_type_avail = 0;
9465 		dut->ap_net_auth_type = 0;
9466 		dut->ap_oper_class = 0;
9467 		dut->ap_pmf = 0;
9468 		dut->ap_add_sha256 = 0;
9469 	}
9470 
9471 	if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
9472 	    dut->program == PROGRAM_IOTLP) {
9473 		int i;
9474 		const char hessid[] = "50:6f:9a:00:11:22";
9475 
9476 		memcpy(dut->ap_hessid, hessid, strlen(hessid) + 1);
9477 		dut->ap_osu_ssid[0] = '\0';
9478 		dut->ap_pmf = 1;
9479 		dut->ap_osu_provider_list = 0;
9480 		dut->ap_osu_provider_nai_list = 0;
9481 		for (i = 0; i < 10; i++) {
9482 			dut->ap_osu_server_uri[i][0] = '\0';
9483 			dut->ap_osu_method[i] = 0xFF;
9484 		}
9485 		dut->ap_qos_map_set = 0;
9486 		dut->ap_tag_key_mgmt[0] = AP2_OPEN;
9487 		dut->ap2_proxy_arp = 0;
9488 		dut->ap2_osu = 0;
9489 		dut->ap_osu_icon_tag = 0;
9490 	}
9491 
9492 	if (dut->program == PROGRAM_VHT) {
9493 		/* Set up the defaults */
9494 		dut->use_5g = 1;
9495 		dut->ap_mode = AP_11ac;
9496 		dut->ap_channel = 36;
9497 		dut->ap_ampdu = VALUE_NOT_SET;
9498 		dut->ap_ndpa_frame = 1;
9499 		if (dut->device_type == AP_testbed) {
9500 			dut->ap_amsdu = VALUE_DISABLED;
9501 			dut->ap_ldpc = VALUE_DISABLED;
9502 			dut->ap_rx_amsdu = VALUE_DISABLED;
9503 			dut->ap_sgi80 = 0;
9504 		} else {
9505 			dut->ap_amsdu = VALUE_ENABLED;
9506 			/*
9507 			 * As LDPC is optional, don't enable this by default
9508 			 * for LINUX-WCN driver. The ap_set_wireless command
9509 			 * can be used to enable LDPC, when needed.
9510 			 */
9511 			if (drv != DRIVER_LINUX_WCN)
9512 				dut->ap_ldpc = VALUE_ENABLED;
9513 			dut->ap_rx_amsdu = VALUE_ENABLED;
9514 			dut->ap_sgi80 = 1;
9515 		}
9516 		dut->ap_fixed_rate = 0;
9517 		dut->ap_rx_streams = 3;
9518 		dut->ap_tx_streams = 3;
9519 		dut->ap_vhtmcs_map = 0;
9520 		dut->ap_chwidth = AP_80;
9521 		dut->ap_tx_stbc = 1;
9522 		dut->ap_dyn_bw_sig = VALUE_ENABLED;
9523 		if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9524 			dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
9525 		if (get_driver_type(dut) == DRIVER_ATHEROS)
9526 			ath_reset_vht_defaults(dut);
9527 	}
9528 
9529 	if (dut->program == PROGRAM_IOTLP) {
9530 		dut->wnm_bss_max_feature = VALUE_DISABLED;
9531 		dut->wnm_bss_max_idle_time = 0;
9532 		dut->wnm_bss_max_protection = VALUE_NOT_SET;
9533 		dut->ap_proxy_arp = 1;
9534 	} else {
9535 		/*
9536 		 * Do not touch the BSS-MAX Idle time feature
9537 		 * if the program is not IOTLP.
9538 		 */
9539 		dut->wnm_bss_max_feature = VALUE_NOT_SET;
9540 		dut->wnm_bss_max_idle_time = 0;
9541 		dut->wnm_bss_max_protection = VALUE_NOT_SET;
9542 	}
9543 
9544 	if (dut->program == PROGRAM_LOC) {
9545 		dut->ap_rrm = 1;
9546 		dut->ap_rtt = 1;
9547 		dut->ap_lci = 0;
9548 		dut->ap_val_lci[0] = '\0';
9549 		dut->ap_infoz[0] = '\0';
9550 		dut->ap_lcr = 0;
9551 		dut->ap_val_lcr[0] = '\0';
9552 		dut->ap_neighap = 0;
9553 		dut->ap_opchannel = 0;
9554 		dut->ap_scan = 0;
9555 		dut->ap_fqdn_held = 0;
9556 		dut->ap_fqdn_supl = 0;
9557 		dut->ap_interworking = 0;
9558 		dut->ap_gas_cb_delay = 0;
9559 		dut->ap_msnt_type = 0;
9560 	}
9561 	dut->ap_ft_oa = 0;
9562 	dut->ap_ft_ds = VALUE_NOT_SET;
9563 	dut->ap_reg_domain = REG_DOMAIN_NOT_SET;
9564 	dut->ap_mobility_domain[0] = '\0';
9565 
9566 	if (dut->program == PROGRAM_MBO) {
9567 		dut->ap_mbo = 1;
9568 		dut->ap_interworking = 1;
9569 		dut->ap_ne_class = 0;
9570 		dut->ap_ne_op_ch = 0;
9571 		dut->ap_set_bssidpref = 1;
9572 		dut->ap_btmreq_disassoc_imnt = 0;
9573 		dut->ap_btmreq_term_bit = 0;
9574 		dut->ap_disassoc_timer = 0;
9575 		dut->ap_btmreq_bss_term_dur = 0;
9576 		dut->ap_channel = 36;
9577 		dut->ap_chwidth = AP_20;
9578 		dut->ap_cell_cap_pref = 0;
9579 		dut->ap_gas_cb_delay = 0;
9580 		dut->mbo_self_ap_tuple.ap_ne_class = -1;
9581 		dut->mbo_self_ap_tuple.ap_ne_pref = -1; /* Not set */
9582 		dut->mbo_self_ap_tuple.ap_ne_op_ch = -1;
9583 		dut->ap_btmreq_bss_term_tsf = 0;
9584 		dut->ap_assoc_delay = 0;
9585 	}
9586 
9587 	if (dut->program == PROGRAM_OCE) {
9588 		if (dut->ap_dhcp_stop)
9589 			run_system(dut, "/etc/init.d/dnsmasq start");
9590 
9591 		dut->ap_dhcp_stop = 0;
9592 		dut->ap_oce = VALUE_ENABLED;
9593 		dut->ap_broadcast_ssid = VALUE_ENABLED;
9594 		dut->ap_fils_dscv_int = 20;
9595 		dut->ap_filsdscv = dut->dev_role == DEVROLE_STA_CFON ?
9596 			VALUE_NOT_SET : VALUE_ENABLED;
9597 		dut->ap_filshlp = VALUE_DISABLED;
9598 		dut->ap_rnr = VALUE_DISABLED;
9599 		dut->ap_nairealm[0] = '\0';
9600 		dut->ap_nairealm_int = 0;
9601 		dut->ap_blechanutil = 0;
9602 		dut->ap_ble_admit_cap = 0;
9603 		dut->ap_esp = VALUE_ENABLED;
9604 		dut->ap_datappdudura = 0;
9605 		dut->ap_airtimefract = 0;
9606 		dut->ap_blestacnt = 0;
9607 		dut->ap_ul_availcap = 0;
9608 		dut->ap_dl_availcap = 0;
9609 		dut->ap_akm = 0;
9610 		dut->ap_add_sha256 = 0;
9611 		dut->ap_add_sha384 = 0;
9612 		dut->ap_80plus80 = 0;
9613 	}
9614 
9615 	dut->ap_he_ppdu = PPDU_NOT_SET;
9616 	dut->ap_he_ulofdma = VALUE_NOT_SET;
9617 	dut->ap_numsounddim = 0;
9618 	dut->ap_bcc = VALUE_DISABLED;
9619 	dut->ap_mu_edca = VALUE_DISABLED;
9620 	dut->ap_he_mimo = MIMO_NOT_SET;
9621 	dut->ap_he_rtsthrshld = VALUE_NOT_SET;
9622 	dut->ap_mbssid = VALUE_DISABLED;
9623 	dut->ap_ampdu = VALUE_NOT_SET;
9624 	dut->he_mcsnssmap = 0;
9625 	dut->ap_fixed_rate = 0;
9626 	dut->he_mmss = 0;
9627 	dut->he_set_sta_1x1 = VALUE_DISABLED;
9628 	dut->he_srctrl_allow = -1;
9629 	if (dut->device_type == AP_testbed) {
9630 		dut->ap_he_dlofdma = VALUE_DISABLED;
9631 		dut->ap_he_frag = VALUE_DISABLED;
9632 		dut->ap_twtresp = VALUE_DISABLED;
9633 		dut->he_ul_mcs = 7;
9634 	} else {
9635 		dut->ap_he_dlofdma = VALUE_NOT_SET;
9636 		dut->ap_he_frag = VALUE_NOT_SET;
9637 		dut->ap_ba_bufsize = BA_BUFSIZE_NOT_SET;
9638 		dut->ap_twtresp = VALUE_NOT_SET;
9639 		dut->he_ul_mcs = 0;
9640 	}
9641 
9642 	if (dut->program == PROGRAM_HE) {
9643 		if (dut->device_type == AP_testbed) {
9644 			dut->ap_ldpc = VALUE_DISABLED;
9645 			dut->ap_ba_bufsize = BA_BUFSIZE_64;
9646 			dut->ap_amsdu = VALUE_DISABLED;
9647 			dut->ap_txBF = 0;
9648 			dut->ap_mu_txBF = 0;
9649 			dut->he_sounding = VALUE_DISABLED;
9650 		} else {
9651 			if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) {
9652 				dut->ap_txBF = 0;
9653 				dut->ap_mu_txBF = 0;
9654 			} else {
9655 				dut->ap_txBF = 1;
9656 				dut->ap_mu_txBF = 1;
9657 			}
9658 			dut->he_sounding = VALUE_ENABLED;
9659 			if (drv == DRIVER_LINUX_WCN) {
9660 				dut->ap_ldpc = VALUE_ENABLED;
9661 				wcn_config_ap_ldpc(dut, get_main_ifname(dut));
9662 #ifdef NL80211_SUPPORT
9663 				if (wcn_set_he_ltf(dut, get_main_ifname(dut),
9664 						   QCA_WLAN_HE_LTF_AUTO)) {
9665 					sigma_dut_print(dut, DUT_MSG_ERROR,
9666 							"Failed to set LTF in ap_reset_default");
9667 				}
9668 #endif /* NL80211_SUPPORT */
9669 			}
9670 		}
9671 		if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9672 			dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
9673 	}
9674 
9675 	memset(&dut->hw_modes, 0, sizeof(struct dut_hw_modes));
9676 #ifdef NL80211_SUPPORT
9677 	if (get_driver_type(dut) == DRIVER_MAC80211 && mac80211_get_wiphy(dut))
9678 		sigma_dut_print(dut, DUT_MSG_DEBUG,
9679 				"Failed to get wiphy data from the driver");
9680 #endif /* NL80211_SUPPORT */
9681 
9682 	dut->ap_oper_chn = 0;
9683 
9684 	dut->ap_pmksa = 0;
9685 	dut->ap_pmksa_caching = 0;
9686 
9687 	free(dut->rsne_override);
9688 	dut->rsne_override = NULL;
9689 	free(dut->rsnxe_override_eapol);
9690 	dut->rsnxe_override_eapol = NULL;
9691 
9692 	free(dut->sae_commit_override);
9693 	dut->sae_commit_override = NULL;
9694 
9695 	free(dut->ap_sae_groups);
9696 	dut->ap_sae_groups = NULL;
9697 
9698 	dut->sae_anti_clogging_threshold = -1;
9699 	dut->sae_reflection = 0;
9700 	dut->ap_sae_commit_status = -1;
9701 	dut->ap_sae_pk_omit = 0;
9702 	dut->sae_confirm_immediate = 0;
9703 	dut->sae_pwe = SAE_PWE_DEFAULT;
9704 
9705 	dut->ap_cipher = AP_CCMP;
9706 	dut->ap_group_cipher = AP_NO_GROUP_CIPHER_SET;
9707 	dut->ap_group_mgmt_cipher = AP_NO_GROUP_MGMT_CIPHER_SET;
9708 	dut->ap_passphrase[0] = '\0';
9709 	dut->ap_psk[0] = '\0';
9710 	dut->ap_beacon_prot = 0;
9711 	dut->ap_transition_disable = 0;
9712 
9713 	dut->dpp_conf_id = -1;
9714 	free(dut->ap_dpp_conf_addr);
9715 	dut->ap_dpp_conf_addr = NULL;
9716 	free(dut->ap_dpp_conf_pkhash);
9717 	dut->ap_dpp_conf_pkhash = NULL;
9718 	dut->ap_start_disabled = 0;
9719 
9720 	if (is_60g_sigma_dut(dut)) {
9721 		dut->ap_mode = AP_11ad;
9722 		dut->ap_channel = 2;
9723 		dut->wps_disable = 0; /* WPS is enabled */
9724 		dut->ap_pmf = 0;
9725 		dut->ap_num_ese_allocs = 0;
9726 		dut->ap_fixed_rate = 0;
9727 
9728 		dut->dev_role = DEVROLE_AP;
9729 
9730 		sigma_dut_print(dut, DUT_MSG_DEBUG,
9731 				"Setting msdu_size to MAX: 7912");
9732 		snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
9733 			 get_main_ifname(dut));
9734 
9735 		if (system(buf) != 0) {
9736 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9737 					buf);
9738 			return ERROR_SEND_STATUS;
9739 		}
9740 
9741 		if (ap_set_force_mcs(dut, 0, 1)) {
9742 			sigma_dut_print(dut, DUT_MSG_ERROR,
9743 					"Failed to reset force MCS");
9744 			return ERROR_SEND_STATUS;
9745 		}
9746 
9747 		if (set_ps(get_main_ifname(dut), dut, 1)) {
9748 			sigma_dut_print(dut, DUT_MSG_ERROR,
9749 					"Failed to enable power save");
9750 			return ERROR_SEND_STATUS;
9751 		}
9752 	}
9753 
9754 	if (dut->program == PROGRAM_WPS &&
9755 	    get_driver_type(dut) == DRIVER_WIL6210) {
9756 		/*
9757 		 * In 60 GHz WPS tests, we configure the AP OOB to
9758 		 * secure connection with a random passphrase.
9759 		 */
9760 		char r[16], passphrase[65];
9761 
9762 		if (random_get_bytes(r, sizeof(r))) {
9763 			sigma_dut_print(dut, DUT_MSG_ERROR,
9764 					"Failed to get random bytes");
9765 			return ERROR_SEND_STATUS;
9766 		}
9767 		if (base64_encode(r, sizeof(r),
9768 				  passphrase, sizeof(passphrase))) {
9769 			sigma_dut_print(dut, DUT_MSG_ERROR,
9770 					"Failed to generate random passphrase");
9771 			return ERROR_SEND_STATUS;
9772 		}
9773 
9774 		dut->ap_key_mgmt = AP_WPA2_PSK;
9775 		dut->ap_cipher = AP_GCMP_128;
9776 		strlcpy(dut->ap_passphrase, passphrase,
9777 			sizeof(dut->ap_passphrase));
9778 		sigma_dut_print(dut, DUT_MSG_DEBUG,
9779 				"60G WPS: configure secure AP with random passphrase");
9780 	}
9781 
9782 	dut->hostapd_running = 0;
9783 
9784 	if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9785 		return 1;
9786 
9787 	if (dut->use_hostapd_pid_file) {
9788 		kill_hostapd_process_pid(dut);
9789 	} else if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
9790 		   system("killall hostapd") == 0) {
9791 		int i;
9792 		/* Wait some time to allow hostapd to complete cleanup before
9793 		 * starting a new process */
9794 		for (i = 0; i < 10; i++) {
9795 			usleep(500000);
9796 			if (system("pidof hostapd") != 0)
9797 				break;
9798 		}
9799 	}
9800 
9801 	if (if_nametoindex("sigmadut") > 0 &&
9802 	    system("iw dev sigmadut del") != 0)
9803 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove "
9804 				"monitor interface");
9805 
9806 	return 1;
9807 }
9808 
9809 
sta_cfon_reset_default(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9810 int sta_cfon_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
9811 			   struct sigma_cmd *cmd)
9812 {
9813 	return cmd_ap_reset_default(dut, conn, cmd);
9814 }
9815 
9816 
cmd_ap_get_info(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9817 static enum sigma_cmd_result cmd_ap_get_info(struct sigma_dut *dut,
9818 					     struct sigma_conn *conn,
9819 					     struct sigma_cmd *cmd)
9820 {
9821 	/* const char *name = get_param(cmd, "NAME"); */
9822 	struct stat s;
9823 	char resp[200];
9824 	FILE *f;
9825 	enum driver_type drv = get_driver_type(dut);
9826 	int res;
9827 
9828 	switch (drv) {
9829 	case DRIVER_ATHEROS: {
9830 		/* Atheros AP */
9831 		struct utsname uts;
9832 		char *version, athver[100];
9833 
9834 		if (stat("/proc/athversion", &s) != 0) {
9835 			if (system("/etc/rc.d/rc.wlan up") != 0) {
9836 			}
9837 		}
9838 
9839 		athver[0] = '\0';
9840 		f = fopen("/proc/athversion", "r");
9841 		if (f) {
9842 			if (fgets(athver, sizeof(athver), f)) {
9843 				char *pos = strchr(athver, '\n');
9844 				if (pos)
9845 					*pos = '\0';
9846 			}
9847 			fclose(f);
9848 		}
9849 
9850 		if (uname(&uts) == 0)
9851 			version = uts.release;
9852 		else
9853 			version = "Unknown";
9854 
9855 		if (if_nametoindex("ath1") > 0)
9856 			res = snprintf(resp, sizeof(resp),
9857 				       "interface,ath0_24G ath1_5G,agent,1.0,version,%s/drv:%s",
9858 				       version, athver);
9859 		else
9860 			res = snprintf(resp, sizeof(resp),
9861 				       "interface,ath0_24G,agent,1.0,version,%s/drv:%s",
9862 				       version, athver);
9863 		if (res < 0 || res >= sizeof(resp))
9864 			send_resp(dut, conn, SIGMA_ERROR, NULL);
9865 		else
9866 			send_resp(dut, conn, SIGMA_COMPLETE, resp);
9867 		return 0;
9868 	}
9869 	case DRIVER_LINUX_WCN:
9870 	case DRIVER_MAC80211: {
9871 		struct utsname uts;
9872 		char *version;
9873 
9874 		if (uname(&uts) == 0)
9875 			version = uts.release;
9876 		else
9877 			version = "Unknown";
9878 
9879 		if (if_nametoindex("wlan1") > 0)
9880 			snprintf(resp, sizeof(resp), "interface,wlan0_24G "
9881 				 "wlan1_5G,agent,1.0,version,%s", version);
9882 		else
9883 			snprintf(resp, sizeof(resp), "interface,wlan0_any,"
9884 				 "agent,1.0,version,%s", version);
9885 
9886 		send_resp(dut, conn, SIGMA_COMPLETE, resp);
9887 		return 0;
9888 	}
9889 	case DRIVER_QNXNTO: {
9890 		struct utsname uts;
9891 		char *version;
9892 
9893 		if (uname(&uts) == 0)
9894 			version = uts.release;
9895 		else
9896 			version = "Unknown";
9897 		snprintf(resp, sizeof(resp),
9898 			 "interface,%s_any,agent,1.0,version,%s",
9899 			 dut->main_ifname ? get_main_ifname(dut) : "NA",
9900 			 version);
9901 		send_resp(dut, conn, SIGMA_COMPLETE, resp);
9902 		return 0;
9903 	}
9904 	case DRIVER_OPENWRT: {
9905 		switch (get_openwrt_driver_type()) {
9906 		case OPENWRT_DRIVER_ATHEROS: {
9907 			struct utsname uts;
9908 			char *version;
9909 
9910 			if (uname(&uts) == 0)
9911 				version = uts.release;
9912 			else
9913 				version = "Unknown";
9914 
9915 			if (if_nametoindex("ath1") > 0)
9916 				snprintf(resp, sizeof(resp),
9917 					 "interface,ath0_5G ath1_24G,agent,1.0,version,%s",
9918 					 version);
9919 			else
9920 				snprintf(resp, sizeof(resp),
9921 					 "interface,ath0_any,agent,1.0,version,%s",
9922 					 version);
9923 
9924 			send_resp(dut, conn, SIGMA_COMPLETE, resp);
9925 			return 0;
9926 		}
9927 		default:
9928 			send_resp(dut, conn, SIGMA_ERROR,
9929 				  "errorCode,Unsupported openwrt driver");
9930 			return 0;
9931 		}
9932 	}
9933 	default:
9934 		send_resp(dut, conn, SIGMA_ERROR,
9935 			  "errorCode,Unsupported driver");
9936 		return 0;
9937 	}
9938 }
9939 
9940 
cmd_ap_deauth_sta(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9941 static enum sigma_cmd_result cmd_ap_deauth_sta(struct sigma_dut *dut,
9942 					       struct sigma_conn *conn,
9943 					       struct sigma_cmd *cmd)
9944 {
9945 	/* const char *name = get_param(cmd, "NAME"); */
9946 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
9947 	const char *val, *disconnect;
9948 	char buf[100];
9949 
9950 	val = get_param(cmd, "MinorCode");
9951 	if (val) {
9952 		/* TODO: add support for P2P minor code */
9953 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,MinorCode not "
9954 			  "yet supported");
9955 		return 0;
9956 	}
9957 
9958 	val = get_param(cmd, "STA_MAC_ADDRESS");
9959 	if (val == NULL)
9960 		return -1;
9961 	disconnect = get_param(cmd, "disconnect");
9962 	if (disconnect && strcasecmp(disconnect, "silent") == 0)
9963 		snprintf(buf, sizeof(buf), "deauth %s tx=0", val);
9964 	else
9965 		snprintf(buf, sizeof(buf), "deauth %s", val);
9966 	if (run_hostapd_cli(dut, buf) != 0)
9967 		return -2;
9968 
9969 	return 1;
9970 }
9971 
9972 
9973 #ifdef __linux__
9974 int inject_frame(int s, const void *data, size_t len, int encrypt);
9975 int open_monitor(const char *ifname);
9976 #endif /* __linux__ */
9977 
9978 enum send_frame_type {
9979 		DISASSOC, DEAUTH, SAQUERY
9980 };
9981 enum send_frame_protection {
9982 	CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9983 };
9984 
9985 
ap_inject_frame(struct sigma_dut * dut,struct sigma_conn * conn,enum send_frame_type frame,enum send_frame_protection protected,const char * sta_addr)9986 static int ap_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9987 			   enum send_frame_type frame,
9988 			   enum send_frame_protection protected,
9989 			   const char *sta_addr)
9990 {
9991 #ifdef __linux__
9992 	unsigned char buf[1000], *pos;
9993 	int s, res;
9994 	unsigned char addr_sta[6], addr_own[6];
9995 	char *ifname;
9996 	char cbuf[100];
9997 	struct ifreq ifr;
9998 
9999 	if ((dut->ap_mode == AP_11a || dut->ap_mode == AP_11na ||
10000 	     dut->ap_mode == AP_11ac) &&
10001 	    if_nametoindex("wlan1") > 0)
10002 		ifname = "wlan1";
10003 	else
10004 		ifname = "wlan0";
10005 
10006 	if (hwaddr_aton(sta_addr, addr_sta) < 0)
10007 		return -1;
10008 
10009 	s = socket(AF_INET, SOCK_DGRAM, 0);
10010 	if (s < 0)
10011 		return -1;
10012 	memset(&ifr, 0, sizeof(ifr));
10013 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10014 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
10015 		perror("ioctl");
10016 		close(s);
10017 		return -1;
10018 	}
10019 	close(s);
10020 	memcpy(addr_own, ifr.ifr_hwaddr.sa_data, 6);
10021 
10022 	if (if_nametoindex("sigmadut") == 0) {
10023 		snprintf(cbuf, sizeof(cbuf),
10024 			 "iw dev %s interface add sigmadut type monitor",
10025 			 ifname);
10026 		if (system(cbuf) != 0 ||
10027 		    if_nametoindex("sigmadut") == 0) {
10028 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10029 					"monitor interface with '%s'", cbuf);
10030 			return -2;
10031 		}
10032 	}
10033 
10034 	if (system("ifconfig sigmadut up") != 0) {
10035 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10036 				"monitor interface up");
10037 		return -2;
10038 	}
10039 
10040 	pos = buf;
10041 
10042 	/* Frame Control */
10043 	switch (frame) {
10044 	case DISASSOC:
10045 		*pos++ = 0xa0;
10046 		break;
10047 	case DEAUTH:
10048 		*pos++ = 0xc0;
10049 		break;
10050 	case SAQUERY:
10051 		*pos++ = 0xd0;
10052 		break;
10053 	}
10054 
10055 	if (protected == INCORRECT_KEY)
10056 		*pos++ = 0x40; /* Set Protected field to 1 */
10057 	else
10058 		*pos++ = 0x00;
10059 
10060 	/* Duration */
10061 	*pos++ = 0x00;
10062 	*pos++ = 0x00;
10063 
10064 	/* addr1 = DA (station) */
10065 	memcpy(pos, addr_sta, 6);
10066 	pos += 6;
10067 	/* addr2 = SA (own address) */
10068 	memcpy(pos, addr_own, 6);
10069 	pos += 6;
10070 	/* addr3 = BSSID (own address) */
10071 	memcpy(pos, addr_own, 6);
10072 	pos += 6;
10073 
10074 	/* Seq# (to be filled by driver/mac80211) */
10075 	*pos++ = 0x00;
10076 	*pos++ = 0x00;
10077 
10078 	if (protected == INCORRECT_KEY) {
10079 		/* CCMP parameters */
10080 		memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
10081 		pos += 8;
10082 	}
10083 
10084 	if (protected == INCORRECT_KEY) {
10085 		switch (frame) {
10086 		case DEAUTH:
10087 			/* Reason code (encrypted) */
10088 			memcpy(pos, "\xa7\x39", 2);
10089 			pos += 2;
10090 			break;
10091 		case DISASSOC:
10092 			/* Reason code (encrypted) */
10093 			memcpy(pos, "\xa7\x39", 2);
10094 			pos += 2;
10095 			break;
10096 		case SAQUERY:
10097 			/* Category|Action|TransID (encrypted) */
10098 			memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
10099 			pos += 4;
10100 			break;
10101 		default:
10102 			return -1;
10103 		}
10104 
10105 		/* CCMP MIC */
10106 		memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
10107 		pos += 8;
10108 	} else {
10109 		switch (frame) {
10110 		case DEAUTH:
10111 			/* reason code = 8 */
10112 			*pos++ = 0x08;
10113 			*pos++ = 0x00;
10114 			break;
10115 		case DISASSOC:
10116 			/* reason code = 8 */
10117 			*pos++ = 0x08;
10118 			*pos++ = 0x00;
10119 			break;
10120 		case SAQUERY:
10121 			/* Category - SA Query */
10122 			*pos++ = 0x08;
10123 			/* SA query Action - Request */
10124 			*pos++ = 0x00;
10125 			/* Transaction ID */
10126 			*pos++ = 0x12;
10127 			*pos++ = 0x34;
10128 			break;
10129 		}
10130 	}
10131 
10132 	s = open_monitor("sigmadut");
10133 	if (s < 0) {
10134 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
10135 			  "monitor socket");
10136 		return 0;
10137 	}
10138 
10139 	res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
10140 	if (res < 0) {
10141 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
10142 			  "inject frame");
10143 		close(s);
10144 		return 0;
10145 	}
10146 	if (res < pos - buf) {
10147 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
10148 			  "frame sent");
10149 		close(s);
10150 		return 0;
10151 	}
10152 
10153 	close(s);
10154 
10155 	return 1;
10156 #else /* __linux__ */
10157 	send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_send_frame not "
10158 		  "yet supported");
10159 	return 0;
10160 #endif /* __linux__ */
10161 }
10162 
10163 
ap_send_frame_hs2(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10164 int ap_send_frame_hs2(struct sigma_dut *dut, struct sigma_conn *conn,
10165 		      struct sigma_cmd *cmd)
10166 {
10167 	const char *val, *dest;
10168 	char buf[100];
10169 
10170 	val = get_param(cmd, "FrameName");
10171 	if (val == NULL)
10172 		return -1;
10173 
10174 	if (strcasecmp(val, "QoSMapConfigure") == 0) {
10175 		dest = get_param(cmd, "Dest");
10176 		if (!dest)
10177 			return -1;
10178 
10179 		val = get_param(cmd, "QoS_MAP_SET");
10180 		if (val) {
10181 			dut->ap_qos_map_set = atoi(val);
10182 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
10183 					dut->ap_qos_map_set);
10184 		}
10185 
10186 		if (dut->ap_qos_map_set == 1)
10187 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1);
10188 		else if (dut->ap_qos_map_set == 2)
10189 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2);
10190 
10191 		snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest);
10192 		if (run_hostapd_cli(dut, buf) != 0)
10193 			return -1;
10194 	}
10195 
10196 	return 1;
10197 }
10198 
10199 
ath_ap_send_frame_vht(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10200 static int ath_ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10201 				 struct sigma_cmd *cmd)
10202 {
10203 	const char *val;
10204 	const char *ifname;
10205 	int chwidth, nss;
10206 
10207 	val = get_param(cmd, "FrameName");
10208 	if (!val || strcasecmp(val, "op_md_notif_frm") != 0) {
10209 		send_resp(dut, conn, SIGMA_ERROR,
10210 			  "errorCode,Unsupported FrameName");
10211 		return 0;
10212 	}
10213 
10214 	/*
10215 	 * Sequence of commands for Opmode notification on
10216 	 * Peregrine based products
10217 	 */
10218 	ifname = get_main_ifname(dut);
10219 
10220 	/* Disable STBC */
10221 	run_iwpriv(dut, ifname, "tx_stbc 0");
10222 
10223 	/* Check whether optional arg channel width was passed */
10224 	val = get_param(cmd, "Channel_width");
10225 	if (val) {
10226 		switch (atoi(val)) {
10227 		case 20:
10228 			chwidth = 0;
10229 			break;
10230 		case 40:
10231 			chwidth = 1;
10232 			break;
10233 		case 80:
10234 			chwidth = 2;
10235 			break;
10236 		case 160:
10237 			chwidth = 3;
10238 			break;
10239 		default:
10240 			chwidth = 2;
10241 			break;
10242 		}
10243 		run_iwpriv(dut, ifname, "chwidth %d", chwidth);
10244 	}
10245 
10246 	/* Check whether optional arg NSS was passed */
10247 	val = get_param(cmd, "NSS");
10248 	if (val) {
10249 		/* Convert nss to chainmask */
10250 		switch (atoi(val)) {
10251 		case 1:
10252 			nss = 1;
10253 			break;
10254 		case 2:
10255 			nss = 3;
10256 			break;
10257 		case 3:
10258 			nss = 7;
10259 			break;
10260 		default:
10261 			/* We do not support NSS > 3 */
10262 			nss = 3;
10263 			break;
10264 		}
10265 		run_iwpriv(dut, ifname, "rxchainmask %d", nss);
10266 	}
10267 
10268 	/* Send the opmode notification */
10269 	run_iwpriv(dut, ifname, "opmode_notify 1");
10270 
10271 	return 1;
10272 }
10273 
10274 
ath_ap_send_frame_loc(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10275 static int ath_ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn,
10276 				 struct sigma_cmd *cmd)
10277 {
10278 	const char *val;
10279 	FILE *f;
10280 	int rand_int = 0;
10281 
10282 	val = get_param(cmd, "MsntType");
10283 	if (val) {
10284 		if (dut->ap_msnt_type == 0)
10285 			dut->ap_msnt_type = atoi(val);
10286 
10287 		if (dut->ap_msnt_type != 5 && dut->ap_msnt_type != 2) {
10288 			dut->ap_msnt_type = atoi(val);
10289 			if (dut->ap_msnt_type == 1) {
10290 				val = get_param(cmd, "RandInterval");
10291 				if (val)
10292 					rand_int = atoi(val);
10293 				f = fopen("/tmp/ftmrr.txt", "a");
10294 				if (!f) {
10295 					sigma_dut_print(dut, DUT_MSG_ERROR,
10296 							"Failed to open /tmp/ftmrr.txt");
10297 					return -1;
10298 				}
10299 
10300 				fprintf(f, "sta_mac = %s\n", cmd->values[3]);
10301 				fprintf(f, "meas_type = 0x10\nrand_inter = 0x%x\nmin_ap_count = 0x%s\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0xf\nmeas_req_mode = 0x00\n",
10302 					rand_int, cmd->values[7]);
10303 				fclose(f);
10304 				dut->ap_msnt_type = 5;
10305 				run_system(dut, "wpc -f /tmp/ftmrr.txt");
10306 			}
10307 		} else if (dut->ap_msnt_type == 5) {
10308 			run_system(dut, "wpc -f /tmp/ftmrr.txt");
10309 		} else if (dut->ap_msnt_type == 2) {
10310 			f = fopen("/tmp/wru.txt", "w");
10311 			if (!f) {
10312 				sigma_dut_print(dut, DUT_MSG_ERROR,
10313 						"Failed to open /tmp/wru.txt");
10314 				return -1;
10315 			}
10316 
10317 			fprintf(f, "sta_mac = %s\n", cmd->values[3]);
10318 			fprintf(f, "meas_type = 0x08\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0x1\nmeas_req_mode = 0x00\nloc_subject = 0x01\n");
10319 			fclose(f);
10320 			run_system(dut, "wpc -w /tmp/wru.txt");
10321 		}
10322 	}
10323 	return 1;
10324 }
10325 
10326 
10327 /*
10328  * The following functions parse_send_frame_params_int(),
10329  * parse_send_frame_params_str(), and parse_send_frame_params_mac()
10330  * are used by ath_ap_send_frame_bcn_rpt_req().
10331  * Beacon Report Request is a frame used as part of the MBO program.
10332  * The command for sending beacon report has a lot of
10333  * arguments and having these functions reduces code size.
10334  *
10335  */
parse_send_frame_params_int(char * param,struct sigma_cmd * cmd,struct sigma_dut * dut,char * buf,size_t buf_size)10336 static int parse_send_frame_params_int(char *param, struct sigma_cmd *cmd,
10337 				       struct sigma_dut *dut,
10338 				       char *buf, size_t buf_size)
10339 {
10340 	const char *str_val;
10341 	int int_val;
10342 	char temp[100];
10343 
10344 	str_val = get_param(cmd, param);
10345 	if (!str_val) {
10346 		sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
10347 		return -1;
10348 	}
10349 	int_val = atoi(str_val);
10350 	snprintf(temp, sizeof(temp), " %d", int_val);
10351 	strlcat(buf, temp, buf_size);
10352 	return 0;
10353 }
10354 
10355 
parse_send_frame_params_str(char * param,struct sigma_cmd * cmd,struct sigma_dut * dut,char * buf,size_t buf_size)10356 static int parse_send_frame_params_str(char *param, struct sigma_cmd *cmd,
10357 				       struct sigma_dut *dut,
10358 				       char *buf, size_t buf_size)
10359 {
10360 	const char *str_val;
10361 	char temp[100];
10362 
10363 	str_val = get_param(cmd, param);
10364 	if (!str_val) {
10365 		sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
10366 		return -1;
10367 	}
10368 	snprintf(temp, sizeof(temp), " %s", str_val);
10369 	temp[sizeof(temp) - 1] = '\0';
10370 	strlcat(buf, temp, buf_size);
10371 	return 0;
10372 }
10373 
10374 
parse_send_frame_params_mac(char * param,struct sigma_cmd * cmd,struct sigma_dut * dut,char * buf,size_t buf_size)10375 static int parse_send_frame_params_mac(char *param, struct sigma_cmd *cmd,
10376 				       struct sigma_dut *dut,
10377 				       char *buf, size_t buf_size)
10378 {
10379 	const char *str_val;
10380 	unsigned char mac[6];
10381 	char temp[100];
10382 
10383 	str_val = get_param(cmd, param);
10384 	if (!str_val) {
10385 		sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
10386 		return -1;
10387 	}
10388 
10389 	if (parse_mac_address(dut, str_val, mac) < 0) {
10390 		sigma_dut_print(dut, DUT_MSG_ERROR,
10391 				"MAC Address not in proper format");
10392 		return -1;
10393 	}
10394 	snprintf(temp, sizeof(temp), " %02x:%02x:%02x:%02x:%02x:%02x",
10395 		 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
10396 	strlcat(buf, temp, buf_size);
10397 	return 0;
10398 }
10399 
10400 
fill_1_or_0_based_on_presence(struct sigma_cmd * cmd,char * param,char * buf,size_t buf_size)10401 static void fill_1_or_0_based_on_presence(struct sigma_cmd *cmd, char *param,
10402 					  char *buf, size_t buf_size)
10403 {
10404 	const char *str_val;
10405 	char *value = " 1";
10406 
10407 	str_val = get_param(cmd, param);
10408 	if (!str_val || str_val[0] == '\0')
10409 		value = " 0";
10410 	strlcat(buf, value, buf_size);
10411 
10412 }
10413 
10414 
10415 /*
10416  * wifitool athN sendbcnrpt
10417  * <STA MAC        - Plugs in from Dest_MAC>
10418  * <regclass       - Plugs in from RegClass - int>
10419  * <channum        - Plugs in from Channel PARAM of dev_send_frame - int>
10420  * <rand_ivl       - Plugs in from RandInt - string>
10421  * <duration       - Plugs in from MeaDur - integer>
10422  * <mode           - Plugs in from MeaMode - string>
10423  * <req_ssid       - Plugs in from SSID PARAM of dev_send_frame - string>
10424  * <rep_cond       - Plugs in from RptCond - integer>
10425  * <rpt_detail     - Plugs in from RptDet - integer>
10426  * <req_ie         - Plugs in from ReqInfo PARAM of dev_send_frame - string>
10427  * <chanrpt_mode   - Plugs in from APChanRpt - integer>
10428  * <specific_bssid - Plugs in from BSSID PARAM of dev_send_frame>
10429  * [AP channel numbers]
10430  */
ath_ap_send_frame_bcn_rpt_req(struct sigma_dut * dut,struct sigma_cmd * cmd,const char * ifname)10431 static int ath_ap_send_frame_bcn_rpt_req(struct sigma_dut *dut,
10432 					 struct sigma_cmd *cmd,
10433 					 const char *ifname)
10434 {
10435 	char buf[100];
10436 	int rpt_det;
10437 	const char *str_val;
10438 	const char *mea_mode;
10439 
10440 	snprintf(buf, sizeof(buf), "wifitool %s sendbcnrpt", ifname);
10441 
10442 	if (parse_send_frame_params_mac("Dest_MAC", cmd, dut, buf, sizeof(buf)))
10443 		return -1;
10444 	if (parse_send_frame_params_int("RegClass", cmd, dut, buf, sizeof(buf)))
10445 		return -1;
10446 	if (parse_send_frame_params_int("Channel", cmd, dut, buf, sizeof(buf)))
10447 		return -1;
10448 	if (parse_send_frame_params_str("RandInt", cmd, dut, buf, sizeof(buf)))
10449 		return -1;
10450 	if (parse_send_frame_params_int("MeaDur", cmd, dut, buf, sizeof(buf)))
10451 		return -1;
10452 
10453 	str_val = get_param(cmd, "MeaMode");
10454 	if (!str_val) {
10455 		sigma_dut_print(dut, DUT_MSG_ERROR,
10456 				"MeaMode parameter not present in send bcn-rpt-req");
10457 		return -1;
10458 	}
10459 	if (strcasecmp(str_val, "passive") == 0) {
10460 		mea_mode = " 0";
10461 	} else if (strcasecmp(str_val, "active") == 0) {
10462 		mea_mode = " 1";
10463 	} else if (strcasecmp(str_val, "table") == 0) {
10464 		mea_mode = " 2";
10465 	} else {
10466 		sigma_dut_print(dut, DUT_MSG_ERROR,
10467 				"MEA-MODE Value not correctly given");
10468 		return -1;
10469 	}
10470 	strlcat(buf, mea_mode, sizeof(buf));
10471 
10472 	fill_1_or_0_based_on_presence(cmd, "SSID", buf, sizeof(buf));
10473 
10474 	if (parse_send_frame_params_int("RptCond", cmd, dut, buf, sizeof(buf)))
10475 		return -1;
10476 
10477 	if (parse_send_frame_params_int("RptDet", cmd, dut, buf, sizeof(buf)))
10478 		return -1;
10479 	str_val = get_param(cmd, "RptDet");
10480 	rpt_det = str_val ? atoi(str_val) : 0;
10481 
10482 	if (rpt_det)
10483 		fill_1_or_0_based_on_presence(cmd, "ReqInfo", buf, sizeof(buf));
10484 	else
10485 		strlcat(buf, " 0", sizeof(buf));
10486 
10487 	if (rpt_det)
10488 		fill_1_or_0_based_on_presence(cmd, "APChanRpt", buf,
10489 					      sizeof(buf));
10490 	else
10491 		strlcat(buf, " 0", sizeof(buf));
10492 
10493 	if (parse_send_frame_params_mac("BSSID", cmd, dut, buf, sizeof(buf)))
10494 		return -1;
10495 
10496 	str_val = get_param(cmd, "APChanRpt");
10497 	if (str_val) {
10498 		const char *pos;
10499 		int ap_chanrpt;
10500 		int ap_chanrpt_2 = 0;
10501 		char chanrpt[100];
10502 
10503 		ap_chanrpt = atoi(str_val);
10504 		pos = strchr(str_val, '_');
10505 		if (pos) {
10506 			pos++;
10507 			ap_chanrpt_2 = atoi(pos);
10508 		}
10509 		if (ap_chanrpt) {
10510 			snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt);
10511 			strlcat(buf, chanrpt, sizeof(buf));
10512 		}
10513 		if (ap_chanrpt_2) {
10514 			snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt_2);
10515 			strlcat(buf, chanrpt, sizeof(buf));
10516 		}
10517 	}
10518 
10519 	run_system(dut, buf);
10520 	return 0;
10521 }
10522 
10523 
inform_and_sleep(struct sigma_dut * dut,int seconds)10524 static void inform_and_sleep(struct sigma_dut *dut, int seconds)
10525 {
10526 	sigma_dut_print(dut, DUT_MSG_DEBUG, "sleeping for %d seconds", seconds);
10527 	sleep(seconds);
10528 	sigma_dut_print(dut, DUT_MSG_DEBUG, "woke up after %d seconds",
10529 			seconds);
10530 }
10531 
10532 
ath_ap_send_frame_btm_req(struct sigma_dut * dut,struct sigma_cmd * cmd,const char * ifname)10533 static int ath_ap_send_frame_btm_req(struct sigma_dut *dut,
10534 				     struct sigma_cmd *cmd, const char *ifname)
10535 {
10536 	unsigned char mac_addr[ETH_ALEN];
10537 	int disassoc_timer;
10538 	char buf[100];
10539 	const char *val;
10540 	int cand_list = 1;
10541 
10542 	val = get_param(cmd, "Dest_MAC");
10543 	if (!val || parse_mac_address(dut, val, mac_addr) < 0) {
10544 		sigma_dut_print(dut, DUT_MSG_ERROR,
10545 				"MAC Address not in proper format");
10546 		return -1;
10547 	}
10548 
10549 	val = get_param(cmd, "Disassoc_Timer");
10550 	if (val)
10551 		disassoc_timer = atoi(val);
10552 	else
10553 		disassoc_timer = dut->ap_disassoc_timer;
10554 	if (disassoc_timer < 0) {
10555 		sigma_dut_print(dut, DUT_MSG_ERROR,
10556 				"Invalid Disassoc_Timer value %d",
10557 				disassoc_timer);
10558 		return -1;
10559 	}
10560 
10561 	val = get_param(cmd, "Cand_List");
10562 	if (val && val[0])
10563 		cand_list = atoi(val);
10564 
10565 	val = get_param(cmd, "BTMQuery_Reason_Code");
10566 	if (val)
10567 		run_iwpriv(dut, ifname, "mbo_trans_rs %s", val);
10568 
10569 	if (dut->ap_btmreq_disassoc_imnt && !dut->ap_assoc_delay)
10570 		run_iwpriv(dut, ifname, "mbo_asoc_ret 1");
10571 
10572 	snprintf(buf, sizeof(buf),
10573 		 "wifitool %s sendbstmreq %02x:%02x:%02x:%02x:%02x:%02x %d %d 15 %d %d %d %d",
10574 		 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
10575 		 mac_addr[4], mac_addr[5], cand_list, disassoc_timer,
10576 		 dut->ap_btmreq_disassoc_imnt,
10577 		 dut->ap_btmreq_term_bit,
10578 		 dut->ap_btmreq_bss_term_tsf,
10579 		 dut->ap_btmreq_bss_term_dur);
10580 	run_system(dut, buf);
10581 
10582 	if (dut->ap_btmreq_term_bit) {
10583 		if (dut->ap_btmreq_bss_term_tsf >= 2)
10584 			inform_and_sleep(dut, dut->ap_btmreq_bss_term_tsf - 2);
10585 		run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10586 			   mac_addr[0], mac_addr[1], mac_addr[2],
10587 			   mac_addr[3], mac_addr[4], mac_addr[5]);
10588 		inform_and_sleep(dut, 2);
10589 		run_system_wrapper(dut, "ifconfig %s down", ifname);
10590 		inform_and_sleep(dut, 5);
10591 		run_system_wrapper(dut, "ifconfig %s up", ifname);
10592 	} else if (dut->ap_btmreq_disassoc_imnt) {
10593 		inform_and_sleep(dut, (disassoc_timer / 1000) + 1);
10594 		run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10595 			   mac_addr[0], mac_addr[1], mac_addr[2],
10596 			   mac_addr[3], mac_addr[4], mac_addr[5]);
10597 	}
10598 	return 0;
10599 }
10600 
10601 
ath_ap_send_frame_disassoc(struct sigma_dut * dut,struct sigma_cmd * cmd,const char * ifname)10602 static int ath_ap_send_frame_disassoc(struct sigma_dut *dut,
10603 				      struct sigma_cmd *cmd, const char *ifname)
10604 {
10605 	unsigned char mac_addr[ETH_ALEN];
10606 	const char *val;
10607 
10608 	val = get_param(cmd, "Dest_MAC");
10609 	if (!val || parse_mac_address(dut, val, mac_addr) < 0) {
10610 		sigma_dut_print(dut, DUT_MSG_ERROR,
10611 				"MAC Address not in proper format");
10612 		return -1;
10613 	}
10614 
10615 	run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10616 		   mac_addr[0], mac_addr[1], mac_addr[2],
10617 		   mac_addr[3], mac_addr[4], mac_addr[5]);
10618 	return 0;
10619 }
10620 
10621 
ath_ap_send_frame_mbo(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10622 static int ath_ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn,
10623 				 struct sigma_cmd *cmd)
10624 {
10625 	const char *val;
10626 	const char *ifname;
10627 
10628 	ifname = get_main_ifname(dut);
10629 
10630 	val = get_param(cmd, "FrameName");
10631 	if (!val)
10632 		return -1;
10633 
10634 	if (strcasecmp(val, "BTMReq") == 0)
10635 		ath_ap_send_frame_btm_req(dut, cmd, ifname);
10636 	else if (strcasecmp(val, "BcnRptReq") == 0)
10637 		ath_ap_send_frame_bcn_rpt_req(dut, cmd, ifname);
10638 	else if (strcasecmp(val, "disassoc") == 0)
10639 		ath_ap_send_frame_disassoc(dut, cmd, ifname);
10640 	else
10641 		return -1;
10642 
10643 	return 1;
10644 }
10645 
10646 
ap_send_frame_vht(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10647 static int ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10648 			     struct sigma_cmd *cmd)
10649 {
10650 	switch (get_driver_type(dut)) {
10651 	case DRIVER_ATHEROS:
10652 		return ath_ap_send_frame_vht(dut, conn, cmd);
10653 		break;
10654 	case DRIVER_OPENWRT:
10655 		switch (get_openwrt_driver_type()) {
10656 		case OPENWRT_DRIVER_ATHEROS:
10657 			return ath_ap_send_frame_vht(dut, conn, cmd);
10658 		default:
10659 			send_resp(dut, conn, SIGMA_ERROR,
10660 				  "errorCode,Unsupported ap_send_frame with the current openwrt driver");
10661 			return 0;
10662 		}
10663 	default:
10664 		send_resp(dut, conn, SIGMA_ERROR,
10665 			  "errorCode,Unsupported ap_send_frame with the current driver");
10666 		return 0;
10667 	}
10668 }
10669 
10670 
ap_send_frame_loc(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10671 static int ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn,
10672 			     struct sigma_cmd *cmd)
10673 {
10674 	switch (get_driver_type(dut)) {
10675 	case DRIVER_ATHEROS:
10676 		return ath_ap_send_frame_loc(dut, conn, cmd);
10677 	case DRIVER_OPENWRT:
10678 		switch (get_openwrt_driver_type()) {
10679 		case OPENWRT_DRIVER_ATHEROS:
10680 			return ath_ap_send_frame_loc(dut, conn, cmd);
10681 		default:
10682 			send_resp(dut, conn, SIGMA_ERROR,
10683 				  "errorCode,Unsupported ap_send_frame_loc with the current openwrt driver");
10684 			return 0;
10685 		}
10686 	default:
10687 		send_resp(dut, conn, SIGMA_ERROR,
10688 			  "errorCode,Unsupported ap_send_frame_loc with the current driver");
10689 		return 0;
10690 	}
10691 }
10692 
10693 
ap_send_frame_mbo(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10694 static int ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn,
10695 			     struct sigma_cmd *cmd)
10696 {
10697 	switch (get_driver_type(dut)) {
10698 	case DRIVER_ATHEROS:
10699 		return ath_ap_send_frame_mbo(dut, conn, cmd);
10700 	case DRIVER_OPENWRT:
10701 		switch (get_openwrt_driver_type()) {
10702 		case OPENWRT_DRIVER_ATHEROS:
10703 			return ath_ap_send_frame_mbo(dut, conn, cmd);
10704 		default:
10705 			send_resp(dut, conn, SIGMA_ERROR,
10706 				  "errorCode,Unsupported ap_send_frame with the current openwrt driver");
10707 			return 0;
10708 		}
10709 	default:
10710 		send_resp(dut, conn, SIGMA_ERROR,
10711 			  "errorCode,Unsupported ap_send_frame with the current driver");
10712 		return 0;
10713 	}
10714 }
10715 
10716 
ap_send_frame_60g(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10717 static int ap_send_frame_60g(struct sigma_dut *dut,
10718 			     struct sigma_conn *conn,
10719 			     struct sigma_cmd *cmd)
10720 {
10721 	switch (get_driver_type(dut)) {
10722 #ifdef __linux__
10723 	case DRIVER_WIL6210:
10724 		return wil6210_send_frame_60g(dut, conn, cmd);
10725 #endif /* __linux__ */
10726 	default:
10727 		send_resp(dut, conn, SIGMA_ERROR,
10728 			  "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10729 		return 0;
10730 	}
10731 }
10732 
10733 
cmd_ap_send_frame(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10734 enum sigma_cmd_result cmd_ap_send_frame(struct sigma_dut *dut,
10735 					struct sigma_conn *conn,
10736 					struct sigma_cmd *cmd)
10737 {
10738 	/* const char *name = get_param(cmd, "NAME"); */
10739 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
10740 	const char *val;
10741 	enum send_frame_type frame;
10742 	enum send_frame_protection protected;
10743 	char buf[100];
10744 
10745 	val = get_param(cmd, "Program");
10746 	if (val) {
10747 		if (strcasecmp(val, "HS2") == 0 ||
10748 		    strcasecmp(val, "HS2-R2") == 0 ||
10749 		    strcasecmp(val, "IOTLP") == 0)
10750 			return ap_send_frame_hs2(dut, conn, cmd);
10751 		if (strcasecmp(val, "VHT") == 0)
10752 			return ap_send_frame_vht(dut, conn, cmd);
10753 		if (strcasecmp(val, "LOC") == 0)
10754 			return ap_send_frame_loc(dut, conn, cmd);
10755 		if (strcasecmp(val, "MBO") == 0)
10756 			return ap_send_frame_mbo(dut, conn, cmd);
10757 		if (strcasecmp(val, "60GHz") == 0)
10758 			return ap_send_frame_60g(dut, conn, cmd);
10759 	}
10760 
10761 	val = get_param(cmd, "PMFFrameType");
10762 	if (val == NULL)
10763 		val = get_param(cmd, "FrameName");
10764 	if (val == NULL)
10765 		val = get_param(cmd, "Type");
10766 	if (val == NULL)
10767 		return -1;
10768 	if (strcasecmp(val, "disassoc") == 0)
10769 		frame = DISASSOC;
10770 	else if (strcasecmp(val, "deauth") == 0)
10771 		frame = DEAUTH;
10772 	else if (strcasecmp(val, "saquery") == 0)
10773 		frame = SAQUERY;
10774 	else {
10775 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10776 			  "PMFFrameType");
10777 		return 0;
10778 	}
10779 
10780 	val = get_param(cmd, "PMFProtected");
10781 	if (val == NULL)
10782 		val = get_param(cmd, "Protected");
10783 	if (val == NULL)
10784 		return -1;
10785 	if (strcasecmp(val, "Correct-key") == 0 ||
10786 	    strcasecmp(val, "CorrectKey") == 0)
10787 		protected = CORRECT_KEY;
10788 	else if (strcasecmp(val, "IncorrectKey") == 0)
10789 		protected = INCORRECT_KEY;
10790 	else if (strcasecmp(val, "Unprotected") == 0)
10791 		protected = UNPROTECTED;
10792 	else {
10793 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10794 			  "PMFProtected");
10795 		return 0;
10796 	}
10797 
10798 	val = get_param(cmd, "stationID");
10799 	if (val == NULL)
10800 		return -1;
10801 
10802 	if (protected == INCORRECT_KEY ||
10803 	    (protected == UNPROTECTED && frame == SAQUERY))
10804 		return ap_inject_frame(dut, conn, frame, protected, val);
10805 
10806 	switch (frame) {
10807 	case DISASSOC:
10808 		snprintf(buf, sizeof(buf), "disassoc %s test=%d",
10809 			 val, protected == CORRECT_KEY);
10810 		break;
10811 	case DEAUTH:
10812 		snprintf(buf, sizeof(buf), "deauth %s test=%d",
10813 			 val, protected == CORRECT_KEY);
10814 		break;
10815 	case SAQUERY:
10816 		snprintf(buf, sizeof(buf), "sa_query %s", val);
10817 		break;
10818 	}
10819 
10820 	if (run_hostapd_cli(dut, buf) != 0)
10821 		return -2;
10822 
10823 	return 1;
10824 }
10825 
10826 
cmd_ap_get_mac_address(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10827 static enum sigma_cmd_result cmd_ap_get_mac_address(struct sigma_dut *dut,
10828 						    struct sigma_conn *conn,
10829 						    struct sigma_cmd *cmd)
10830 {
10831 #if defined( __linux__)
10832 	/* const char *name = get_param(cmd, "NAME"); */
10833 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
10834 	char resp[100];
10835 	unsigned char addr[6];
10836 	char ifname[50];
10837 	struct ifreq ifr;
10838 	int s, wlan_tag = 1;
10839 	const char *val;
10840 
10841 	val = get_param(cmd, "WLAN_TAG");
10842 	if (val) {
10843 		wlan_tag = atoi(val);
10844 		if (wlan_tag < 1 || wlan_tag > 3) {
10845 			/*
10846 			 * The only valid WLAN Tags as of now as per the latest
10847 			 * WFA scripts are 1, 2, and 3.
10848 			 */
10849 			send_resp(dut, conn, SIGMA_ERROR,
10850 				  "errorCode,Unsupported WLAN_TAG");
10851 			return 0;
10852 		}
10853 	}
10854 
10855 	get_if_name(dut, ifname, sizeof(ifname), wlan_tag);
10856 
10857 	s = socket(AF_INET, SOCK_DGRAM, 0);
10858 	if (s < 0)
10859 		return -1;
10860 	memset(&ifr, 0, sizeof(ifr));
10861 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10862 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
10863 		perror("ioctl");
10864 		close(s);
10865 		snprintf(resp, sizeof(resp),
10866 			 "errorCode,Could not find interface %s", ifname);
10867 		send_resp(dut, conn, SIGMA_ERROR, resp);
10868 		return 0;
10869 	}
10870 	close(s);
10871 	memcpy(addr, ifr.ifr_hwaddr.sa_data, 6);
10872 
10873 	snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x",
10874 		 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
10875 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
10876 	return 0;
10877 #elif defined( __QNXNTO__)
10878 	char resp[50];
10879 	unsigned char addr[6];
10880 
10881 	if (!dut->main_ifname) {
10882 		send_resp(dut, conn, SIGMA_ERROR, "ifname is null");
10883 		return 0;
10884 	}
10885 
10886 	if (get_hwaddr(get_main_ifname(dut), addr) != 0) {
10887 		send_resp(dut, conn, SIGMA_ERROR,
10888 			  "errorCode,Failed to get address");
10889 		return 0;
10890 	}
10891 	snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x",
10892 		 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
10893 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
10894 	return 0;
10895 #else /* __linux__ */
10896 	send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_get_mac_address not "
10897 		  "yet supported");
10898 	return 0;
10899 #endif /* __linux__ */
10900 }
10901 
10902 
sta_cfon_get_mac_address(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10903 int sta_cfon_get_mac_address(struct sigma_dut *dut, struct sigma_conn *conn,
10904 			     struct sigma_cmd *cmd)
10905 {
10906 	return cmd_ap_get_mac_address(dut, conn, cmd);
10907 }
10908 
10909 
cmd_ap_set_pmf(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10910 static enum sigma_cmd_result cmd_ap_set_pmf(struct sigma_dut *dut,
10911 					    struct sigma_conn *conn,
10912 					    struct sigma_cmd *cmd)
10913 {
10914 	/*
10915 	 * Ignore the command since the parameters are already handled through
10916 	 * ap_set_security.
10917 	 */
10918 
10919 	return 1;
10920 }
10921 
10922 
cmd_ap_set_hs2(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10923 static enum sigma_cmd_result cmd_ap_set_hs2(struct sigma_dut *dut,
10924 					    struct sigma_conn *conn,
10925 					    struct sigma_cmd *cmd)
10926 {
10927 	/* const char *name = get_param(cmd, "NAME"); */
10928 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
10929 	const char *val, *dest;
10930 	char *pos, buf[100];
10931 	int i, wlan_tag = 1, res;
10932 
10933 	sigma_dut_print(dut, DUT_MSG_INFO, "ap_set_hs2: Processing the "
10934 			"following parameters");
10935 	for (i = 0; i < cmd->count; i++) {
10936 		sigma_dut_print(dut, DUT_MSG_INFO, "%s %s", cmd->params[i],
10937 				(cmd->values[i] ? cmd->values[i] : "NULL"));
10938 	}
10939 
10940 	val = get_param(cmd, "ICMPv4_ECHO");
10941 	if (val && atoi(val)) {
10942 		snprintf(buf, sizeof(buf), "ebtables -F");
10943 		if (system(buf) != 0) {
10944 			sigma_dut_print(dut, DUT_MSG_ERROR,
10945 					"Failed to set ebtables rules, RULE-12");
10946 		}
10947 		return 1;
10948 	}
10949 
10950 	val = get_param(cmd, "WLAN_TAG");
10951 	if (val) {
10952 		wlan_tag = atoi(val);
10953 		if (wlan_tag != 1 && wlan_tag != 2) {
10954 			send_resp(dut, conn, SIGMA_INVALID,
10955 				  "errorCode,Invalid WLAN_TAG");
10956 			return 0;
10957 		}
10958 	}
10959 
10960 	if (wlan_tag == 2) {
10961 		val = get_param(cmd, "PROXY_ARP");
10962 		if (val)
10963 			dut->ap2_proxy_arp = atoi(val);
10964 
10965 		val = get_param(cmd, "OSU");
10966 		if (val)
10967 			dut->ap2_osu = atoi(val);
10968 		return 1;
10969 	}
10970 
10971 	dest = get_param(cmd, "STA_MAC");
10972 	if (dest) {
10973 		/* This is a special/ugly way of using this command.
10974 		 * If "Dest" MAC is included, assume that this command
10975 		 * is being issued after ap_config_commit for dynamically
10976 		 * setting the QoS Map Set.
10977 		 */
10978 		val = get_param(cmd, "QoS_MAP_SET");
10979 		if (val) {
10980 			dut->ap_qos_map_set = atoi(val);
10981 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
10982 					dut->ap_qos_map_set);
10983 		}
10984 
10985 		if (dut->ap_qos_map_set == 1)
10986 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1);
10987 		else if (dut->ap_qos_map_set == 2)
10988 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2);
10989 
10990 		snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest);
10991 		if (run_hostapd_cli(dut, buf) != 0)
10992 			return -1;
10993 	}
10994 
10995 	val = get_param(cmd, "DGAF_DISABLE");
10996 	if (val)
10997 		dut->ap_dgaf_disable = atoi(val);
10998 
10999 	dut->ap_interworking = 1;
11000 
11001 	val = get_param(cmd, "INTERWORKING");
11002 	if (val == NULL)
11003 		val = get_param(cmd, "INTERNETWORKING");
11004 	if (val != NULL && atoi(val) == 0) {
11005 		dut->ap_interworking = 0;
11006 		dut->ap_hs2 = 0;
11007 		return 1;
11008 	}
11009 
11010 	val = get_param(cmd, "ACCS_NET_TYPE");
11011 	if (val) {
11012 		if (strcasecmp(val, "Chargeable_Public_Network") == 0 ||
11013 		    strcasecmp(val, "Chargable_Public_Network") == 0 ||
11014 		    strcasecmp(val, "Chargable Public Network") == 0)
11015 			dut->ap_access_net_type = 2;
11016 		else
11017 			dut->ap_access_net_type = atoi(val);
11018 	}
11019 
11020 	val = get_param(cmd, "INTERNET");
11021 	if (val)
11022 		dut->ap_internet = atoi(val);
11023 
11024 	val = get_param(cmd, "VENUE_GRP");
11025 	if (val) {
11026 		if (strcasecmp(val, "Business") == 0)
11027 			dut->ap_venue_group = 2;
11028 		else
11029 			dut->ap_venue_group = atoi(val);
11030 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d",
11031 				dut->ap_venue_name);
11032 	}
11033 
11034 	val = get_param(cmd, "VENUE_TYPE");
11035 	if (val) {
11036 		if (strcasecmp(val, "R&D") == 0)
11037 			dut->ap_venue_type = 8;
11038 		else
11039 			dut->ap_venue_type = atoi(val);
11040 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_type %d",
11041 				dut->ap_venue_type);
11042 	}
11043 
11044 	val = get_param(cmd, "HESSID");
11045 	if (val) {
11046 		if (strlen(val) >= sizeof(dut->ap_hessid)) {
11047 			send_resp(dut, conn, SIGMA_ERROR,
11048 				  "errorCode,Invalid HESSID");
11049 			return 0;
11050 		}
11051 		snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), "%s", val);
11052 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_hessid %s",
11053 				dut->ap_hessid);
11054 	}
11055 
11056 	val = get_param(cmd, "ROAMING_CONS");
11057 	if (val) {
11058 		if (strlen(val) >= sizeof(dut->ap_roaming_cons)) {
11059 			send_resp(dut, conn, SIGMA_ERROR,
11060 				  "errorCode,Invalid ROAMING_CONS");
11061 			return 0;
11062 		}
11063 		if (strcasecmp(val, "Disabled") == 0) {
11064 			dut->ap_roaming_cons[0] = '\0';
11065 		} else {
11066 			snprintf(dut->ap_roaming_cons,
11067 				 sizeof(dut->ap_roaming_cons), "%s", val);
11068 		}
11069 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_roaming_cons %s",
11070 				dut->ap_roaming_cons);
11071 	}
11072 
11073 	val = get_param(cmd, "ANQP");
11074 	if (val)
11075 		dut->ap_anqpserver_on = atoi(val);
11076 
11077 	val = get_param(cmd, "NAI_REALM_LIST");
11078 	if (val) {
11079 		dut->ap_nai_realm_list = atoi(val);
11080 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_nai_realm_list %d",
11081 				dut->ap_nai_realm_list);
11082 	}
11083 
11084 	val = get_param(cmd, "3GPP_INFO");
11085 	if (val) {
11086 		/* What kind of encoding format is used?! */
11087 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,3GPP_INFO "
11088 			  "not yet supported (contents not fully defined)");
11089 		return 0;
11090 	}
11091 
11092 	val = get_param(cmd, "DOMAIN_LIST");
11093 	if (val) {
11094 		if (strlen(val) >= sizeof(dut->ap_domain_name_list)) {
11095 			send_resp(dut, conn, SIGMA_ERROR, "errorCode,Too long "
11096 				  "DOMAIN_LIST");
11097 			return 0;
11098 		}
11099 		snprintf(dut->ap_domain_name_list,
11100 			 sizeof(dut->ap_domain_name_list), "%s", val);
11101 		pos = dut->ap_domain_name_list;
11102 		while (*pos) {
11103 			if (*pos == ';')
11104 				*pos = ',';
11105 			pos++;
11106 		}
11107 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_domain_name_list %s",
11108 				dut->ap_domain_name_list);
11109 	}
11110 
11111 	val = get_param(cmd, "OPER_NAME");
11112 	if (val) {
11113 		dut->ap_oper_name = atoi(val);
11114 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_name %d",
11115 				dut->ap_oper_name);
11116 	}
11117 
11118 	val = get_param(cmd, "VENUE_NAME");
11119 	if (val) {
11120 		dut->ap_venue_name = atoi(val);
11121 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d",
11122 				dut->ap_venue_name);
11123 	}
11124 
11125 	val = get_param(cmd, "GAS_CB_DELAY");
11126 	if (val) {
11127 		dut->ap_gas_cb_delay = atoi(val);
11128 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_gas_cb_delay %d",
11129 				dut->ap_gas_cb_delay);
11130 	}
11131 
11132 	val = get_param(cmd, "MIH");
11133 	if (val && atoi(val) > 0) {
11134 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,MIH not "
11135 			  "supported");
11136 		return 0;
11137 	}
11138 
11139 	val = get_param(cmd, "L2_TRAFFIC_INSPECT");
11140 	if (val) {
11141 		dut->ap_l2tif = atoi(val);
11142 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_l2tif %d",
11143 				dut->ap_l2tif);
11144 	}
11145 
11146 	val = get_param(cmd, "BCST_UNCST");
11147 	if (val) {
11148 		send_resp(dut, conn, SIGMA_ERROR,
11149 			  "errorCode,BCST_UNCST not yet supported");
11150 		return 0;
11151 	}
11152 
11153 	val = get_param(cmd, "PLMN_MCC");
11154 	if (val) {
11155 		char mcc[100], *start, *end;
11156 		int i = 0;
11157 		if (strlen(val) >= sizeof(mcc)) {
11158 			send_resp(dut, conn, SIGMA_ERROR,
11159 				  "errorCode,PLMN_MCC too long");
11160 			return 0;
11161 		}
11162 		strlcpy(mcc, val, sizeof(mcc));
11163 		start = mcc;
11164 		while ((end = strchr(start, ';'))) {
11165 			/* process all except the last */
11166 			*end = '\0';
11167 			if (strlen(start) != 3) {
11168 				send_resp(dut, conn, SIGMA_ERROR,
11169 					  "errorCode,Invalid PLMN_MCC");
11170 				return 0;
11171 			}
11172 			res = snprintf(dut->ap_plmn_mcc[i],
11173 				       sizeof(dut->ap_plmn_mcc[i]), "%s",
11174 				       start);
11175 			if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i]))
11176 				return ERROR_SEND_STATUS;
11177 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s",
11178 					dut->ap_plmn_mcc[i]);
11179 			i++;
11180 			start = end + 1;
11181 			*end = ';';
11182 		}
11183 		if (strlen(start) != 3) {
11184 			send_resp(dut, conn, SIGMA_ERROR,
11185 				  "errorCode,Invalid PLMN_MCC");
11186 			return 0;
11187 		}
11188 		/* process last or only one */
11189 		res = snprintf(dut->ap_plmn_mcc[i],
11190 			       sizeof(dut->ap_plmn_mcc[i]), "%s", start);
11191 		if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i]))
11192 			return ERROR_SEND_STATUS;
11193 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s",
11194 			dut->ap_plmn_mcc[i]);
11195 	}
11196 
11197 	val = get_param(cmd, "PLMN_MNC");
11198 	if (val) {
11199 		char mnc[100], *start, *end;
11200 		int i = 0;
11201 		if (strlen(val) >= sizeof(mnc)) {
11202 			send_resp(dut, conn, SIGMA_ERROR,
11203 				  "errorCode,PLMN_MNC too long");
11204 			return 0;
11205 		}
11206 		strlcpy(mnc, val, sizeof(mnc));
11207 		start = mnc;
11208 		while ((end = strchr(start, ';'))) {
11209 			*end = '\0';
11210 			if (strlen(start) != 2 && strlen(start) != 3) {
11211 				send_resp(dut, conn, SIGMA_ERROR,
11212 					"errorCode,Invalid PLMN_MNC");
11213 				return 0;
11214 			}
11215 			res = snprintf(dut->ap_plmn_mnc[i],
11216 				       sizeof(dut->ap_plmn_mnc[i]), "%s",
11217 				       start);
11218 			if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i]))
11219 				return ERROR_SEND_STATUS;
11220 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s",
11221 				dut->ap_plmn_mnc[i]);
11222 			i++;
11223 			start = end + 1;
11224 			*end = ';';
11225 		}
11226 		if (strlen(start) != 2 && strlen(start) != 3) {
11227 			send_resp(dut, conn, SIGMA_ERROR,
11228 				  "errorCode,Invalid PLMN_MNC");
11229 			return 0;
11230 		}
11231 		res = snprintf(dut->ap_plmn_mnc[i],
11232 			       sizeof(dut->ap_plmn_mnc[i]), "%s", start);
11233 		if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i]))
11234 			return ERROR_SEND_STATUS;
11235 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s",
11236 			dut->ap_plmn_mnc[i]);
11237 	}
11238 
11239 	val = get_param(cmd, "PROXY_ARP");
11240 	if (val) {
11241 		dut->ap_proxy_arp = atoi(val);
11242 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_proxy_arp %d",
11243 				dut->ap_proxy_arp);
11244 	}
11245 
11246 	val = get_param(cmd, "WAN_METRICS");
11247 	if (val) {
11248 		dut->ap_wan_metrics = atoi(val);
11249 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_wan_metrics %d",
11250 				dut->ap_wan_metrics);
11251 	}
11252 
11253 	val = get_param(cmd, "CONN_CAP");
11254 	if (val) {
11255 		dut->ap_conn_capab = atoi(val);
11256 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_conn_capab %d",
11257 				dut->ap_conn_capab);
11258 	}
11259 
11260 	val = get_param(cmd, "IP_ADD_TYPE_AVAIL");
11261 	if (val) {
11262 		dut->ap_ip_addr_type_avail = atoi(val);
11263 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_ip_addr_type_avail %d",
11264 				dut->ap_ip_addr_type_avail);
11265 	}
11266 
11267 	val = get_param(cmd, "NET_AUTH_TYPE");
11268 	if (val) {
11269 		dut->ap_net_auth_type = atoi(val);
11270 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_net_auth_type %d",
11271 				dut->ap_net_auth_type);
11272 	}
11273 
11274 	val = get_param(cmd, "OP_CLASS");
11275 	if (val == NULL)
11276 		val = get_param(cmd, "OPER_CLASS");
11277 	if (val) {
11278 		dut->ap_oper_class = atoi(val);
11279 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_class %d",
11280 				dut->ap_oper_class);
11281 	}
11282 
11283 	val = get_param(cmd, "OSU_PROVIDER_LIST");
11284 	if (val) {
11285 		dut->ap_osu_provider_list = atoi(val);
11286 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_osu_provider_list %d",
11287 				dut->ap_osu_provider_list);
11288 	}
11289 
11290 	val = get_param(cmd, "OSU_PROVIDER_NAI_LIST");
11291 	if (val) {
11292 		dut->ap_osu_provider_nai_list = atoi(val);
11293 		sigma_dut_print(dut, DUT_MSG_INFO,
11294 				"ap_osu_provider_nai_list %d",
11295 				dut->ap_osu_provider_nai_list);
11296 	}
11297 
11298 	val = get_param(cmd, "OSU_SERVER_URI");
11299 	if (val) {
11300 		i = 0;
11301 		do {
11302 			int len;
11303 			const char *uri = val;
11304 			val = strchr(val, ' ');
11305 			len = val ? (val++ - uri) : (int) strlen(uri);
11306 			if (len > 0 && len < 256) {
11307 				memcpy(dut->ap_osu_server_uri[i], uri, len);
11308 				dut->ap_osu_server_uri[i][len] = '\0';
11309 				sigma_dut_print(dut, DUT_MSG_INFO,
11310 						"ap_osu_server_uri[%d] %s", i,
11311 						dut->ap_osu_server_uri[i]);
11312 			}
11313 		} while (val && ++i < 10);
11314 	}
11315 
11316 	val = get_param(cmd, "OSU_METHOD");
11317 	if (val) {
11318 		i = 0;
11319 		do {
11320 			int len;
11321 			const char *method = val;
11322 			val = strchr(val, ' ');
11323 			len = val ? (val++ - method) : (int) strlen(method);
11324 			if (len > 0) {
11325 				if (strncasecmp(method, "SOAP", len) == 0)
11326 					dut->ap_osu_method[i] = 1;
11327 				else if (strncasecmp(method, "OMADM", len) == 0)
11328 					dut->ap_osu_method[i] = 0;
11329 				else
11330 					return -2;
11331 			}
11332 		} while (val && ++i < 10);
11333 	}
11334 
11335 	val = get_param(cmd, "OSU_SSID");
11336 	if (val) {
11337 		if (strlen(val) > 0 && strlen(val) <= 32) {
11338 			strlcpy(dut->ap_osu_ssid, val,
11339 				sizeof(dut->ap_osu_ssid));
11340 			sigma_dut_print(dut, DUT_MSG_INFO,
11341 					"ap_osu_ssid %s",
11342 					dut->ap_osu_ssid);
11343 		}
11344 	}
11345 
11346 	val = get_param(cmd, "OSU_ICON_TAG");
11347 	if (val)
11348 		dut->ap_osu_icon_tag = atoi(val);
11349 
11350 	val = get_param(cmd, "QoS_MAP_SET");
11351 	if (val) {
11352 		dut->ap_qos_map_set = atoi(val);
11353 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
11354 				dut->ap_qos_map_set);
11355 	}
11356 
11357 	val = get_param(cmd, "BSS_LOAD");
11358 	if (val) {
11359 		dut->ap_bss_load = atoi(val);
11360 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_bss_load %d",
11361 				dut->ap_bss_load);
11362 	}
11363 
11364 	val = get_param(cmd, "Venue_URL");
11365 	if (val)
11366 		dut->ap_venue_url = atoi(val);
11367 
11368 	val = get_param(cmd, "Advice_of_Charge");
11369 	if (val)
11370 		dut->ap_advice_of_charge = atoi(val);
11371 
11372 	val = get_param(cmd, "Operator_Icon_Metadata");
11373 	if (val)
11374 		dut->ap_oper_icon_metadata = atoi(val);
11375 
11376 	val = get_param(cmd, "TnC_File_Name");
11377 	if (val)
11378 		dut->ap_tnc_file_name = atoi(val);
11379 
11380 	val = get_param(cmd, "TnC_File_Time_Stamp");
11381 	if (val)
11382 		dut->ap_tnc_time_stamp = strtol(val, NULL, 10);
11383 
11384 	return 1;
11385 }
11386 
11387 
nfc_status(struct sigma_dut * dut,const char * state,const char * oper)11388 void nfc_status(struct sigma_dut *dut, const char *state, const char *oper)
11389 {
11390 	char buf[100];
11391 
11392 	if (!file_exists("nfc-status"))
11393 		return;
11394 
11395 	snprintf(buf, sizeof(buf), "./nfc-status %s %s", state, oper);
11396 	run_system(dut, buf);
11397 }
11398 
11399 
run_nfc_command(struct sigma_dut * dut,const char * cmd,const char * info)11400 static int run_nfc_command(struct sigma_dut *dut, const char *cmd,
11401 			   const char *info)
11402 {
11403 	int res;
11404 
11405 	printf("\n\n\n=====[ NFC operation ]=========================\n\n");
11406 	printf("%s\n\n", info);
11407 
11408 	nfc_status(dut, "START", info);
11409 	res = run_system(dut, cmd);
11410 	nfc_status(dut, res ? "FAIL" : "SUCCESS", info);
11411 	if (res) {
11412 		sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s': %d",
11413 				cmd, res);
11414 		return res;
11415 	}
11416 
11417 	return 0;
11418 }
11419 
11420 
ap_nfc_write_config_token(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11421 static int ap_nfc_write_config_token(struct sigma_dut *dut,
11422 				     struct sigma_conn *conn,
11423 				     struct sigma_cmd *cmd)
11424 {
11425 	int res;
11426 	char buf[300];
11427 
11428 	run_system(dut, "killall wps-ap-nfc.py");
11429 	unlink("nfc-success");
11430 	snprintf(buf, sizeof(buf),
11431 		 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-config",
11432 		 dut->summary_log ? "--summary " : "",
11433 		 dut->summary_log ? dut->summary_log : "");
11434 	res = run_nfc_command(dut, buf,
11435 			      "Touch NFC Tag to write WPS configuration token");
11436 	if (res || !file_exists("nfc-success")) {
11437 		send_resp(dut, conn, SIGMA_ERROR,
11438 			  "ErrorCode,Failed to write tag");
11439 		return 0;
11440 	}
11441 
11442 	return 1;
11443 }
11444 
11445 
ap_nfc_wps_read_passwd(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11446 static int ap_nfc_wps_read_passwd(struct sigma_dut *dut,
11447 				  struct sigma_conn *conn,
11448 				  struct sigma_cmd *cmd)
11449 {
11450 	int res;
11451 	char buf[300];
11452 
11453 	run_system(dut, "killall wps-ap-nfc.py");
11454 
11455 	unlink("nfc-success");
11456 	snprintf(buf, sizeof(buf),
11457 		 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success",
11458 		 dut->summary_log ? "--summary " : "",
11459 		 dut->summary_log ? dut->summary_log : "");
11460 	res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
11461 	if (res || !file_exists("nfc-success")) {
11462 		send_resp(dut, conn, SIGMA_ERROR,
11463 			  "ErrorCode,Failed to read tag");
11464 		return 0;
11465 	}
11466 
11467 	return 1;
11468 }
11469 
11470 
ap_nfc_write_password_token(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11471 static int ap_nfc_write_password_token(struct sigma_dut *dut,
11472 				       struct sigma_conn *conn,
11473 				       struct sigma_cmd *cmd)
11474 {
11475 	int res;
11476 	char buf[300];
11477 
11478 	run_system(dut, "killall wps-ap-nfc.py");
11479 	unlink("nfc-success");
11480 	snprintf(buf, sizeof(buf),
11481 		 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-password",
11482 		 dut->summary_log ? "--summary " : "",
11483 		 dut->summary_log ? dut->summary_log : "");
11484 	res = run_nfc_command(dut, buf,
11485 			      "Touch NFC Tag to write WPS password token");
11486 	if (res || !file_exists("nfc-success")) {
11487 		send_resp(dut, conn, SIGMA_ERROR,
11488 			  "ErrorCode,Failed to write tag");
11489 		return 0;
11490 	}
11491 
11492 	if (run_hostapd_cli(dut, "wps_nfc_token enable") != 0) {
11493 		send_resp(dut, conn, SIGMA_ERROR,
11494 			  "ErrorCode,Failed to enable NFC password token");
11495 		return 0;
11496 	}
11497 
11498 	return 1;
11499 }
11500 
11501 
ap_nfc_wps_connection_handover(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11502 static int ap_nfc_wps_connection_handover(struct sigma_dut *dut,
11503 					  struct sigma_conn *conn,
11504 					  struct sigma_cmd *cmd)
11505 {
11506 	int res;
11507 	char buf[300];
11508 
11509 	run_system(dut, "killall wps-ap-nfc.py");
11510 	unlink("nfc-success");
11511 	snprintf(buf, sizeof(buf),
11512 		 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success",
11513 		 dut->summary_log ? "--summary " : "",
11514 		 dut->summary_log ? dut->summary_log : "");
11515 	res = run_nfc_command(dut, buf,
11516 			      "Touch NFC Device to respond to WPS connection handover");
11517 	if (res) {
11518 		send_resp(dut, conn, SIGMA_ERROR,
11519 			  "ErrorCode,Failed to enable NFC for connection "
11520 			  "handover");
11521 		return 0;
11522 	}
11523 	if (!file_exists("nfc-success")) {
11524 		send_resp(dut, conn, SIGMA_ERROR,
11525 			  "ErrorCode,Failed to complete NFC connection handover");
11526 		return 0;
11527 	}
11528 
11529 	return 1;
11530 }
11531 
11532 
cmd_ap_nfc_action(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11533 static enum sigma_cmd_result cmd_ap_nfc_action(struct sigma_dut *dut,
11534 					       struct sigma_conn *conn,
11535 					       struct sigma_cmd *cmd)
11536 {
11537 	/* const char *name = get_param(cmd, "Name"); */
11538 	/* const char *intf = get_param(cmd, "Interface"); */
11539 	const char *oper = get_param(cmd, "Operation");
11540 
11541 	if (oper == NULL)
11542 		return -1;
11543 
11544 	if (strcasecmp(oper, "WRITE_CONFIG") == 0)
11545 		return ap_nfc_write_config_token(dut, conn, cmd);
11546 	if (strcasecmp(oper, "WRITE_PASSWD") == 0)
11547 		return ap_nfc_write_password_token(dut, conn, cmd);
11548 	if (strcasecmp(oper, "WPS_READ_PASSWD") == 0)
11549 		return ap_nfc_wps_read_passwd(dut, conn, cmd);
11550 	if (strcasecmp(oper, "WPS_CONN_HNDOVR") == 0)
11551 		return ap_nfc_wps_connection_handover(dut, conn, cmd);
11552 
11553 	send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported operation");
11554 	return 0;
11555 }
11556 
11557 
cmd_ap_wps_read_pin(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11558 static enum sigma_cmd_result cmd_ap_wps_read_pin(struct sigma_dut *dut,
11559 						 struct sigma_conn *conn,
11560 						 struct sigma_cmd *cmd)
11561 {
11562 	char *pin = "12345670"; /* TODO: use random PIN */
11563 	char resp[100];
11564 
11565 	snprintf(resp, sizeof(resp), "PIN,%s", pin);
11566 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
11567 
11568 	return 0;
11569 }
11570 
11571 
cmd_ap_wps_enter_pin(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11572 static enum sigma_cmd_result cmd_ap_wps_enter_pin(struct sigma_dut *dut,
11573 						  struct sigma_conn *conn,
11574 						  struct sigma_cmd *cmd)
11575 {
11576 	const char *pin = get_param(cmd, "PIN");
11577 	char wps_pin[11];
11578 
11579 	if (!pin)
11580 		return -1;
11581 
11582 	sigma_dut_print(dut, DUT_MSG_DEBUG,
11583 			"Authorize a client to join with WPS PIN %s", pin);
11584 
11585 	strlcpy(wps_pin, pin, sizeof(wps_pin));
11586 	/* we need to tolerate extra '-' characters entered */
11587 	str_remove_chars(wps_pin, '-');
11588 	strlcpy(dut->wps_pin, wps_pin, sizeof(dut->wps_pin));
11589 	dut->wps_method = WFA_CS_WPS_PIN_KEYPAD;
11590 
11591 	return 1;
11592 }
11593 
11594 
cmd_ap_wps_set_pbc(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11595 static enum sigma_cmd_result cmd_ap_wps_set_pbc(struct sigma_dut *dut,
11596 						struct sigma_conn *conn,
11597 						struct sigma_cmd *cmd)
11598 {
11599 	sigma_dut_print(dut, DUT_MSG_DEBUG,
11600 			"Selecting the push button configuration method");
11601 
11602 	dut->wps_method = WFA_CS_WPS_PBC;
11603 
11604 	return 1;
11605 }
11606 
11607 
ap_wps_registration(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11608 int ap_wps_registration(struct sigma_dut *dut, struct sigma_conn *conn,
11609 			struct sigma_cmd *cmd)
11610 {
11611 	char buf[100], resp[256];
11612 	const char *intf = get_param(cmd, "interface");
11613 	const char *config_method = get_param(cmd, "WPSConfigMethod");
11614 
11615 	if (config_method && strcasecmp(config_method, "PBC") == 0)
11616 		dut->wps_method = WFA_CS_WPS_PBC;
11617 
11618 	if (!intf)
11619 		intf = get_main_ifname(dut);
11620 
11621 	if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
11622 		send_resp(dut, conn, SIGMA_ERROR,
11623 			  "ErrorCode,WPS parameters not yet set");
11624 		return STATUS_SENT;
11625 	}
11626 
11627 	if (dut->wps_method == WFA_CS_WPS_PBC)
11628 		snprintf(buf, sizeof(buf), "WPS_PBC");
11629 	else /* WFA_CS_WPS_PIN_KEYPAD */
11630 		snprintf(buf, sizeof(buf), "WPS_PIN any %s", dut->wps_pin);
11631 
11632 	/* Run WPS command */
11633 	if (hapd_command(intf, buf) < 0) {
11634 		/* command fails immediately if overlapped session detected */
11635 		snprintf(resp, sizeof(resp), "WpsState,OverlapSession");
11636 		send_resp(dut, conn, SIGMA_COMPLETE, resp);
11637 		return STATUS_SENT;
11638 	}
11639 
11640 	/* In AP mode return immediately and do not wait for WPS registration */
11641 	return SUCCESS_SEND_STATUS;
11642 }
11643 
11644 
cmd_ap_get_parameter(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11645 static enum sigma_cmd_result cmd_ap_get_parameter(struct sigma_dut *dut,
11646 						  struct sigma_conn *conn,
11647 						  struct sigma_cmd *cmd)
11648 {
11649 	char value[256], resp[512];
11650 	const char *param = get_param(cmd, "parameter");
11651 	const char *ifname = get_param(cmd, "Interface");
11652 	const char *var;
11653 
11654 	if (!ifname)
11655 		ifname = get_main_ifname(dut);
11656 
11657 	if (!param) {
11658 		send_resp(dut, conn, SIGMA_ERROR,
11659 			  "ErrorCode,Parameter not specified");
11660 		return 0;
11661 	}
11662 
11663 	if (strcasecmp(param, "SSID") == 0) {
11664 		if (get_hapd_config(ifname, "ssid", value, sizeof(value))) {
11665 			sigma_dut_print(dut, DUT_MSG_ERROR,
11666 					"Failed to get SSID");
11667 			return -2;
11668 		}
11669 		snprintf(resp, sizeof(resp), "SSID,%s", value);
11670 	} else if (strcasecmp(param, "PSK") == 0) {
11671 		if (get_hapd_config(ifname, "passphrase", value,
11672 				    sizeof(value))) {
11673 			sigma_dut_print(dut, DUT_MSG_ERROR,
11674 					"Failed to get PSK");
11675 			return -2;
11676 		}
11677 		snprintf(resp, sizeof(resp), "PSK,%s", value);
11678 	} else if (strcasecmp(param, "PMK") == 0) {
11679 		var = get_param(cmd, "STA_MAC_Address");
11680 		if (!var)
11681 			return INVALID_SEND_STATUS;
11682 		snprintf(resp, sizeof(resp), "GET_PMK %s", var);
11683 		if (hapd_command_resp(ifname, resp, &resp[4],
11684 				      sizeof(resp) - 4) < 0) {
11685 			send_resp(dut, conn, SIGMA_ERROR,
11686 				  "ErrorCode,GET_PMK failed");
11687 			return STATUS_SENT_ERROR;
11688 		}
11689 		memcpy(resp, "PMK,", 4);
11690 	} else {
11691 		send_resp(dut, conn, SIGMA_ERROR,
11692 			  "ErrorCode,Unsupported parameter");
11693 		return 0;
11694 	}
11695 
11696 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
11697 	return 0;
11698 }
11699 
11700 
ath_vht_op_mode_notif(struct sigma_dut * dut,const char * ifname,const char * val)11701 static int ath_vht_op_mode_notif(struct sigma_dut *dut, const char *ifname,
11702 				 const char *val)
11703 {
11704 	char *token, *result;
11705 	int nss = 0, chwidth = 0;
11706 	char *saveptr;
11707 
11708 	/*
11709 	 * The following commands should be invoked to generate
11710 	 * VHT op mode notification
11711 	 */
11712 
11713 	/* Extract the NSS info */
11714 	token = strdup(val);
11715 	if (!token)
11716 		return -1;
11717 	result = strtok_r(token, ";", &saveptr);
11718 	if (result) {
11719 		int count = atoi(result);
11720 
11721 		/* We do not support NSS > 3 */
11722 		if (count < 0 || count > 3) {
11723 			free(token);
11724 			return -1;
11725 		}
11726 
11727 		/* Convert nss to chainmask */
11728 		while (count--)
11729 			nss = (nss << 1) | 1;
11730 
11731 		run_iwpriv(dut, ifname, "rxchainmask %d", nss);
11732 	}
11733 
11734 	/* Extract the Channel width info */
11735 	result = strtok_r(NULL, ";", &saveptr);
11736 	if (result) {
11737 		switch (atoi(result)) {
11738 		case 20:
11739 			chwidth = 0;
11740 			break;
11741 		case 40:
11742 			chwidth = 1;
11743 			break;
11744 		case 80:
11745 			chwidth = 2;
11746 			break;
11747 		case 160:
11748 			chwidth = 3;
11749 			break;
11750 		default:
11751 			chwidth = 2;
11752 			break;
11753 		}
11754 		run_iwpriv(dut, ifname, "chwidth %d", chwidth);
11755 	}
11756 
11757 	/* Send the opmode notification */
11758 	run_iwpriv(dut, ifname, "opmode_notify 1");
11759 	free(token);
11760 
11761 	return 0;
11762 }
11763 
11764 
ath_vht_nss_mcs(struct sigma_dut * dut,const char * ifname,const char * val)11765 static int ath_vht_nss_mcs(struct sigma_dut *dut, const char *ifname,
11766 			   const char *val)
11767 {
11768 	/* String (nss_operating_mode; mcs_operating_mode) */
11769 	int nss, mcs;
11770 	char *token, *result;
11771 	char *saveptr;
11772 
11773 	token = strdup(val);
11774 	if (!token)
11775 		return -1;
11776 	result = strtok_r(token, ";", &saveptr);
11777 	if (!result) {
11778 		sigma_dut_print(dut, DUT_MSG_ERROR,
11779 				"VHT NSS not specified");
11780 		goto end;
11781 	}
11782 	if (strcasecmp(result, "def") != 0) {
11783 		nss = atoi(result);
11784 
11785 		if (nss == 4)
11786 			ath_disable_txbf(dut, ifname);
11787 
11788 		run_iwpriv(dut, ifname, "nss %d", nss);
11789 	} else {
11790 		if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1)
11791 			run_iwpriv(dut, ifname, "nss 1");
11792 		if (dut->device_type == AP_testbed &&
11793 		    dut->program == PROGRAM_HE) {
11794 			nss = dut->ap_tx_streams;
11795 			run_iwpriv(dut, ifname, "nss %d", nss);
11796 		}
11797 	}
11798 
11799 	result = strtok_r(NULL, ";", &saveptr);
11800 	if (!result) {
11801 		sigma_dut_print(dut, DUT_MSG_ERROR,
11802 				"VHT MCS not specified");
11803 		goto end;
11804 	}
11805 	if (strcasecmp(result, "def") == 0) {
11806 		if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1)
11807 			run_iwpriv(dut, ifname, "vhtmcs 7");
11808 		else
11809 			run_iwpriv(dut, ifname, "set11NRates 0");
11810 		if (dut->device_type == AP_testbed &&
11811 		    dut->program == PROGRAM_HE)
11812 			run_iwpriv(dut, ifname, "he_mcs 7");
11813 	} else {
11814 		mcs = atoi(result);
11815 		if (dut->program == PROGRAM_HE)
11816 			run_iwpriv(dut, ifname, "he_mcs %d", mcs);
11817 		else
11818 			run_iwpriv(dut, ifname, "vhtmcs %d", mcs);
11819 	}
11820 
11821 end:
11822 	free(token);
11823 	return 0;
11824 }
11825 
11826 
ath_vht_chnum_band(struct sigma_dut * dut,const char * ifname,const char * val)11827 static int ath_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
11828 			      const char *val)
11829 {
11830 	char *token, *result;
11831 	int channel = 36;
11832 	int chwidth = 80;
11833 	char *saveptr;
11834 
11835 	/* Extract the channel info */
11836 	token = strdup(val);
11837 	if (!token)
11838 		return -1;
11839 	result = strtok_r(token, ";", &saveptr);
11840 	if (result)
11841 		channel = atoi(result);
11842 
11843 	/* Extract the channel width info */
11844 	result = strtok_r(NULL, ";", &saveptr);
11845 	if (result)
11846 		chwidth = atoi(result);
11847 
11848 	/* Issue the channel switch command */
11849 	run_iwpriv(dut, ifname, "doth_ch_chwidth %d 10 %d", channel, chwidth);
11850 
11851 	free(token);
11852 	return 0;
11853 }
11854 
11855 
ath_ndpa_stainfo_mac(struct sigma_dut * dut,const char * ifname,const char * val)11856 static int ath_ndpa_stainfo_mac(struct sigma_dut *dut, const char *ifname,
11857 				const char *val)
11858 {
11859 	char buf[80];
11860 	unsigned char mac_addr[6];
11861 
11862 	if (parse_mac_address(dut, val, mac_addr) < 0)
11863 		return -1;
11864 
11865 	snprintf(buf, sizeof(buf),
11866 		 "wifitool %s beeliner_fw_test 92 0x%02x%02x%02x%02x",
11867 		 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3]);
11868 	run_system(dut, buf);
11869 
11870 	snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 93 0x%02x%02x",
11871 		 ifname, mac_addr[4], mac_addr[5]);
11872 	run_system(dut, buf);
11873 
11874 	snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 94 1", ifname);
11875 	run_system(dut, buf);
11876 
11877 	return 0;
11878 }
11879 
11880 
novap_reset(struct sigma_dut * dut,const char * ifname,int reset)11881 void novap_reset(struct sigma_dut *dut, const char *ifname, int reset)
11882 {
11883 	run_iwpriv(dut, ifname, "novap_reset %d", reset);
11884 }
11885 
11886 
mbo_find_nebor_ap_entry(struct sigma_dut * dut,const uint8_t * mac_addr)11887 static struct mbo_pref_ap * mbo_find_nebor_ap_entry(struct sigma_dut *dut,
11888 						    const uint8_t *mac_addr)
11889 {
11890 	int i;
11891 
11892 	for (i = 0; i < dut->mbo_pref_ap_cnt; i++) {
11893 		if (memcmp(mac_addr, dut->mbo_pref_aps[i].mac_addr,
11894 			   ETH_ALEN) == 0)
11895 			return &dut->mbo_pref_aps[i];
11896 	}
11897 	return NULL;
11898 }
11899 
11900 
mbo_add_nebor_entry(struct sigma_dut * dut,const uint8_t * mac_addr,int ap_ne_class,int ap_ne_op_ch,int ap_ne_pref)11901 static void mbo_add_nebor_entry(struct sigma_dut *dut, const uint8_t *mac_addr,
11902 				int ap_ne_class, int ap_ne_op_ch,
11903 				int ap_ne_pref)
11904 {
11905 	struct mbo_pref_ap *entry;
11906 	uint8_t self_mac[ETH_ALEN];
11907 	char ifname[50];
11908 
11909 	get_if_name(dut, ifname, sizeof(ifname), 1);
11910 	get_hwaddr(ifname, self_mac);
11911 
11912 	if (memcmp(mac_addr, self_mac, ETH_ALEN) == 0)
11913 		entry = &dut->mbo_self_ap_tuple;
11914 	else
11915 		entry = mbo_find_nebor_ap_entry(dut, mac_addr);
11916 
11917 	if (!entry) {
11918 		if (dut->mbo_pref_ap_cnt >= MBO_MAX_PREF_BSSIDS) {
11919 			sigma_dut_print(dut, DUT_MSG_ERROR,
11920 					"Nebor AP List is full. Not adding");
11921 			return;
11922 		}
11923 		entry = &dut->mbo_pref_aps[dut->mbo_pref_ap_cnt];
11924 		dut->mbo_pref_ap_cnt++;
11925 		memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
11926 		entry->ap_ne_class = -1;
11927 		entry->ap_ne_op_ch = -1;
11928 		entry->ap_ne_pref = -1;
11929 	}
11930 	if (ap_ne_class != -1)
11931 		entry->ap_ne_class = ap_ne_class;
11932 	if (ap_ne_op_ch != -1)
11933 		entry->ap_ne_op_ch = ap_ne_op_ch;
11934 	if (ap_ne_pref != -1)
11935 		entry->ap_ne_pref = ap_ne_pref;
11936 }
11937 
11938 
ath_set_nebor_bssid(struct sigma_dut * dut,const char * ifname,struct sigma_cmd * cmd)11939 static int ath_set_nebor_bssid(struct sigma_dut *dut, const char *ifname,
11940 			       struct sigma_cmd *cmd)
11941 {
11942 	unsigned char mac_addr[ETH_ALEN];
11943 	const char *val;
11944 	/*
11945 	 * -1 is invalid value for the following
11946 	 *  to differentiate between unset and set values
11947 	 *  -1 => implies not set by CAPI
11948 	 */
11949 	int ap_ne_class = -1, ap_ne_op_ch = -1, ap_ne_pref = -1;
11950 	int list_offset = dut->mbo_pref_ap_cnt;
11951 
11952 	if (list_offset >= MBO_MAX_PREF_BSSIDS) {
11953 		sigma_dut_print(dut, DUT_MSG_ERROR,
11954 				"AP Pref Entry list is full");
11955 		return -1;
11956 	}
11957 
11958 	val = get_param(cmd, "Nebor_Op_Class");
11959 	if (val)
11960 		ap_ne_class = atoi(val);
11961 
11962 	val = get_param(cmd, "Nebor_Op_Ch");
11963 	if (val)
11964 		ap_ne_op_ch = atoi(val);
11965 
11966 	val = get_param(cmd, "Nebor_Pref");
11967 	if (val)
11968 		ap_ne_pref = atoi(val);
11969 
11970 	val = get_param(cmd, "Nebor_BSSID");
11971 	if (!val || parse_mac_address(dut, val, mac_addr) < 0)
11972 		return -1;
11973 
11974 	mbo_add_nebor_entry(dut, mac_addr, ap_ne_class, ap_ne_op_ch,
11975 			    ap_ne_pref);
11976 	apply_mbo_pref_ap_list(dut);
11977 	return 0;
11978 }
11979 
11980 
he_ltf(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val)11981 static enum sigma_cmd_result he_ltf(struct sigma_dut *dut,
11982 				    struct sigma_conn *conn,
11983 				    const char *ifname, const char *val)
11984 {
11985 	const char *var;
11986 
11987 	if (dut->ap_he_ulofdma == VALUE_ENABLED)
11988 		var = "he_ul_ltf";
11989 	else
11990 		var = "he_ltf";
11991 
11992 	if (strcmp(val, "6.4") == 0) {
11993 		run_iwpriv(dut, ifname, "%s 2", var);
11994 	} else if (strcmp(val, "12.8") == 0) {
11995 		run_iwpriv(dut, ifname, "%s 3", var);
11996 	} else if (strcmp(val, "3.2") == 0) {
11997 		run_iwpriv(dut, ifname, "%s 1", var);
11998 	} else {
11999 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported LTF");
12000 		return STATUS_SENT_ERROR;
12001 	}
12002 
12003 	return SUCCESS_SEND_STATUS;
12004 }
12005 
12006 
he_shortgi(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val)12007 static enum sigma_cmd_result he_shortgi(struct sigma_dut *dut,
12008 					struct sigma_conn *conn,
12009 					const char *ifname,
12010 					const char *val)
12011 {
12012 	const char *var;
12013 
12014 	if (dut->ap_he_ulofdma == VALUE_ENABLED)
12015 		var = "he_ul_shortgi";
12016 	else
12017 		var = "shortgi";
12018 
12019 	if (strcmp(val, "0.8") == 0) {
12020 		run_iwpriv(dut, ifname, "%s 0", var);
12021 	} else if (strcmp(val, "1.6") == 0) {
12022 		run_iwpriv(dut, ifname, "%s 2", var);
12023 	} else if (strcmp(val, "3.2") == 0) {
12024 		run_iwpriv(dut, ifname, "%s 3", var);
12025 	} else {
12026 		send_resp(dut, conn, SIGMA_ERROR,
12027 			  "errorCode,Unsupported shortGI");
12028 		return STATUS_SENT_ERROR;
12029 	}
12030 
12031 	return SUCCESS_SEND_STATUS;
12032 }
12033 
12034 
he_ar_gi_ltf_mask(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val)12035 static enum sigma_cmd_result he_ar_gi_ltf_mask(struct sigma_dut *dut,
12036 					       struct sigma_conn *conn,
12037 					       const char *ifname,
12038 					       const char *val)
12039 {
12040 
12041 	uint32_t he_ar_gi_ltf;
12042 	uint16_t he_ar_gi, he_ar_ltf;
12043 
12044 	if (strcmp(val, "0.4") == 0) {
12045 		he_ar_gi = 0x01;
12046 	} else if (strcmp(val, "0.8") == 0) {
12047 		he_ar_gi = 0x02;
12048 	} else if (strcmp(val, "1.6") == 0) {
12049 		he_ar_gi = 0x04;
12050 	} else if (strcmp(val, "3.2") == 0) {
12051 		he_ar_gi = 0x08;
12052 	} else {
12053 		send_resp(dut, conn, SIGMA_ERROR,
12054 			  "errorCode,Unsupported shortGI");
12055 		return STATUS_SENT_ERROR;
12056 	}
12057 
12058 	if (dut->ar_ltf && strcmp(dut->ar_ltf, "6.4") == 0) {
12059 		he_ar_ltf = 0x02;
12060 	} else if (dut->ar_ltf && strcmp(dut->ar_ltf, "12.8") == 0) {
12061 		he_ar_ltf = 0x04;
12062 	} else if (dut->ar_ltf && strcmp(dut->ar_ltf, "3.2") == 0) {
12063 		he_ar_ltf = 0x01;
12064 	} else {
12065 		send_resp(dut, conn, SIGMA_ERROR,
12066 			  "errorCode,Unsupported LTF");
12067 		return STATUS_SENT_ERROR;
12068 	}
12069 
12070 	he_ar_gi_ltf = (he_ar_gi << 8) | he_ar_ltf;
12071 	run_iwpriv(dut, ifname, "he_ar_gi_ltf %lu", he_ar_gi_ltf);
12072 
12073 	return SUCCESS_SEND_STATUS;
12074 }
12075 
12076 
he_rualloctones(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val)12077 static enum sigma_cmd_result he_rualloctones(struct sigma_dut *dut,
12078 					     struct sigma_conn *conn,
12079 					     const char *ifname,
12080 					     const char *val)
12081 {
12082 	char *token, *result;
12083 	int value;
12084 	char *saveptr;
12085 	int rualloc_type;
12086 	enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
12087 
12088 	token = strdup(val);
12089 	if (!token)
12090 		return -1;
12091 	result = strtok_r(token, ":", &saveptr);
12092 	if (!result) {
12093 		free(token);
12094 		send_resp(dut, conn, SIGMA_ERROR,
12095 			  "errorCode,RUAllocTones not specified");
12096 		return STATUS_SENT_ERROR;
12097 	}
12098 
12099 	/*
12100 	* ru_allocation_type can take the values of:
12101 	* 1 - DL OFDMA data RU allocation
12102 	* 3 - UL OFDMA data RU allocation
12103 	*/
12104 	rualloc_type = dut->ap_he_ulofdma == VALUE_ENABLED ? 3 : 1;
12105 
12106 
12107 	value = atoi(result);
12108 	if (value == 106) {
12109 		enum value_not_set_enabled_disabled ap_he_rualloc_106_80 =
12110 			VALUE_NOT_SET;
12111 
12112 		result = strtok_r(NULL, ":", &saveptr);
12113 		if (result) {
12114 			result = strtok_r(NULL, ":", &saveptr);
12115 			if (result)
12116 				ap_he_rualloc_106_80 = VALUE_ENABLED;
12117 			else
12118 				ap_he_rualloc_106_80 = VALUE_DISABLED;
12119 		}
12120 		if (ap_he_rualloc_106_80 == VALUE_ENABLED) {
12121 			run_system_wrapper(dut,
12122 					   "wifitool %s setUnitTestCmd 0x4b 9 %d 0 2 1 2 2 2 3 2",
12123 					   ifname, rualloc_type);
12124 		} else {
12125 			run_system_wrapper(dut,
12126 					   "wifitool %s setUnitTestCmd 0x4b 5 %d 0 2 1 2",
12127 					   ifname, rualloc_type);
12128 		}
12129 	} else if (value == 242) {
12130 		run_system_wrapper(
12131 			dut,
12132 			"wifitool %s setUnitTestCmd 0x4b 9 %d 0 3 1 3 2 3 3 3",
12133 			ifname, rualloc_type);
12134 	} else if (value == 26) {
12135 		run_system_wrapper(
12136 			dut,
12137 			"wifitool %s setUnitTestCmd 0x4b 9 %d 0 0 2 0 5 0 7 0",
12138 			ifname, rualloc_type);
12139 	} else if (value == 52) {
12140 		run_system_wrapper(
12141 			dut,
12142 			"wifitool %s setUnitTestCmd 0x4b 9 %d 0 1 1 1 2 1 3 1",
12143 			ifname, rualloc_type);
12144 	} else if (value == 484) {
12145 		run_system_wrapper(
12146 			dut,
12147 			"wifitool %s setUnitTestCmd 0x4b 5 %d 0 4 1 4",
12148 			ifname, rualloc_type);
12149 	} else if (value == 996) {
12150 		run_system_wrapper(dut,
12151 				   "wifitool %s setUnitTestCmd 0x4b 3 %d 0 5",
12152 				   ifname, rualloc_type);
12153 	} else {
12154 		send_resp(dut, conn, SIGMA_ERROR,
12155 			  "errorCode,Unsupported RUAllocTones");
12156 		ret = STATUS_SENT_ERROR;
12157 	}
12158 
12159 	free(token);
12160 	return ret;
12161 }
12162 
12163 
ath_set_trigger_type_0(struct sigma_dut * dut,const char * ifname)12164 static void ath_set_trigger_type_0(struct sigma_dut *dut, const char *ifname)
12165 {
12166 	/* TriggerType "0" for Basic trigger */
12167 	if (dut->ap_channel >= 36) {
12168 		/* 1 and 2 here is interpreted to 5g and 2g (bitmasks) */
12169 		run_system_wrapper(dut,
12170 				   "wifitool %s setUnitTestCmd 0x47 2 42 1",
12171 				   ifname);
12172 	} else {
12173 		run_system_wrapper(dut,
12174 				   "wifitool %s setUnitTestCmd 0x47 2 42 2",
12175 				   ifname);
12176 	}
12177 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 6",
12178 			   ifname);
12179 }
12180 
12181 
ath_set_trigger_type_1(struct sigma_dut * dut,const char * ifname)12182 static void ath_set_trigger_type_1(struct sigma_dut *dut, const char *ifname)
12183 {
12184 	/* TriggerType "1" for MU BRP */
12185 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 1",
12186 			   ifname);
12187 	mubrp_commands(dut, ifname);
12188 }
12189 
12190 
ath_set_trigger_type_2(struct sigma_dut * dut,const char * ifname)12191 static void ath_set_trigger_type_2(struct sigma_dut *dut, const char *ifname)
12192 {
12193 	/* TriggerType "2" for MU BAR */
12194 	if (dut->ap_channel >= 36) {
12195 		/* RU allocation RU 242 - DL OFDMA data */
12196 		run_system_wrapper(dut,
12197 				   "wifitool %s setUnitTestCmd 0x4b 5 9 0 3 1 3 2 3 3 3",
12198 				   ifname);
12199 		/* RU allocation RU 52 - UL BA */
12200 		run_system_wrapper(dut,
12201 				   "wifitool %s setUnitTestCmd 0x4b 5 9 0 2 1 2 2 2 3 2",
12202 				   ifname);
12203 	} else {
12204 		/* RU allocation RU 52 - DL ofdma data */
12205 		run_system_wrapper(dut,
12206 				   "wifitool %s setUnitTestCmd 0x4b 5 9 0 1 1 1 2 1 3 1",
12207 				   ifname);
12208 	}
12209 	/* Force TBPPDU duration to 400 us */
12210 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 400",
12211 			   ifname);
12212 	/* 0 to enable MU BAR, 1 to enable SU BAR */
12213 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 49 0",
12214 			   ifname);
12215 	/* MU BAR */
12216 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 64 0",
12217 			   ifname);
12218 }
12219 
12220 
ath_set_trigger_type_3(struct sigma_dut * dut,const char * ifname)12221 static void ath_set_trigger_type_3(struct sigma_dut *dut, const char *ifname)
12222 {
12223 	/* TriggerType "3" for MU RTS */
12224 	/* Send MU RTS Trigger - '1' is to enable MU RTS */
12225 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 101 1",
12226 			   ifname);
12227 }
12228 
12229 
ath_set_trigger_type_4(struct sigma_dut * dut,const char * ifname,const char * basedev)12230 static void ath_set_trigger_type_4(struct sigma_dut *dut, const char *ifname,
12231 				   const char *basedev)
12232 {
12233 	/* TriggerType "4" for BSRP */
12234 	run_system_wrapper(dut, "cfg80211tool %s he_ul_trig_int 200", basedev);
12235 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 1000",
12236 			   ifname);
12237 	if (dut->ap_channel >= 36) {
12238 		run_system_wrapper(dut,
12239 				   "wifitool %s setUnitTestCmd 0x47 2 42 1",
12240 				   ifname);
12241 	} else {
12242 		run_system_wrapper(dut,
12243 				   "wifitool %s setUnitTestCmd 0x47 2 42 2",
12244 				   ifname);
12245 	}
12246 	/* Send BSRP command */
12247 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 7",
12248 			   ifname);
12249 }
12250 
12251 
ath_ap_set_rfeature(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)12252 static enum sigma_cmd_result ath_ap_set_rfeature(struct sigma_dut *dut,
12253 						 struct sigma_conn *conn,
12254 						 struct sigma_cmd *cmd)
12255 {
12256 	const char *val;
12257 	const char *ifname;
12258 	enum sigma_cmd_result res;
12259 	const char *basedev = "wifi0";
12260 	int trigtype;
12261 	int he_ackpolicymac = 0;
12262 	char *num_ss = NULL;
12263 	char *nss[4] = { NULL, NULL, NULL, NULL };
12264 	char *aid[4] = { NULL, NULL, NULL, NULL };
12265 	char *aid_ss = NULL;
12266 	int omctrl_rxnss = 0, omctrl_chwidth = 0;
12267 	int param;
12268 	unsigned char mac_addr[ETH_ALEN];
12269 
12270 	memset(mac_addr, 0x00, ETH_ALEN);
12271 
12272 	ifname = get_main_ifname(dut);
12273 
12274 	if (sigma_radio_ifname[0])
12275 		basedev = sigma_radio_ifname[0];
12276 
12277 	/* Disable vap reset between the commands */
12278 	novap_reset(dut, ifname, 1);
12279 
12280 	val = get_param(cmd, "Opt_md_notif_ie");
12281 	if (val && ath_vht_op_mode_notif(dut, ifname, val) < 0)
12282 		return ERROR_SEND_STATUS;
12283 
12284 	/* TODO: Optional arguments */
12285 
12286 	val = get_param(cmd, "nss_mcs_opt");
12287 	if (val && ath_vht_nss_mcs(dut, ifname, val) < 0)
12288 		return ERROR_SEND_STATUS;
12289 
12290 	val = get_param(cmd, "chnum_band");
12291 	if (val && ath_vht_chnum_band(dut, ifname, val) < 0)
12292 		return ERROR_SEND_STATUS;
12293 
12294 	val = get_param(cmd, "RTS_FORCE");
12295 	if (val)
12296 		ath_config_rts_force(dut, ifname, val);
12297 
12298 	val = get_param(cmd, "DYN_BW_SGNL");
12299 	if (val)
12300 		ath_config_dyn_bw_sig(dut, ifname, val);
12301 
12302 	val = get_param(cmd, "CTS_WIDTH");
12303 	if (val)
12304 		ath_set_cts_width(dut, ifname, val);
12305 
12306 	val = get_param(cmd, "Ndpa_stainfo_mac");
12307 	if (val && ath_ndpa_stainfo_mac(dut, ifname, val) < 0)
12308 		return ERROR_SEND_STATUS;
12309 
12310 	val = get_param(cmd, "txBandwidth");
12311 	if (val && ath_set_width(dut, conn, ifname, val) < 0)
12312 		return ERROR_SEND_STATUS;
12313 
12314 	val = get_param(cmd, "Assoc_Disallow");
12315 	if (val)
12316 		ath_set_assoc_disallow(dut, ifname, val);
12317 
12318 
12319 	ath_set_nebor_bssid(dut, ifname, cmd);
12320 	val = get_param(cmd, "BTMReq_DisAssoc_Imnt");
12321 	if (val) {
12322 		dut->ap_btmreq_disassoc_imnt = atoi(val);
12323 		dut->ap_disassoc_timer = 1000;
12324 	}
12325 
12326 	val = get_param(cmd, "BTMReq_Term_Bit");
12327 	if (val)
12328 		dut->ap_btmreq_term_bit = atoi(val);
12329 
12330 	val = get_param(cmd, "Assoc_Delay");
12331 	if (val) {
12332 		dut->ap_assoc_delay = 1;
12333 		run_iwpriv(dut, ifname, "mbo_asoc_ret %s", val);
12334 	}
12335 
12336 	val = get_param(cmd, "Disassoc_Timer");
12337 	if (val)
12338 		dut->ap_disassoc_timer = atoi(val);
12339 
12340 	val = get_param(cmd, "BSS_Term_Duration");
12341 	if (val)
12342 		dut->ap_btmreq_bss_term_dur = atoi(val);
12343 
12344 	val = get_param(cmd, "BSS_Term_TSF");
12345 	if (val)
12346 		dut->ap_btmreq_bss_term_tsf = atoi(val);
12347 
12348 	val = get_param(cmd, "TxPower");
12349 	if (val)
12350 		ath_set_txpower(dut, ifname, val);
12351 
12352 	val = get_param(cmd, "DownlinkAvailCap");
12353 	if (val)
12354 		dut->ap_dl_availcap = atoi(val);
12355 
12356 	val = get_param(cmd, "UplinkAvailCap");
12357 	if (val) {
12358 		dut->ap_ul_availcap = atoi(val);
12359 		run_iwpriv(dut, ifname, "oce_wan_mtr %d %d",
12360 			   dut->ap_dl_availcap, dut->ap_ul_availcap);
12361 	}
12362 
12363 	val = get_param(cmd, "RSSIthreshold");
12364 	if (val) {
12365 		int rssithreshold;
12366 
12367 		run_iwpriv(dut, ifname, "oce_asoc_rej 1");
12368 		rssithreshold = atoi(val);
12369 		run_iwpriv(dut, ifname, "oce_asoc_rssi %d", rssithreshold);
12370 	}
12371 
12372 	val = get_param(cmd, "RetryDelay");
12373 	if (val) {
12374 		int retrydelay;
12375 
12376 		run_iwpriv(dut, ifname, "oce_asoc_rej 1");
12377 		retrydelay = atoi(val);
12378 		run_iwpriv(dut, ifname, "oce_asoc_dly %d", retrydelay);
12379 	}
12380 
12381 	val = get_param(cmd, "LTF");
12382 	if (val) {
12383 		if (dut->ap_fixed_rate) {
12384 			res = he_ltf(dut, conn, ifname, val);
12385 			if (res != SUCCESS_SEND_STATUS)
12386 				return res;
12387 		} else {
12388 			free(dut->ar_ltf);
12389 			dut->ar_ltf = strdup(val);
12390 			if (!dut->ar_ltf)
12391 				return ERROR_SEND_STATUS;
12392 		}
12393 	}
12394 
12395 	val = get_param(cmd, "GI");
12396 	if (val) {
12397 		if (dut->ap_fixed_rate)
12398 			res = he_shortgi(dut, conn, ifname, val);
12399 		else
12400 			res = he_ar_gi_ltf_mask(dut, conn, ifname, val);
12401 		if (res != SUCCESS_SEND_STATUS)
12402 			return res;
12403 	}
12404 
12405 	val = get_param(cmd, "RUAllocTones");
12406 	if (val) {
12407 		res = he_rualloctones(dut, conn, ifname, val);
12408 		if (res != SUCCESS_SEND_STATUS)
12409 			return res;
12410 	}
12411 
12412 	val = get_param(cmd, "MPDU_MU_SpacingFactor");
12413 	if (val)
12414 		run_system_wrapper(dut,
12415 				   "wifitool %s setUnitTestCmd 0x48 2 119, %s",
12416 				   ifname, val);
12417 
12418 	val = get_param(cmd, "PPDUTxType");
12419 	if (val) {
12420 		if (strcasecmp(val, "HE-SU") == 0) {
12421 			/* Change PPDU format type to HE-SU MCS 1 */
12422 			run_system_wrapper(dut,
12423 					   "wifitool %s setUnitTestCmd 0x48 2 89 0x401",
12424 					   ifname);
12425 		} else if (strcasecmp(val, "legacy") == 0) {
12426 			/* Change PPDU format type to non-HT */
12427 			run_system_wrapper(dut,
12428 					   "wifitool %s setUnitTestCmd 0x48 2 89 3",
12429 					   ifname);
12430 		} else {
12431 			send_resp(dut, conn, SIGMA_ERROR,
12432 				  "errorCode,Unsupported PPDUTxType");
12433 			return STATUS_SENT_ERROR;
12434 		}
12435 	}
12436 
12437 	val = get_param(cmd, "TXOPDuration");
12438 	if (val) {
12439 		if (strcasecmp(val, "UNSPECIFIED") == 0) {
12440 			/* The hardware is hardcoded with 0x7f; do nothing */
12441 		} else {
12442 			send_resp(dut, conn, SIGMA_ERROR,
12443 				  "errorCode,Unsupported TXOPDuration");
12444 			return STATUS_SENT_ERROR;
12445 		}
12446 	}
12447 
12448 	val = get_param(cmd, "Trig_Usrinfo_UL-MCS");
12449 	if (val)
12450 		run_iwpriv(dut, ifname, "he_ul_mcs %d", atoi(val));
12451 
12452 	val = get_param(cmd, "Trig_Usrinfo_UL-Target-RSSI");
12453 	if (val) {
12454 		/* Set target RSSI to -55 dBm */
12455 		run_system_wrapper(dut,
12456 				   "wifitool %s setUnitTestCmd 0x4b 2 7 %d",
12457 				   ifname, atoi(val) - 110);
12458 	}
12459 
12460 	val = get_param(cmd, "Trig_Interval");
12461 	if (val)
12462 		run_iwpriv(dut, basedev, "he_ul_trig_int %d", atoi(val));
12463 
12464 	val = get_param(cmd, "Trig_ComInfo_ULLength");
12465 	if (val)
12466 		run_system_wrapper(dut,
12467 				   "wifitool %s setUnitTestCmd 0x48 2 141 %d",
12468 				   ifname, atoi(val));
12469 
12470 	val = get_param(cmd, "DisableTriggerType");
12471 	if (val) {
12472 		trigtype = atoi(val);
12473 		switch (trigtype) {
12474 		case 0:
12475 			/* DisableTriggerType "0" for basic trigger */
12476 			run_system_wrapper(dut,
12477 					   "wifitool %s setUnitTestCmd 0x47 2 42 0",
12478 					   ifname);
12479 			break;
12480 		default:
12481 			/* Nothing to be done for now */
12482 			break;
12483 		}
12484 	}
12485 
12486 	val = get_param(cmd, "Trigger_TxBF");
12487 	if (val) {
12488 		if (strcasecmp(val, "enable") == 0) {
12489 			run_iwpriv(dut, ifname, "he_sounding_mode 0x9");
12490 		} else if (strcasecmp(val, "disable") == 0) {
12491 			run_iwpriv(dut, ifname, "he_sounding_mode 0x1");
12492 		} else {
12493 			send_resp(dut, conn, SIGMA_ERROR,
12494 				  "errorCode,Unsupported trigger_txbf");
12495 			return STATUS_SENT_ERROR;
12496 		}
12497 	}
12498 
12499 	val = get_param(cmd, "Trig_UsrInfo_RUAlloc");
12500 	if (val) {
12501 		res = he_rualloctones(dut, conn, ifname, val);
12502 		if (res != SUCCESS_SEND_STATUS)
12503 			return res;
12504 	}
12505 
12506 	val = get_param(cmd, "TriggerCoding");
12507 	if (val) {
12508 		if (strcasecmp(val, "BCC") == 0) {
12509 			/* In case of LDPC enable this command can force BCC if
12510 			 * RU size <= 242 */
12511 			run_iwpriv(dut, ifname, "he_ul_ldpc 0");
12512 		} else if (strcasecmp(val, "LDPC") == 0) {
12513 			novap_reset(dut, ifname, 0);
12514 			run_iwpriv(dut, ifname, "he_ul_ldpc 1");
12515 			novap_reset(dut, ifname, 1);
12516 		} else {
12517 			send_resp(dut, conn, SIGMA_ERROR,
12518 				  "errorCode,Unsupported TriggerCoding");
12519 			return STATUS_SENT_ERROR;
12520 		}
12521 	}
12522 
12523 	val = get_param(cmd, "AckPolicy_MAC");
12524 	if (val) {
12525 		if (parse_mac_address(dut, val, mac_addr) < 0) {
12526 			send_resp(dut, conn, SIGMA_ERROR,
12527 				  "errorCode,MAC Address not in proper format");
12528 			return STATUS_SENT_ERROR;
12529 		}
12530 		he_ackpolicymac = 1;
12531 	}
12532 
12533 	val = get_param(cmd, "AckPolicy");
12534 	if (val) {
12535 		int ap_he_ackpolicy;
12536 
12537 		ap_he_ackpolicy = atoi(val);
12538 		if (ap_he_ackpolicy == 0 && he_ackpolicymac) {
12539 			/* Disable all-BAR ackpolicy for MU-MIMO */
12540 			run_system_wrapper(dut,
12541 					   "wifitool %s setUnitTestCmd 0x48 2 62 0",
12542 					   ifname);
12543 			/* Disable all-BAR ackpolicy first */
12544 			run_system_wrapper(dut,
12545 					   "wifitool %s setUnitTestCmd 0x48 2 64 0",
12546 					   ifname);
12547 			/* Set normal ack policy for the STA with the specified
12548 			 * MAC address in DL-TX case */
12549 			run_system_wrapper(dut,
12550 					   "wifitool %s setUnitTestCmd 0x4b 8 8 1 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
12551 					   ifname, mac_addr[0], mac_addr[1],
12552 					   mac_addr[2], mac_addr[3],
12553 					   mac_addr[4], mac_addr[5]);
12554 		} else if (ap_he_ackpolicy == 3) {
12555 			/* Enable all-BAR ackpolicy for MU-MIMO DL */
12556 			run_system_wrapper(dut,
12557 					   "wifitool %s setUnitTestCmd 0x48 2 62 1",
12558 					   ifname);
12559 			/* Enable all-BAR ackpolicy */
12560 			run_system_wrapper(dut,
12561 					   "wifitool %s setUnitTestCmd 0x48 2 64 1",
12562 					   ifname);
12563 		} else if (ap_he_ackpolicy == 4) {
12564 			/* Enable htp-ack ackpolicy */
12565 			run_system_wrapper(dut,
12566 					   "wifitool %s setUnitTestCmd 0x47 2 99 1",
12567 					   ifname);
12568 		} else {
12569 			send_resp(dut, conn, SIGMA_ERROR,
12570 				  "errorCode,Invalid AckPolicy setting");
12571 			return STATUS_SENT_ERROR;
12572 		}
12573 	}
12574 
12575 	val = get_param(cmd, "Trig_ComInfo_GI-LTF");
12576 	if (val) {
12577 		int trig_gi_ltf;
12578 
12579 		trig_gi_ltf = atoi(val);
12580 		if (trig_gi_ltf == 0) {
12581 			he_ltf(dut, conn, ifname, "3.2");
12582 			he_shortgi(dut, conn, ifname, "1.6");
12583 		} else if (trig_gi_ltf == 1) {
12584 			he_ltf(dut, conn, ifname, "6.4");
12585 			he_shortgi(dut, conn, ifname, "1.6");
12586 		} else if (trig_gi_ltf == 2) {
12587 			he_ltf(dut, conn, ifname, "12.8");
12588 			he_shortgi(dut, conn, ifname, "3.2");
12589 		} else {
12590 			send_resp(dut, conn, SIGMA_ERROR,
12591 				  "errorCode,Unsupported Trig_ComInfo_GI-LTF");
12592 			return STATUS_SENT_ERROR;
12593 		}
12594 	}
12595 
12596 	val = get_param(cmd, "Trig_ComInfo_BW");
12597 	if (val) {
12598 		int chwidth;
12599 
12600 		chwidth = atoi(val);
12601 		/* Set the channel width */
12602 		run_iwpriv(dut, ifname, "chwidth %d", chwidth);
12603 	}
12604 
12605 	val = get_param(cmd, "NumSS");
12606 	if (val) {
12607 		int i = 0;
12608 		char *numss_val;
12609 		char *saveptr;
12610 
12611 		num_ss = strdup(val);
12612 		if (!num_ss)
12613 			return ERROR_SEND_STATUS;
12614 
12615 		numss_val = strtok_r(num_ss, " ", &saveptr);
12616 		for (i = 0; numss_val && i < 4; i++) {
12617 			nss[i] = numss_val;
12618 			numss_val = strtok_r(NULL, " ", &saveptr);
12619 		}
12620 	}
12621 
12622 	val = get_param(cmd, "NumSS_MAC");
12623 	if (val) {
12624 		char *sta_mac_str;
12625 		char *saveptr;
12626 		char *sta_mac_list_str;
12627 
12628 		sta_mac_list_str = strdup(val);
12629 		if (!sta_mac_list_str) {
12630 			free(num_ss);
12631 			return ERROR_SEND_STATUS;
12632 		}
12633 
12634 		sta_mac_str = strtok_r(sta_mac_list_str, " ", &saveptr);
12635 		if (sta_mac_str && nss[0]) {
12636 			run_system_wrapper(dut,
12637 					   "wifitool %s chmask_persta %s %s",
12638 					   ifname, sta_mac_str, nss[0]);
12639 		}
12640 
12641 		sta_mac_str = strtok_r(NULL, " ", &saveptr);
12642 		if (sta_mac_str && nss[1]) {
12643 			run_system_wrapper(dut,
12644 					   "wifitool %s chmask_persta %s %s",
12645 					   ifname, sta_mac_str, nss[1]);
12646 		}
12647 
12648 		sta_mac_str = strtok_r(NULL, " ", &saveptr);
12649 		if (sta_mac_str && nss[2]) {
12650 			run_system_wrapper(dut,
12651 					   "wifitool %s chmask_persta %s %s",
12652 					   ifname, sta_mac_str, nss[2]);
12653 		}
12654 
12655 		sta_mac_str = strtok_r(NULL, " ", &saveptr);
12656 		if (sta_mac_str && nss[3]) {
12657 			run_system_wrapper(dut,
12658 					   "wifitool %s chmask_persta %s %s",
12659 					   ifname, sta_mac_str, nss[3]);
12660 		}
12661 
12662 		free(sta_mac_list_str);
12663 	}
12664 
12665 	free(num_ss);
12666 	num_ss = NULL;
12667 
12668 	val = get_param(cmd, "AID");
12669 	if (val) {
12670 		int i = 0;
12671 		char *aid_val;
12672 		char *saveptr;
12673 
12674 		aid_ss = strdup(val);
12675 		if (!aid_ss)
12676 			return ERROR_SEND_STATUS;
12677 
12678 		aid_val = strtok_r(aid_ss, " ", &saveptr);
12679 		for (i = 0; aid_val && i < 4; i++) {
12680 			aid[i] = aid_val;
12681 			aid_val = strtok_r(NULL, " ", &saveptr);
12682 		}
12683 	}
12684 
12685 	val = get_param(cmd, "AddbaReq");
12686 	if (val) {
12687 		if (strcasecmp(val, "enable") == 0) {
12688 			run_iwpriv(dut, ifname, "setaddbaoper 1");
12689 			run_system_wrapper(dut,
12690 					   "wifitool %s sendaddba %s 0 64",
12691 					   ifname, aid[0]);
12692 		} else {
12693 			send_resp(dut, conn, SIGMA_ERROR,
12694 				  "errorCode,Unsupported AddbaReq value");
12695 			free(aid_ss);
12696 			return STATUS_SENT_ERROR;
12697 		}
12698 	}
12699 
12700 	val = get_param(cmd, "AddbaResp");
12701 	if (val) {
12702 		if (aid_ss && strcasecmp(val, "accepted") == 0) {
12703 			int aid_1 = atoi(aid_ss);
12704 
12705 			if (aid_1 == 1)
12706 				aid_1 = 2;
12707 			else
12708 				aid_1 = aid_1 - 1;
12709 
12710 			/* There is no mechanism in place to reject Add BA Req
12711 			 * from all STAs and selectively accept Add BA Req from
12712 			 * a specified STA. Instead, it can accept Add BA Req
12713 			 * from all STAs and selectively reject from specified
12714 			 * STAs. Make changes for the same using the below
12715 			 * commands. */
12716 			run_system_wrapper(dut, ifname, "setaddbaoper 1");
12717 			run_system_wrapper(dut, "wifitool %s refusealladdbas 0",
12718 					   ifname);
12719 			run_system_wrapper(dut,
12720 					   "wifitool %s setaddbaresp %d 0 37",
12721 					   ifname, aid_1);
12722 		} else {
12723 			send_resp(dut, conn, SIGMA_ERROR,
12724 				  "errorCode,Unsupported Addbaresp value");
12725 			free(aid_ss);
12726 			return STATUS_SENT_ERROR;
12727 		}
12728 	}
12729 
12730 	val = get_param(cmd, "Trig_UsrInfo_SSAlloc_RA-RU");
12731 	if (val) {
12732 		char *ssalloc_str;
12733 		char *saveptr;
12734 		char *ssalloc_list_str;
12735 
12736 		ssalloc_list_str = strdup(val);
12737 		if (!ssalloc_list_str) {
12738 			free(aid_ss);
12739 			return ERROR_SEND_STATUS;
12740 		}
12741 
12742 		ssalloc_str = strtok_r(ssalloc_list_str, ":", &saveptr);
12743 		if (ssalloc_str && aid[0]) {
12744 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12745 					   ifname, aid[0], ssalloc_str);
12746 		}
12747 
12748 		ssalloc_str = strtok_r(NULL, " ", &saveptr);
12749 		if (ssalloc_str && aid[1]) {
12750 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12751 					   ifname, aid[1], ssalloc_str);
12752 		}
12753 
12754 		ssalloc_str = strtok_r(NULL, " ", &saveptr);
12755 		if (ssalloc_str && aid[2]) {
12756 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12757 					   ifname, aid[2], ssalloc_str);
12758 		}
12759 
12760 		ssalloc_str = strtok_r(NULL, " ", &saveptr);
12761 		if (ssalloc_str && aid[3]) {
12762 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12763 					   ifname, aid[3], ssalloc_str);
12764 		}
12765 
12766 		free(ssalloc_list_str);
12767 	}
12768 
12769 	free(aid_ss);
12770 	aid_ss = NULL;
12771 
12772 	val = get_param(cmd, "OMCtrl_RxNSS");
12773 	if (val)
12774 		omctrl_rxnss = atoi(val);
12775 
12776 	val = get_param(cmd, "OMCtrl_ChnlWidth");
12777 	if (val)
12778 		omctrl_chwidth = atoi(val);
12779 
12780 	val = get_param(cmd, "Client_mac");
12781 	if (val) {
12782 		if (parse_mac_address(dut, val, mac_addr) < 0) {
12783 			send_resp(dut, conn, SIGMA_ERROR,
12784 				  "errorCode,MAC Address not in proper format");
12785 			return STATUS_SENT_ERROR;
12786 		}
12787 
12788 		/* setUnitTestCmd 13 7 1 mac3mac2mac1mac0 mac5mac4 <rx_nss>
12789 		 * <bw> <ulmu> <tx_nss> */
12790 		run_system_wrapper(dut,
12791 				   "wifitool %s setUnitTestCmd 13 7 1 0x%02x%02x%02x%02x 0x%02x%02x %d %d 1 %d",
12792 				   ifname, mac_addr[3], mac_addr[2],
12793 				   mac_addr[1], mac_addr[0], mac_addr[5],
12794 				   mac_addr[4], omctrl_rxnss,
12795 				   omctrl_chwidth, omctrl_rxnss);
12796 	}
12797 
12798 	val = get_param(cmd, "TriggerType");
12799 	if (val) {
12800 		trigtype = atoi(val);
12801 		switch (trigtype) {
12802 		case 0:
12803 			ath_set_trigger_type_0(dut, ifname);
12804 			break;
12805 		case 1:
12806 			ath_set_trigger_type_1(dut, ifname);
12807 			break;
12808 		case 2:
12809 			ath_set_trigger_type_2(dut, ifname);
12810 			break;
12811 		case 3:
12812 			ath_set_trigger_type_3(dut, ifname);
12813 			break;
12814 		case 4:
12815 			ath_set_trigger_type_4(dut, ifname, basedev);
12816 			break;
12817 		default:
12818 			send_resp(dut, conn, SIGMA_ERROR,
12819 				  "errorCode,TriggerType not supported");
12820 			return STATUS_SENT_ERROR;
12821 		}
12822 	}
12823 
12824 	val = get_param(cmd, "HE_TXOPDurRTSThr");
12825 	if (val)
12826 		run_iwpriv(dut, ifname, "he_rtsthrshld %d", atoi(val));
12827 
12828 	val = get_param(cmd, "NAV_Update");
12829 	if (val) {
12830 		if (strcasecmp(val, "disable") == 0) {
12831 			run_iwpriv(dut, basedev, "nav_config 1 0");
12832 		} else if (strcasecmp(val, "enable") == 0) {
12833 			/* Do nothing */
12834 		} else {
12835 			send_resp(dut, conn, SIGMA_ERROR,
12836 				  "errorCode,Unsupported NAV update");
12837 			return STATUS_SENT_ERROR;
12838 		}
12839 	}
12840 
12841 	/* Configure WMM Parameter Elements */
12842 	val = get_param(cmd, "STA_WMMPE_ECWmin_BE");
12843 	if (val) {
12844 		param = atoi(val);
12845 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BE, param);
12846 	}
12847 
12848 	val = get_param(cmd, "STA_WMMPE_ECWmin_BK");
12849 	if (val) {
12850 		param = atoi(val);
12851 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BK, param);
12852 	}
12853 
12854 	val = get_param(cmd, "STA_WMMPE_ECWmin_VI");
12855 	if (val) {
12856 		param = atoi(val);
12857 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VI, param);
12858 	}
12859 
12860 	val = get_param(cmd, "STA_WMMPE_ECWmin_VO");
12861 	if (val) {
12862 		param = atoi(val);
12863 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VO, param);
12864 	}
12865 
12866 	val = get_param(cmd, "STA_WMMPE_ECWmax_BE");
12867 	if (val) {
12868 		param = atoi(val);
12869 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BE, param);
12870 	}
12871 
12872 	val = get_param(cmd, "STA_WMMPE_ECWmax_BK");
12873 	if (val) {
12874 		param = atoi(val);
12875 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BK, param);
12876 	}
12877 
12878 	val = get_param(cmd, "STA_WMMPE_ECWmax_VI");
12879 	if (val) {
12880 		param = atoi(val);
12881 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VI, param);
12882 	}
12883 
12884 	val = get_param(cmd, "STA_WMMPE_ECWmax_VO");
12885 	if (val) {
12886 		param = atoi(val);
12887 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VO, param);
12888 	}
12889 
12890 	val = get_param(cmd, "STA_WMMPE_AIFSN_BE");
12891 	if (val) {
12892 		param = atoi(val);
12893 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BE, param);
12894 	}
12895 
12896 	val = get_param(cmd, "STA_WMMPE_AIFSN_BK");
12897 	if (val) {
12898 		param = atoi(val);
12899 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BK, param);
12900 	}
12901 
12902 	val = get_param(cmd, "STA_WMMPE_AIFSN_VI");
12903 	if (val) {
12904 		param = atoi(val);
12905 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VI, param);
12906 	}
12907 
12908 	val = get_param(cmd, "STA_WMMPE_AIFSN_VO");
12909 	if (val) {
12910 		param = atoi(val);
12911 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VO, param);
12912 	}
12913 
12914 
12915 	val = get_param(cmd, "STA_WMMPE_TXOP_BE");
12916 	if (val) {
12917 		param = atoi(val);
12918 		run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BE, param);
12919 	}
12920 
12921 	val = get_param(cmd, "STA_WMMPE_TOXP_BK");
12922 	if (val) {
12923 		param = atoi(val);
12924 		run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BK, param);
12925 	}
12926 
12927 	val = get_param(cmd, "STA_WMMPE_TXOP_VI");
12928 	if (val) {
12929 		param = atoi(val);
12930 		run_iwpriv(dut, ifname, "txoplimit %d %d", AP_AC_VI, param);
12931 	}
12932 
12933 	val = get_param(cmd, "STA_WMMPE_TXOP_VO");
12934 	if (val) {
12935 		param = atoi(val);
12936 		run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_VO, param);
12937 	}
12938 
12939 	/* Configure MU EDCA */
12940 	val = get_param(cmd, "STA_MUEDCA_ECWmin_BE");
12941 	if (val) {
12942 		param = atoi(val);
12943 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BE, param);
12944 	}
12945 
12946 	val = get_param(cmd, "STA_MUEDCA_ECWmin_BK");
12947 	if (val) {
12948 		param = atoi(val);
12949 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BK, param);
12950 	}
12951 
12952 	val = get_param(cmd, "STA_MUEDCA_ECWmin_VI");
12953 	if (val) {
12954 		param = atoi(val);
12955 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VI, param);
12956 	}
12957 
12958 	val = get_param(cmd, "STA_MUEDCA_ECWmin_VO");
12959 	if (val) {
12960 		param = atoi(val);
12961 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VO, param);
12962 	}
12963 
12964 	val = get_param(cmd, "STA_MUEDCA_ECWmax_BE");
12965 	if (val) {
12966 		param = atoi(val);
12967 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BE, param);
12968 	}
12969 
12970 	val = get_param(cmd, "STA_MUEDCA_ECWmax_BK");
12971 	if (val) {
12972 		param = atoi(val);
12973 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BK, param);
12974 	}
12975 
12976 	val = get_param(cmd, "STA_MUEDCA_ECWmax_VI");
12977 	if (val) {
12978 		param = atoi(val);
12979 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VI, param);
12980 	}
12981 
12982 	val = get_param(cmd, "STA_MUEDCA_ECWmax_VO");
12983 	if (val) {
12984 		param = atoi(val);
12985 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VO, param);
12986 	}
12987 
12988 	val = get_param(cmd, "STA_MUEDCA_AIFSN_BE");
12989 	if (val) {
12990 		param = atoi(val);
12991 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BE, param);
12992 	}
12993 
12994 	val = get_param(cmd, "STA_MUEDCA_AIFSN_BK");
12995 	if (val) {
12996 		param = atoi(val);
12997 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BK, param);
12998 	}
12999 
13000 	val = get_param(cmd, "STA_MUEDCA_AIFSN_VI");
13001 	if (val) {
13002 		param = atoi(val);
13003 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VI, param);
13004 	}
13005 
13006 	val = get_param(cmd, "STA_MUEDCA_AIFSN_VO");
13007 	if (val) {
13008 		param = atoi(val);
13009 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VO, param);
13010 	}
13011 
13012 	val = get_param(cmd, "STA_MUEDCA_Timer_BE");
13013 	if (val) {
13014 		param = atoi(val);
13015 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BE, param);
13016 	}
13017 
13018 	val = get_param(cmd, "STA_MUEDCA_Timer_BK");
13019 	if (val) {
13020 		param = atoi(val);
13021 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BK, param);
13022 	}
13023 
13024 	val = get_param(cmd, "STA_MUEDCA_Timer_VI");
13025 	if (val) {
13026 		param = atoi(val);
13027 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VI, param);
13028 	}
13029 
13030 	val = get_param(cmd, "STA_MUEDCA_Timer_VO");
13031 	if (val) {
13032 		param = atoi(val);
13033 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VO, param);
13034 	}
13035 
13036 	return SUCCESS_SEND_STATUS;
13037 }
13038 
13039 
wcn_vht_chnum_band(struct sigma_dut * dut,const char * ifname,const char * val)13040 static int wcn_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
13041 			      const char *val)
13042 {
13043 	char *token, *result;
13044 	int channel = 36;
13045 	char *saveptr;
13046 
13047 	/* Extract the channel info */
13048 	token = strdup(val);
13049 	if (!token)
13050 		return -1;
13051 	result = strtok_r(token, ";", &saveptr);
13052 	if (result)
13053 		channel = atoi(result);
13054 
13055 	/* Issue the channel switch command */
13056 	run_iwpriv(dut, ifname, "setChanChange %d", channel);
13057 
13058 	free(token);
13059 	return 0;
13060 }
13061 
13062 
wcn_ap_set_rfeature(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13063 static enum sigma_cmd_result wcn_ap_set_rfeature(struct sigma_dut *dut,
13064 						 struct sigma_conn *conn,
13065 						 struct sigma_cmd *cmd)
13066 {
13067 	const char *val;
13068 	const char *ifname;
13069 
13070 	ifname = get_main_ifname(dut);
13071 
13072 	val = get_param(cmd, "chnum_band");
13073 	if (val && wcn_vht_chnum_band(dut, ifname, val) < 0)
13074 		return ERROR_SEND_STATUS;
13075 
13076 	val = get_param(cmd, "txBandwidth");
13077 	if (val) {
13078 		int old_ch_bw = dut->ap_chwidth;
13079 
13080 		if (strcasecmp(val, "Auto") == 0) {
13081 			dut->ap_chwidth = 0;
13082 		} else if (strcasecmp(val, "20") == 0) {
13083 			dut->ap_chwidth = 0;
13084 		} else if (strcasecmp(val, "40") == 0) {
13085 			dut->ap_chwidth = 1;
13086 		} else if (strcasecmp(val, "80") == 0) {
13087 			dut->ap_chwidth = 2;
13088 		} else if (strcasecmp(val, "160") == 0) {
13089 			dut->ap_chwidth = 3;
13090 		} else {
13091 			send_resp(dut, conn, SIGMA_ERROR,
13092 				  "ErrorCode,WIDTH not supported");
13093 			return STATUS_SENT_ERROR;
13094 		}
13095 		if (old_ch_bw != dut->ap_chwidth) {
13096 			if (cmd_ap_config_commit(dut, conn, cmd) <= 0)
13097 				return STATUS_SENT_ERROR;
13098 		} else {
13099 			sigma_dut_print(dut, DUT_MSG_DEBUG, "No change in BW");
13100 		}
13101 	}
13102 
13103 	val = get_param(cmd, "GI");
13104 	if (val) {
13105 		int fix_rate_sgi;
13106 
13107 		if (strcmp(val, "0.8") == 0) {
13108 			run_iwpriv(dut, ifname, "enable_short_gi 9");
13109 			fix_rate_sgi = 1;
13110 		} else if (strcmp(val, "1.6") == 0) {
13111 			run_iwpriv(dut, ifname, "enable_short_gi 10");
13112 			fix_rate_sgi = 2;
13113 		} else if (strcmp(val, "3.2") == 0) {
13114 			run_iwpriv(dut, ifname, "enable_short_gi 11");
13115 			fix_rate_sgi = 3;
13116 		} else {
13117 			send_resp(dut, conn, SIGMA_ERROR,
13118 				  "errorCode,GI value not supported");
13119 			return STATUS_SENT_ERROR;
13120 		}
13121 		run_iwpriv(dut, ifname, "enable_short_gi %d", fix_rate_sgi);
13122 	}
13123 
13124 	val = get_param(cmd, "LTF");
13125 	if (val) {
13126 #ifdef NL80211_SUPPORT
13127 		if (strcmp(val, "3.2") == 0) {
13128 			wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_1X);
13129 		} if (strcmp(val, "6.4") == 0) {
13130 			wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_2X);
13131 		} else if (strcmp(val, "12.8") == 0) {
13132 			wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_4X);
13133 		} else {
13134 			send_resp(dut, conn, SIGMA_ERROR,
13135 				  "errorCode,LTF value not supported");
13136 			return STATUS_SENT;
13137 		}
13138 #else /* NL80211_SUPPORT */
13139 		sigma_dut_print(dut, DUT_MSG_ERROR,
13140 				"LTF cannot be set without NL80211_SUPPORT defined");
13141 		return ERROR_SEND_STATUS;
13142 #endif /* NL80211_SUPPORT */
13143 	}
13144 
13145 	return SUCCESS_SEND_STATUS;
13146 }
13147 
13148 
mac80211_vht_chnum_band(struct sigma_dut * dut,const char * ifname,const char * val)13149 static int mac80211_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
13150 				   const char *val)
13151 {
13152 	char *token, *result;
13153 	int channel = 36, chwidth = 80, center_freq_idx, center_freq,
13154 		channel_freq;
13155 	char buf[100];
13156 	char *saveptr;
13157 	int res;
13158 
13159 	/* Extract the channel info */
13160 	token = strdup(val);
13161 	if (!token)
13162 		return -1;
13163 	result = strtok_r(token, ";", &saveptr);
13164 	if (result)
13165 		channel = atoi(result);
13166 
13167 	/* Extract the channel width info */
13168 	result = strtok_r(NULL, ";", &saveptr);
13169 	if (result)
13170 		chwidth = atoi(result);
13171 
13172 	center_freq_idx = get_oper_centr_freq_seq_idx(chwidth, channel);
13173 	if (center_freq_idx < 0) {
13174 		free(token);
13175 		return -1;
13176 	}
13177 
13178 	center_freq = get_5g_channel_freq(center_freq_idx);
13179 	channel_freq = get_5g_channel_freq(channel);
13180 
13181 	/* Issue the channel switch command */
13182 	res = snprintf(buf, sizeof(buf),
13183 		       " -i %s chan_switch 10 %d sec_channel_offset=1 center_freq1=%d bandwidth=%d blocktx vht",
13184 		       ifname, channel_freq, center_freq, chwidth);
13185 	if (res < 0 || res >= sizeof(buf) || run_hostapd_cli(dut, buf) != 0) {
13186 		sigma_dut_print(dut, DUT_MSG_ERROR,
13187 				"hostapd_cli chan_switch failed");
13188 	}
13189 
13190 	free(token);
13191 	return 0;
13192 }
13193 
13194 
13195 static enum sigma_cmd_result
mac80211_he_tx_bandwidth(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val,const char * type)13196 mac80211_he_tx_bandwidth(struct sigma_dut *dut, struct sigma_conn *conn,
13197 			 const char *ifname, const char *val, const char *type)
13198 {
13199 	int width, center_freq_idx, center_freq, channel_freq, res;
13200 	char *mode, buf[256];
13201 
13202 	if (!type) {
13203 		send_resp(dut, conn, SIGMA_INVALID,
13204 			  "errorCode,Missing type parameter");
13205 		return STATUS_SENT_ERROR;
13206 	}
13207 
13208 	if (strcasecmp(type, "HE") == 0) {
13209 		mode = "he";
13210 	} else if (strcasecmp(type, "VHT") == 0) {
13211 		mode = "vht";
13212 	} else if (strcasecmp(type, "HT") == 0) {
13213 		mode = "ht";
13214 	} else {
13215 		send_resp(dut, conn, SIGMA_ERROR,
13216 			  "errorCode,Unsupported type value");
13217 		return STATUS_SENT_ERROR;
13218 	}
13219 
13220 	width = atoi(val);
13221 	center_freq_idx = get_oper_centr_freq_seq_idx(width, dut->ap_channel);
13222 	if (center_freq_idx < 0)
13223 		return ERROR_SEND_STATUS;
13224 
13225 	center_freq = get_5g_channel_freq(center_freq_idx);
13226 	channel_freq = get_5g_channel_freq(dut->ap_channel);
13227 
13228 	res = snprintf(buf, sizeof(buf),
13229 		       "CHAN_SWITCH 10 %d sec_channel_offset=1 center_freq1=%d bandwidth=%d blocktx %s",
13230 		       channel_freq, center_freq, width, mode);
13231 
13232 	if (res < 0 || res >= sizeof(buf) || hapd_command(ifname, buf) != 0) {
13233 		send_resp(dut, conn, SIGMA_ERROR, "CHAN_SWITCH command failed");
13234 		return STATUS_SENT_ERROR;
13235 	}
13236 
13237 	return SUCCESS_SEND_STATUS;
13238 }
13239 
13240 
mac80211_he_ltf_mapping(struct sigma_dut * dut,const char * val)13241 static int mac80211_he_ltf_mapping(struct sigma_dut *dut,
13242 				   const char *val)
13243 {
13244 	if (strcmp(val, "3.2") == 0)
13245 		return 0x01;
13246 	if (strcmp(val, "6.4") == 0)
13247 		return 0x02;
13248 	if (strcmp(val, "12.8") == 0)
13249 		return 0x04;
13250 
13251 	sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported LTF value %s", val);
13252 	return -1;
13253 }
13254 
13255 
mac80211_he_ltf(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val)13256 static enum sigma_cmd_result mac80211_he_ltf(struct sigma_dut *dut,
13257 					     struct sigma_conn *conn,
13258 					     const char *ifname,
13259 					     const char *val)
13260 {
13261 	free(dut->ar_ltf);
13262 	dut->ar_ltf = strdup(val);
13263 	if (!dut->ar_ltf) {
13264 		send_resp(dut, conn, SIGMA_ERROR,
13265 			  "errorCode,Failed to store new LTF");
13266 		return STATUS_SENT_ERROR;
13267 	}
13268 	return SUCCESS_SEND_STATUS;
13269 }
13270 
13271 
mac80211_he_gi(struct sigma_dut * dut,const char * ifname,const char * val)13272 static enum sigma_cmd_result mac80211_he_gi(struct sigma_dut *dut,
13273 					    const char *ifname,
13274 					    const char *val)
13275 {
13276 	int16_t he_ltf = 0xFF;
13277 	char *mode = dut->use_5g ? "5" : "2.4";
13278 	int ret = -1;
13279 
13280 	if (dut->ar_ltf) {
13281 		he_ltf = mac80211_he_ltf_mapping(dut, dut->ar_ltf);
13282 		free(dut->ar_ltf);
13283 		dut->ar_ltf = NULL;
13284 
13285 		if (he_ltf < 0)
13286 			return ERROR_SEND_STATUS;
13287 
13288 		if (val) {
13289 			ret = run_system_wrapper(
13290 				dut,
13291 				"iw %s set bitrates he-gi-%s %s he-ltf-%s %u",
13292 				ifname, mode, val, mode,
13293 				he_ltf);
13294 		} else {
13295 			ret = run_system_wrapper(
13296 				dut,
13297 				"iw %s set bitrates he-ltf-%s %u",
13298 				ifname, mode, he_ltf);
13299 		}
13300 	} else if (val) {
13301 		ret = run_system_wrapper(dut,
13302 					 "iw %s set bitrates he-gi-%s %s",
13303 					 ifname, mode, val);
13304 	}
13305 	if (ret < 0)
13306 		return ERROR_SEND_STATUS;
13307 	return SUCCESS_SEND_STATUS;
13308 }
13309 
13310 
mac80211_set_ackpolicy_0(struct sigma_dut * dut,const char * ifname,unsigned char * mac_addr)13311 static void mac80211_set_ackpolicy_0(struct sigma_dut *dut, const char *ifname,
13312 				     unsigned char *mac_addr)
13313 {
13314 	char cmd[256];
13315 
13316 	/* Disable all-BAR ackpolicy for MU-MIMO */
13317 	fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 62 0", ifname);
13318 	/* Disable all-BAR ackpolicy first */
13319 	fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 64 0", ifname);
13320 
13321 	/*
13322 	 * Set the normal ack policy for the STA with the specified
13323 	 * MAC address in the DL TX case.
13324 	 */
13325 	snprintf(cmd, sizeof(cmd),
13326 		 "-m 0x4b -v 0 8 1 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
13327 		 mac_addr[0], mac_addr[1], mac_addr[2],
13328 		 mac_addr[3], mac_addr[4], mac_addr[5]);
13329 
13330 	fwtest_cmd_wrapper(dut, cmd, ifname);
13331 }
13332 
13333 
mac80211_set_ackpolicy_3(struct sigma_dut * dut,const char * ifname)13334 static void mac80211_set_ackpolicy_3(struct sigma_dut *dut, const char *ifname)
13335 {
13336 	/* Enable all-BAR ackpolicy for MU-MIMO DL */
13337 	fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 62 1", ifname);
13338 	/* Enable all-BAR ackpolicy */
13339 	fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 64 1", ifname);
13340 }
13341 
13342 
mac80211_set_ackpolicy_4(struct sigma_dut * dut,const char * ifname)13343 static void mac80211_set_ackpolicy_4(struct sigma_dut *dut, const char *ifname)
13344 {
13345 	/* Enable htp-ack ackpolicy */
13346 	fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 99 1", ifname);
13347 }
13348 
13349 
mac80211_ap_set_rfeature(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13350 static enum sigma_cmd_result mac80211_ap_set_rfeature(struct sigma_dut *dut,
13351 						      struct sigma_conn *conn,
13352 						      struct sigma_cmd *cmd)
13353 {
13354 	const char *val;
13355 	const char *ifname;
13356 	enum sigma_cmd_result res;
13357 	unsigned char mac_addr[ETH_ALEN];
13358 	int he_ackpolicymac = 0;
13359 	int ap_he_ackpolicy;
13360 
13361 	ifname = get_main_ifname(dut);
13362 
13363 	val = get_param(cmd, "RTS_FORCE");
13364 	if (val)
13365 		mac80211_config_rts_force(dut, ifname, val);
13366 
13367 	val = get_param(cmd, "chnum_band");
13368 	if (val && mac80211_vht_chnum_band(dut, ifname, val) < 0)
13369 		return -1;
13370 
13371 	val = get_param(cmd, "txBandwidth");
13372 	if (val) {
13373 		res = mac80211_he_tx_bandwidth(dut, conn, ifname, val,
13374 					       get_param(cmd, "type"));
13375 		if (res != SUCCESS_SEND_STATUS)
13376 			return res;
13377 	}
13378 
13379 	val = get_param(cmd, "LTF");
13380 	if (val) {
13381 		res = mac80211_he_ltf(dut, conn, ifname, val);
13382 		if (res != SUCCESS_SEND_STATUS)
13383 			return res;
13384 	}
13385 
13386 	val = get_param(cmd, "GI");
13387 	if (val || dut->ar_ltf) {
13388 		res = mac80211_he_gi(dut, ifname, val);
13389 		if (res != SUCCESS_SEND_STATUS)
13390 			return res;
13391 	}
13392 
13393 	val = get_param(cmd, "AckPolicy_MAC");
13394 	if (val) {
13395 		if (parse_mac_address(dut, val, mac_addr) < 0) {
13396 			send_resp(dut, conn, SIGMA_ERROR,
13397 				  "errorCode,MAC address not in proper format");
13398 			return STATUS_SENT_ERROR;
13399 		}
13400 
13401 		he_ackpolicymac = 1;
13402 	}
13403 
13404 	val = get_param(cmd, "AckPolicy");
13405 	if (val) {
13406 		ap_he_ackpolicy = atoi(val);
13407 
13408 		switch (ap_he_ackpolicy) {
13409 		case 0:
13410 			if (!he_ackpolicymac)
13411 				break;
13412 			mac80211_set_ackpolicy_0(dut, ifname, mac_addr);
13413 			break;
13414 		case 3:
13415 			mac80211_set_ackpolicy_3(dut, ifname);
13416 			break;
13417 		case 4:
13418 			mac80211_set_ackpolicy_4(dut, ifname);
13419 			break;
13420 		default:
13421 			send_resp(dut, conn, SIGMA_ERROR,
13422 				  "errorCode,Invalid AckPolicy setting");
13423 			return STATUS_SENT_ERROR;
13424 		}
13425 	}
13426 
13427 	return SUCCESS_SEND_STATUS;
13428 }
13429 
13430 
13431 #ifdef __linux__
wil6210_ap_set_rfeature(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13432 static int wil6210_ap_set_rfeature(struct sigma_dut *dut,
13433 				   struct sigma_conn *conn,
13434 				   struct sigma_cmd *cmd)
13435 {
13436 	const char *val;
13437 
13438 	val = get_param(cmd, "ExtSchIE");
13439 	if (val && !strcasecmp(val, "Enable")) {
13440 		struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
13441 		int count = MAX_ESE_ALLOCS;
13442 
13443 		if (sta_extract_60g_ese(dut, cmd, allocs, &count))
13444 			return -1;
13445 		if (wil6210_set_ese(dut, count, allocs))
13446 			return -1;
13447 		return 1;
13448 	}
13449 
13450 	send_resp(dut, conn, SIGMA_ERROR,
13451 		  "errorCode,Invalid ap_set_rfeature(60G)");
13452 	return 0;
13453 }
13454 #endif /* __linux__ */
13455 
13456 
cmd_ap_set_rfeature(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13457 static enum sigma_cmd_result cmd_ap_set_rfeature(struct sigma_dut *dut,
13458 						 struct sigma_conn *conn,
13459 						 struct sigma_cmd *cmd)
13460 {
13461 	/* const char *name = get_param(cmd, "NAME"); */
13462 	/* const char *type = get_param(cmd, "Type"); */
13463 	const char *val, *oci_chan, *oci_frametype;
13464 	char buf[100];
13465 	const char *ifname = get_hostapd_ifname(dut);
13466 
13467 	val = get_param(cmd, "ReassocResp_RSNXE_Used");
13468 	if (val) {
13469 		if (atoi(val) == 0)
13470 			snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 2");
13471 		else
13472 			snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 1");
13473 		if (hapd_command(ifname, buf) < 0) {
13474 			send_resp(dut, conn, SIGMA_ERROR,
13475 				  "ErrorCode,Failed to set ft_rsnxe_used");
13476 			return STATUS_SENT_ERROR;
13477 		}
13478 	}
13479 
13480 	oci_chan = get_param(cmd, "OCIChannel");
13481 	oci_frametype = get_param(cmd, "OCIFrameType");
13482 	if (oci_chan && oci_frametype) {
13483 		unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
13484 
13485 		if (!oci_freq) {
13486 			send_resp(dut, conn, SIGMA_ERROR,
13487 				  "errorCode,Invalid OCIChannel number");
13488 			return STATUS_SENT_ERROR;
13489 		}
13490 
13491 		if (strcasecmp(oci_frametype, "eapolM3") == 0) {
13492 			snprintf(buf, sizeof(buf),
13493 				 "SET oci_freq_override_eapol_m3 %d", oci_freq);
13494 		} else if (strcasecmp(oci_frametype, "eapolG1") == 0) {
13495 			snprintf(buf, sizeof(buf),
13496 				 "SET oci_freq_override_eapol_g1 %d", oci_freq);
13497 		} else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
13498 			snprintf(buf, sizeof(buf),
13499 				 "SET oci_freq_override_saquery_req %d",
13500 				 oci_freq);
13501 		} else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
13502 			snprintf(buf, sizeof(buf),
13503 				 "SET oci_freq_override_saquery_resp %d",
13504 				 oci_freq);
13505 		} else {
13506 			send_resp(dut, conn, SIGMA_ERROR,
13507 				  "errorCode,Unsupported OCIFrameType");
13508 			return STATUS_SENT_ERROR;
13509 		}
13510 		if (hapd_command(ifname, buf) < 0) {
13511 			send_resp(dut, conn, SIGMA_ERROR,
13512 				  "errorCode,Failed to set oci_freq_override");
13513 			return STATUS_SENT_ERROR;
13514 		}
13515 		return SUCCESS_SEND_STATUS;
13516 	}
13517 
13518 	val = get_param(cmd, "Transition_Disable");
13519 	if (val) {
13520 		if (atoi(val)) {
13521 			val = get_param(cmd, "Transition_Disable_Index");
13522 			if (!val) {
13523 				send_resp(dut, conn, SIGMA_INVALID,
13524 					  "errorCode,Transition_Disable without Transition_Disable_Index");
13525 				return STATUS_SENT;
13526 			}
13527 			dut->ap_transition_disable = 1 << atoi(val);
13528 		} else {
13529 			dut->ap_transition_disable = 0;
13530 		}
13531 
13532 		snprintf(buf, sizeof(buf), "SET transition_disable 0x%02x",
13533 			 dut->ap_transition_disable);
13534 		if (hapd_command(ifname, buf) < 0) {
13535 			send_resp(dut, conn, SIGMA_ERROR,
13536 				  "errorCode,Failed to update transition mode disabled indication");
13537 			return STATUS_SENT_ERROR;
13538 		}
13539 		return SUCCESS_SEND_STATUS;
13540 	}
13541 
13542 	switch (get_driver_type(dut)) {
13543 	case DRIVER_ATHEROS:
13544 		return ath_ap_set_rfeature(dut, conn, cmd);
13545 	case DRIVER_OPENWRT:
13546 		switch (get_openwrt_driver_type()) {
13547 		case OPENWRT_DRIVER_ATHEROS:
13548 			return ath_ap_set_rfeature(dut, conn, cmd);
13549 		default:
13550 			send_resp(dut, conn, SIGMA_ERROR,
13551 				  "errorCode,Unsupported ap_set_rfeature with the current openwrt driver");
13552 			return 0;
13553 		}
13554 	case DRIVER_LINUX_WCN:
13555 	case DRIVER_WCN:
13556 		return wcn_ap_set_rfeature(dut, conn, cmd);
13557 	case DRIVER_MAC80211:
13558 		return mac80211_ap_set_rfeature(dut, conn, cmd);
13559 #ifdef __linux__
13560 	case DRIVER_WIL6210:
13561 		return wil6210_ap_set_rfeature(dut, conn, cmd);
13562 #endif /* __linux__ */
13563 	default:
13564 		send_resp(dut, conn, SIGMA_ERROR,
13565 			  "errorCode,Unsupported ap_set_rfeature with the current driver");
13566 		return 0;
13567 	}
13568 }
13569 
13570 
cmd_accesspoint(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13571 static enum sigma_cmd_result cmd_accesspoint(struct sigma_dut *dut,
13572 					     struct sigma_conn *conn,
13573 					     struct sigma_cmd *cmd)
13574 {
13575 	/* const char *name = get_param(cmd, "NAME"); */
13576 	return 1;
13577 }
13578 
13579 
13580 static enum sigma_cmd_result
cmd_ap_preset_testparameters(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13581 cmd_ap_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
13582 			     struct sigma_cmd *cmd)
13583 {
13584 	const char *val;
13585 
13586 	val = get_param(cmd, "Oper_Chn");
13587 	if (val) {
13588 		dut->ap_oper_chn = 1;
13589 		dut->ap_channel = atoi(val);
13590 	}
13591 
13592 	val = get_param(cmd, "DPPConfiguratorAddress");
13593 	if (val) {
13594 		free(dut->ap_dpp_conf_addr);
13595 		dut->ap_dpp_conf_addr = strdup(val);
13596 	}
13597 
13598 	val = get_param(cmd, "DPPConfiguratorPKHash");
13599 	if (val) {
13600 		free(dut->ap_dpp_conf_pkhash);
13601 		dut->ap_dpp_conf_pkhash = strdup(val);
13602 	}
13603 
13604 	return 1;
13605 }
13606 
13607 
ap_register_cmds(void)13608 void ap_register_cmds(void)
13609 {
13610 	sigma_dut_reg_cmd("ap_ca_version", NULL, cmd_ap_ca_version);
13611 	sigma_dut_reg_cmd("ap_set_wireless", NULL, cmd_ap_set_wireless);
13612 	sigma_dut_reg_cmd("ap_send_addba_req", NULL, cmd_ap_send_addba_req);
13613 	sigma_dut_reg_cmd("ap_set_11n_wireless", NULL, cmd_ap_set_wireless);
13614 	sigma_dut_reg_cmd("ap_set_11n", NULL, cmd_ap_set_wireless);
13615 	sigma_dut_reg_cmd("ap_set_11d", NULL, cmd_ap_set_wireless);
13616 	sigma_dut_reg_cmd("ap_set_11h", NULL, cmd_ap_set_wireless);
13617 	sigma_dut_reg_cmd("ap_set_security", NULL, cmd_ap_set_security);
13618 	sigma_dut_reg_cmd("ap_set_apqos", NULL, cmd_ap_set_apqos);
13619 	sigma_dut_reg_cmd("ap_set_staqos", NULL, cmd_ap_set_staqos);
13620 	sigma_dut_reg_cmd("ap_set_radius", NULL, cmd_ap_set_radius);
13621 	sigma_dut_reg_cmd("ap_reboot", NULL, cmd_ap_reboot);
13622 	sigma_dut_reg_cmd("ap_config_commit", NULL, cmd_ap_config_commit);
13623 	sigma_dut_reg_cmd("ap_reset_default", NULL, cmd_ap_reset_default);
13624 	sigma_dut_reg_cmd("ap_get_info", NULL, cmd_ap_get_info);
13625 	sigma_dut_reg_cmd("ap_deauth_sta", NULL, cmd_ap_deauth_sta);
13626 	sigma_dut_reg_cmd("ap_send_frame", NULL, cmd_ap_send_frame);
13627 	sigma_dut_reg_cmd("ap_get_mac_address", NULL, cmd_ap_get_mac_address);
13628 	sigma_dut_reg_cmd("ap_set_pmf", NULL, cmd_ap_set_pmf);
13629 	sigma_dut_reg_cmd("ap_set_hs2", NULL, cmd_ap_set_hs2);
13630 	sigma_dut_reg_cmd("ap_set_rfeature", NULL, cmd_ap_set_rfeature);
13631 	sigma_dut_reg_cmd("ap_nfc_action", NULL, cmd_ap_nfc_action);
13632 	sigma_dut_reg_cmd("ap_wps_read_pin", NULL, cmd_ap_wps_read_pin);
13633 	sigma_dut_reg_cmd("ap_wps_enter_pin", NULL, cmd_ap_wps_enter_pin);
13634 	sigma_dut_reg_cmd("ap_wps_set_pbc", NULL, cmd_ap_wps_set_pbc);
13635 	sigma_dut_reg_cmd("ap_get_parameter", NULL, cmd_ap_get_parameter);
13636 	sigma_dut_reg_cmd("AccessPoint", NULL, cmd_accesspoint);
13637 	sigma_dut_reg_cmd("ap_preset_testparameters", NULL,
13638 			  cmd_ap_preset_testparameters);
13639 }
13640