xref: /wlan-dirver/utils/sigma-dut/ap.c (revision 5589dc81e8d4dae5102678042d344aa1383e0966)
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 /*
92  * MTU for Ethernet need to take into account 8-byte SNAP header
93  * to be added when encapsulating Ethernet frame into 802.11.
94  */
95 #ifndef IEEE80211_MAX_DATA_LEN_DMG
96 #define IEEE80211_MAX_DATA_LEN_DMG 7920
97 #endif /* IEEE80211_MAX_DATA_LEN_DMG */
98 #ifndef IEEE80211_SNAP_LEN_DMG
99 #define IEEE80211_SNAP_LEN_DMG 8
100 #endif /* IEEE80211_SNAP_LEN_DMG */
101 
102 extern char *sigma_wpas_ctrl;
103 extern char *sigma_hapd_ctrl;
104 extern char *ap_inet_addr;
105 extern char *ap_inet_mask;
106 extern char *sigma_radio_ifname[];
107 
108 static int ath_ap_start_hostapd(struct sigma_dut *dut);
109 static void ath_ap_set_params(struct sigma_dut *dut);
110 static int kill_process(struct sigma_dut *dut, char *proc_name,
111 			unsigned char is_proc_instance_one, int sig);
112 
113 
114 static int ap_ft_enabled(struct sigma_dut *dut)
115 {
116 	return dut->ap_ft_oa == 1 ||
117 		dut->ap_ft_ds == VALUE_ENABLED ||
118 		dut->ap_key_mgmt == AP_WPA2_FT_EAP ||
119 		dut->ap_key_mgmt == AP_WPA2_FT_PSK ||
120 		dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP ||
121 		(dut->ap_akm_values &
122 		 ((1 << AKM_FT_EAP) |
123 		  (1 << AKM_FT_PSK) |
124 		  (1 << AKM_FT_SAE) |
125 		  (1 << AKM_FT_SUITE_B) |
126 		  (1 << AKM_FT_FILS_SHA256) |
127 		  (1 << AKM_FT_FILS_SHA384)));
128 }
129 
130 
131 static enum sigma_cmd_result cmd_ap_ca_version(struct sigma_dut *dut,
132 					       struct sigma_conn *conn,
133 					       struct sigma_cmd *cmd)
134 {
135 	/* const char *name = get_param(cmd, "NAME"); */
136 	send_resp(dut, conn, SIGMA_COMPLETE, "version,1.0");
137 	return 0;
138 }
139 
140 
141 static void kill_hostapd_process_pid(struct sigma_dut *dut)
142 {
143 	FILE *f;
144 	int pid, res;
145 	char path[100];
146 	int count;
147 
148 	f = fopen(SIGMA_DUT_HOSTAPD_PID_FILE, "r");
149 	if (!f)
150 		return;
151 	res = fscanf(f, "%d", &pid);
152 	fclose(f);
153 	if (res != 1)
154 		return;
155 	sigma_dut_print(dut, DUT_MSG_INFO, "Killing hostapd pid %d", pid);
156 	kill(pid, SIGTERM);
157 	snprintf(path, sizeof(path), "/proc/%d", pid);
158 	for (count = 0; count < 20 && file_exists(path); count++)
159 		usleep(100000);
160 }
161 
162 
163 int get_hwaddr(const char *ifname, unsigned char *hwaddr)
164 {
165 #ifndef __QNXNTO__
166 	struct ifreq ifr;
167 	int s;
168 
169 	s = socket(AF_INET, SOCK_DGRAM, 0);
170 	if (s < 0)
171 		return -1;
172 	memset(&ifr, 0, sizeof(ifr));
173 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
174 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
175 		perror("ioctl");
176 		close(s);
177 		return -1;
178 	}
179 	close(s);
180 	memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
181 #else /* __QNXNTO__ */
182 	struct ifaddrs *ifaddrshead = NULL;
183 	int found = 0;
184 	struct ifaddrs *temp_ifap = NULL;
185 	struct sockaddr_dl *sdl = NULL;
186 
187 	if (getifaddrs(&ifaddrshead) != 0) {
188 		perror("getifaddrs failed");
189 		return -1;
190 	}
191 
192 	for (temp_ifap = ifaddrshead; ifaddrshead && !found;
193 	     ifaddrshead = ifaddrshead->ifa_next) {
194 		if (ifaddrshead->ifa_addr->sa_family == AF_LINK &&
195 		    strcmp(ifaddrshead->ifa_name, ifname) == 0) {
196 			found = 1;
197 			sdl = (struct sockaddr_dl *) ifaddrshead->ifa_addr;
198 			if (sdl)
199 				memcpy(hwaddr, LLADDR(sdl), sdl->sdl_alen);
200 		}
201 	}
202 
203 	if (temp_ifap)
204 		freeifaddrs(temp_ifap);
205 
206 	if (!found) {
207 		perror("Failed to get the interface");
208 		return -1;
209 	}
210 #endif /* __QNXNTO__ */
211 	return 0;
212 }
213 
214 
215 static void ath_ap_set_group_id(struct sigma_dut *dut, const char *ifname,
216 				const char *val)
217 {
218 	char buf[60];
219 
220 	snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 55 %d",
221 		 ifname, atoi(val));
222 	if (system(buf) != 0) {
223 		sigma_dut_print(dut, DUT_MSG_ERROR,
224 				"wifitool ap_group_id failed");
225 	}
226 }
227 
228 
229 void ath_set_cts_width(struct sigma_dut *dut, const char *ifname,
230 		       const char *val)
231 {
232 	char buf[60];
233 
234 	/* TODO: Enable support for other values */
235 	if (strcasecmp(val, "40") == 0) {
236 		snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 1",
237 			 ifname);
238 		if (system(buf) != 0) {
239 			sigma_dut_print(dut, DUT_MSG_ERROR,
240 					"wifitool cts_width failed");
241 		}
242 		snprintf(buf, sizeof(buf),
243 			 "athdiag --set --address=0x10024  --val=0xd90b8a14");
244 		if (system(buf) != 0) {
245 			sigma_dut_print(dut, DUT_MSG_ERROR,
246 					"disabling phy restart failed");
247 		}
248 	} else {
249 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported CTS_WIDTH");
250 	}
251 }
252 
253 
254 void ath_config_dyn_bw_sig(struct sigma_dut *dut, const char *ifname,
255 			   const char *val)
256 {
257 	char buf[60];
258 
259 	if (strcasecmp(val, "enable") == 0) {
260 		dut->ap_dyn_bw_sig = VALUE_ENABLED;
261 		run_iwpriv(dut, ifname, "cwmenable 1");
262 
263 		snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 96 1",
264 			 ifname);
265 		if (system(buf) != 0) {
266 			sigma_dut_print(dut, DUT_MSG_ERROR,
267 					"disabling RTS from rate control logic failed");
268 		}
269 	} else if (strcasecmp(val, "disable") == 0) {
270 		dut->ap_dyn_bw_sig = VALUE_DISABLED;
271 		run_iwpriv(dut, ifname, "cwmenable 0");
272 	} else {
273 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported DYN_BW_SGL");
274 	}
275 }
276 
277 
278 static void wcn_config_ap_ldpc(struct sigma_dut *dut, const char *ifname)
279 {
280 	if (dut->ap_ldpc == VALUE_NOT_SET)
281 		return;
282 	run_iwpriv(dut, ifname, "ldpc %d", dut->ap_ldpc != VALUE_DISABLED);
283 }
284 
285 
286 static void mac80211_config_rts_force(struct sigma_dut *dut, const char *ifname,
287 				      const char *val)
288 {
289 	char buf[60];
290 	char fname[128], path[128], *pos;
291 	ssize_t res;
292 
293 	res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
294 		       ifname);
295 	if (res < 0 || res >= sizeof(fname))
296 		return;
297 
298 	res = readlink(fname, path, sizeof(path));
299 	if (res < 0)
300 		return;
301 
302 	if (res >= (int) sizeof(path))
303 		res = sizeof(path) - 1;
304 	path[res] = '\0';
305 
306 	pos = strrchr(path, '/');
307 	if (!pos)
308 		pos = path;
309 	else
310 		pos++;
311 
312 	if (strcasecmp(val, "enable") == 0) {
313 		dut->ap_sig_rts = VALUE_ENABLED;
314 		res = snprintf(buf, sizeof(buf), "iw %s set rts 64", pos);
315 		if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
316 			sigma_dut_print(dut, DUT_MSG_ERROR,
317 					"iw set rts 64 failed");
318 		}
319 	} else if (strcasecmp(val, "disable") == 0) {
320 		dut->ap_sig_rts = VALUE_DISABLED;
321 		res = snprintf(buf, sizeof(buf), "iw %s set rts 2347", pos);
322 		if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
323 			sigma_dut_print(dut, DUT_MSG_ERROR,
324 					"iw rts 2347 failed");
325 		}
326 	} else {
327 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE");
328 	}
329 
330 }
331 
332 
333 static void ath_config_rts_force(struct sigma_dut *dut, const char *ifname,
334 				 const char *val)
335 {
336 	char buf[60];
337 
338 	if (strcasecmp(val, "enable") == 0) {
339 		dut->ap_sig_rts = VALUE_ENABLED;
340 		snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname);
341 		if (system(buf) != 0) {
342 			sigma_dut_print(dut, DUT_MSG_ERROR,
343 					"iwconfig rts 64 failed");
344 		}
345 		snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 100 1",
346 			 ifname);
347 		if (system(buf) != 0) {
348 			sigma_dut_print(dut, DUT_MSG_ERROR,
349 					"wifitool beeliner_fw_test 100 1 failed");
350 		}
351 	} else if (strcasecmp(val, "disable") == 0) {
352 		dut->ap_sig_rts = VALUE_DISABLED;
353 		snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname);
354 		if (system(buf) != 0) {
355 			sigma_dut_print(dut, DUT_MSG_ERROR,
356 					"iwconfig rts 2347 failed");
357 		}
358 	} else {
359 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE");
360 	}
361 }
362 
363 
364 static void ath_radio(struct sigma_dut *dut, const char *val)
365 {
366 	if (strcasecmp(val, "on") == 0) {
367 		if (dut->ap_interface_5g == 1) {
368 			run_system(dut, "uci set wireless.wifi0.disabled=0");
369 		} else if (dut->ap_interface_2g == 1) {
370 			run_system(dut, "uci set wireless.wifi1.disabled=0");
371 		} else {
372 			run_system(dut, "uci set wireless.wifi0.disabled=0");
373 			run_system(dut, "uci set wireless.wifi1.disabled=0");
374 		}
375 		run_system(dut, "uci commit");
376 		run_system(dut, "wifi down");
377 		run_system(dut, "wifi up");
378 	} else if (strcasecmp(val, "off") == 0) {
379 		if (dut->ap_interface_5g == 1) {
380 			run_system(dut, "uci set wireless.wifi0.disabled=1");
381 		} else if (dut->ap_interface_2g == 1) {
382 			run_system(dut, "uci set wireless.wifi1.disabled=1");
383 		} else {
384 			run_system(dut, "uci set wireless.wifi0.disabled=1");
385 			run_system(dut, "uci set wireless.wifi1.disabled=1");
386 		}
387 		run_system(dut, "uci commit");
388 		run_system(dut, "wifi down");
389 		run_system(dut, "wifi up");
390 	}
391 }
392 
393 
394 static void deauth_disassoc(struct sigma_dut *dut, const char *ifname,
395 			    const char *val)
396 {
397 	if (strcasecmp(val, "disable") == 0)
398 		run_iwpriv(dut, ifname, "stealthdown 1");
399 }
400 
401 
402 static void ath_set_txpower(struct sigma_dut *dut, const char *ifname,
403 			    const char *val)
404 {
405 	char buf[60];
406 
407 	if (strcasecmp(val, "high") == 0)
408 		snprintf(buf, sizeof(buf), "iwconfig %s txpower 29", ifname);
409 	else if (strcasecmp(val, "low") == 0)
410 		snprintf(buf, sizeof(buf), "iwconfig %s txpower 1", ifname);
411 	else
412 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported txpower");
413 
414 	if (system(buf) != 0)
415 		sigma_dut_print(dut, DUT_MSG_ERROR, "setting txpower failed");
416 }
417 
418 
419 static enum ap_mode get_mode(const char *str)
420 {
421 	if (strcasecmp(str, "11a") == 0)
422 		return AP_11a;
423 	else if (strcasecmp(str, "11g") == 0)
424 		return AP_11g;
425 	else if (strcasecmp(str, "11b") == 0)
426 		return AP_11b;
427 	else if (strcasecmp(str, "11na") == 0)
428 		return AP_11na;
429 	else if (strcasecmp(str, "11ng") == 0)
430 		return AP_11ng;
431 	else if (strcasecmp(str, "11ac") == 0 || strcasecmp(str, "ac") == 0)
432 		return AP_11ac;
433 	else if (strcasecmp(str, "11ad") == 0)
434 		return AP_11ad;
435 	else if (strcasecmp(str, "11ax") == 0)
436 		return AP_11ax;
437 	else
438 		return AP_inval;
439 }
440 
441 
442 static int run_hostapd_cli(struct sigma_dut *dut, char *buf)
443 {
444 	char command[1000];
445 	const char *bin;
446 	enum driver_type drv = get_driver_type(dut);
447 	char *sigma_hapd_file = sigma_hapd_ctrl;
448 
449 	if (file_exists("hostapd_cli"))
450 		bin = "./hostapd_cli";
451 	else if (file_exists("../../hostapd/hostapd_cli"))
452 		bin = "../../hostapd/hostapd_cli";
453 	else
454 		bin = "hostapd_cli";
455 
456 	if (drv == DRIVER_OPENWRT && sigma_hapd_ctrl == NULL) {
457 		sigma_hapd_file = "/var/run/hostapd-wifi0";
458 
459 		if (sigma_radio_ifname[0] &&
460 		    strcmp(sigma_radio_ifname[0], "wifi1") == 0)
461 			sigma_hapd_file = "/var/run/hostapd-wifi1";
462 		else if (sigma_radio_ifname[0] &&
463 			 strcmp(sigma_radio_ifname[0], "wifi2") == 0)
464 			sigma_hapd_file = "/var/run/hostapd-wifi2";
465 	}
466 
467 	if (sigma_hapd_file)
468 		snprintf(command, sizeof(command), "%s -p %s %s",
469 			 bin, sigma_hapd_file, buf);
470 	else
471 		snprintf(command, sizeof(command), "%s %s", bin, buf);
472 	return run_system(dut, command);
473 }
474 
475 
476 static int ath_set_lci_config(struct sigma_dut *dut, const char *val,
477 			      struct sigma_cmd *cmd)
478 {
479 	FILE *f;
480 	int i;
481 
482 	f = fopen("/tmp/lci_cfg.txt", "w");
483 	if (!f) {
484 		sigma_dut_print(dut, DUT_MSG_ERROR,
485 				"Failed to open /tmp/lci_cfg.txt");
486 		return -1;
487 	}
488 
489 	for (i = 2; i < cmd->count; i++)
490 		fprintf(f, "%s = %s \n", cmd->params[i], cmd->values[i]);
491 	fprintf(f, "\n");
492 	fclose(f);
493 
494 	return 0;
495 }
496 
497 
498 static void set_ap_country_code(struct sigma_dut *dut)
499 {
500 #if defined(ANDROID) || defined(LINUX_EMBEDDED)
501 	char buf[256];
502 
503 	if (dut->ap_countrycode[0]) {
504 		snprintf(buf, sizeof(buf), "DRIVER COUNTRY %s",
505 			 dut->ap_countrycode);
506 		if (wpa_command(get_station_ifname(dut), buf) < 0)
507 			sigma_dut_print(dut, DUT_MSG_ERROR,
508 					"Failed to set country code");
509 		else
510 			sigma_dut_print(dut, DUT_MSG_INFO,
511 					"Successfully set country code to %s",
512 					dut->ap_countrycode);
513 	}
514 #endif
515 }
516 
517 
518 static void set_vht_mcsmap_nss(struct sigma_dut *dut, int nss, int mcs)
519 {
520 	switch (nss) {
521 	case 1:
522 		switch (mcs) {
523 		case 7:
524 			dut->ap_vhtmcs_map = 0xfffc;
525 			break;
526 		case 8:
527 			dut->ap_vhtmcs_map = 0xfffd;
528 			break;
529 		case 9:
530 			dut->ap_vhtmcs_map = 0xfffe;
531 			break;
532 		default:
533 			dut->ap_vhtmcs_map = 0xfffe;
534 			break;
535 		}
536 		break;
537 	case 2:
538 		switch (mcs) {
539 		case 7:
540 			dut->ap_vhtmcs_map = 0xfff0;
541 			break;
542 		case 8:
543 			dut->ap_vhtmcs_map = 0xfff5;
544 			break;
545 		case 9:
546 			dut->ap_vhtmcs_map = 0xfffa;
547 			break;
548 		default:
549 			dut->ap_vhtmcs_map = 0xfffa;
550 			break;
551 		}
552 		break;
553 	case 3:
554 		switch (mcs) {
555 		case 7:
556 			dut->ap_vhtmcs_map = 0xffc0;
557 			break;
558 		case 8:
559 			dut->ap_vhtmcs_map = 0xffd5;
560 			break;
561 		case 9:
562 			dut->ap_vhtmcs_map = 0xffea;
563 			break;
564 		default:
565 			dut->ap_vhtmcs_map = 0xffea;
566 			break;
567 		}
568 	default:
569 		dut->ap_vhtmcs_map = 0xffea;
570 		break;
571 	}
572 }
573 
574 
575 /* Get 2*nss bitmask */
576 /* We are trying to pack 2-bit MCS values per NSS in a 16-bit wide field.
577  * IEEE P802.11ax/D5.0, 9.4.2.247.4 supported HE-MCS And NSS Set field
578  * defines the following format for the 16 bit value. */
579 
580 #define HE_GET_MCS_NSS_PACK_MASK(nss) ((1 << ((nss) << 1)) - 1)
581 
582 static void he_reset_mcs_values_for_unsupported_ss(uint8_t *mcsnssmap,
583 						   uint8_t nss)
584 {
585 	uint8_t nssmask;
586 
587 	if (nss <= 4) {
588 		nssmask = ~HE_GET_MCS_NSS_PACK_MASK(nss);
589 		mcsnssmap[0] |= nssmask;
590 		mcsnssmap[1] = 0xff;
591 	} else if (nss > 4 && nss <= 8) {
592 		nssmask = ~HE_GET_MCS_NSS_PACK_MASK(nss - 4);
593 		mcsnssmap[0] &= 0xff;
594 		mcsnssmap[1] |= nssmask;
595 	}
596 }
597 
598 
599 static void get_he_mcs_nssmap(uint8_t *mcsnssmap, uint8_t nss,
600 			      uint8_t mcs)
601 {
602 	switch (mcs) {
603 	case 11:
604 		mcsnssmap[0] = 0xaa;
605 		mcsnssmap[1] = 0xaa;
606 		break;
607 	case 9:
608 		mcsnssmap[0] = 0x55;
609 		mcsnssmap[1] = 0x55;
610 		break;
611 	case 7:
612 		mcsnssmap[0] = 0x0;
613 		mcsnssmap[1] = 0x0;
614 		break;
615 	}
616 	he_reset_mcs_values_for_unsupported_ss(mcsnssmap, nss);
617 }
618 
619 
620 static enum sigma_cmd_result cmd_ap_set_wireless(struct sigma_dut *dut,
621 						 struct sigma_conn *conn,
622 						 struct sigma_cmd *cmd)
623 {
624 	/* const char *name = get_param(cmd, "NAME"); */
625 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
626 	const char *val;
627 	unsigned int wlan_tag = 1;
628 	const char *ifname = get_main_ifname(dut);
629 	char buf[128];
630 
631 	/* Allow program to be overridden if specified in the ap_set_wireless
632 	 * to support some 60 GHz test scripts where the program may be 60 GHz
633 	 * or WPS. */
634 	val = get_param(cmd, "PROGRAM");
635 	if (val)
636 		dut->program = sigma_program_to_enum(val);
637 
638 	val = get_param(cmd, "WLAN_TAG");
639 	if (val) {
640 		wlan_tag = atoi(val);
641 		if (wlan_tag < 1 || wlan_tag > 3) {
642 			/*
643 			 * The only valid WLAN Tags as of now as per the latest
644 			 * WFA scripts are 1, 2, and 3.
645 			 */
646 			send_resp(dut, conn, SIGMA_INVALID,
647 				  "errorCode,Invalid WLAN_TAG");
648 			return STATUS_SENT;
649 		}
650 	}
651 
652 	val = get_param(cmd, "Interface");
653 	if (val) {
654 		if (strcasecmp(val, "5G") == 0)
655 			dut->ap_interface_5g = 1;
656 		else
657 			dut->ap_interface_2g = 1;
658 
659 		if (dut->ap_interface_5g && dut->ap_interface_2g)
660 			dut->ap_is_dual = 1;
661 	}
662 
663 	val = get_param(cmd, "CountryCode");
664 	if (val) {
665 		if (strlen(val) > sizeof(dut->ap_countrycode) - 1)
666 			return INVALID_SEND_STATUS;
667 		snprintf(dut->ap_countrycode, sizeof(dut->ap_countrycode),
668 			 "%s", val);
669 
670 		/*
671 		 * Regdomain self-managed driver does not accept hostapd country
672 		 * code setting in all cases. Try to use wpa_supplicant DRIVER
673 		 * command first to set the driver to a specific country code
674 		 * before starting AP functionality. This is targeting cases
675 		 * where wpa_supplicant is running on the device as well for
676 		 * non-AP mode functionality.
677 		 */
678 		if (get_driver_type(dut) == DRIVER_LINUX_WCN)
679 			set_ap_country_code(dut);
680 	}
681 
682 	val = get_param(cmd, "regulatory_mode");
683 	if (val) {
684 		if (strcasecmp(val, "11d") == 0 || strcasecmp(val, "11h") == 0)
685 			dut->ap_regulatory_mode = AP_80211D_MODE_ENABLED;
686 	}
687 
688 	val = get_param(cmd, "SSID");
689 	if (val) {
690 		if (strlen(val) > sizeof(dut->ap_ssid) - 1)
691 			return INVALID_SEND_STATUS;
692 
693 		if (wlan_tag == 1) {
694 			/*
695 			 * If tag is not specified, it is deemed to be 1.
696 			 * Hence tag of 1 is a special case and the values
697 			 * corresponding to wlan-tag=1 are stored separately
698 			 * from the values corresponding tags 2 and 3.
699 			 * This approach minimises the changes to existing code
700 			 * since most of the sigma_dut code does not deal with
701 			 * WLAN-TAG CAPI variable.
702 			 */
703 			snprintf(dut->ap_ssid,
704 				 sizeof(dut->ap_ssid), "%s", val);
705 		} else {
706 			snprintf(dut->ap_tag_ssid[wlan_tag - 2],
707 				 sizeof(dut->ap_tag_ssid[wlan_tag - 2]),
708 				 "%s", val);
709 		}
710 	}
711 
712 	val = get_param(cmd, "CHANNEL");
713 	if (val) {
714 		const char *pos;
715 		dut->ap_channel = atoi(val);
716 		pos = strchr(val, ';');
717 		if (pos) {
718 			pos++;
719 			dut->ap_channel_1 = atoi(pos);
720 		}
721 	}
722 
723 	/* Overwrite the AP channel with DFS channel if configured */
724 	val = get_param(cmd, "dfs_chan");
725 	if (val) {
726 		dut->ap_channel = atoi(val);
727 	}
728 
729 	val = get_param(cmd, "dfs_mode");
730 	if (val) {
731 		if (strcasecmp(val, "Enable") == 0)
732 			dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
733 		else if (strcasecmp(val, "Disable") == 0)
734 			dut->ap_dfs_mode = AP_DFS_MODE_DISABLED;
735 		else
736 			sigma_dut_print(dut, DUT_MSG_ERROR,
737 					"Unsupported dfs_mode value: %s", val);
738 	}
739 
740 	val = get_param(cmd, "MODE");
741 	if (val) {
742 		char *str, *pos;
743 
744 		str = strdup(val);
745 		if (str == NULL)
746 			return INVALID_SEND_STATUS;
747 		pos = strchr(str, ';');
748 		if (pos)
749 			*pos++ = '\0';
750 
751 		dut->ap_is_dual = 0;
752 		dut->ap_mode = get_mode(str);
753 		if (dut->ap_mode == AP_inval) {
754 			send_resp(dut, conn, SIGMA_INVALID,
755 				  "errorCode,Unsupported MODE");
756 			free(str);
757 			return STATUS_SENT;
758 		}
759 		if (dut->ap_mode == AP_11ac && dut->ap_80plus80 != 1)
760 			dut->ap_chwidth = AP_80;
761 
762 		if (pos) {
763 			dut->ap_mode_1 = get_mode(pos);
764 			if (dut->ap_mode_1 == AP_inval) {
765 				send_resp(dut, conn, SIGMA_INVALID,
766 					  "errorCode,Unsupported MODE");
767 				free(str);
768 				return STATUS_SENT;
769 			}
770 			if (dut->ap_mode_1 == AP_11ac)
771 				dut->ap_chwidth_1 = AP_80;
772 			dut->ap_is_dual = 1;
773 		}
774 
775 		free(str);
776 	} else if (dut->ap_mode == AP_inval) {
777 		if (dut->ap_channel <= 11)
778 			dut->ap_mode = AP_11ng;
779 		else if (dut->program == PROGRAM_VHT)
780 			dut->ap_mode = AP_11ac;
781 		else
782 			dut->ap_mode = AP_11na;
783 	}
784 
785 	/* Override the AP mode in case of 60 GHz */
786 	if (dut->program == PROGRAM_60GHZ) {
787 		dut->ap_mode = AP_11ad;
788 		/* Workaround to force channel 2 if not specified */
789 		if (!dut->ap_channel)
790 			dut->ap_channel = 2;
791 	}
792 
793 	switch (dut->ap_mode) {
794 	case AP_11g:
795 	case AP_11b:
796 	case AP_11ng:
797 		dut->use_5g = 0;
798 		break;
799 	case AP_11a:
800 	case AP_11na:
801 	case AP_11ac:
802 		dut->use_5g = 1;
803 		break;
804 	case AP_11ax:
805 		if (dut->ap_channel >= 1 && dut->ap_channel <= 14)
806 			dut->use_5g = 0;
807 		else if (dut->ap_channel >= 36 && dut->ap_channel <= 171)
808 			dut->use_5g = 1;
809 		break;
810 	case AP_11ad:
811 	case AP_inval:
812 		break;
813 	}
814 
815 	val = get_param(cmd, "WME");
816 	if (val) {
817 		if (strcasecmp(val, "on") == 0)
818 			dut->ap_wme = AP_WME_ON;
819 		else if (strcasecmp(val, "off") == 0)
820 			dut->ap_wme = AP_WME_OFF;
821 		else
822 			sigma_dut_print(dut, DUT_MSG_ERROR,
823 					"Unsupported WME value: %s", val);
824 	}
825 
826 	val = get_param(cmd, "WMMPS");
827 	if (val) {
828 		if (strcasecmp(val, "on") == 0)
829 			dut->ap_wmmps = AP_WMMPS_ON;
830 		else if (strcasecmp(val, "off") == 0)
831 			dut->ap_wmmps = AP_WMMPS_OFF;
832 		else
833 			sigma_dut_print(dut, DUT_MSG_ERROR,
834 					"Unsupported WMMPS value: %s", val);
835 	}
836 
837 	val = get_param(cmd, "RTS");
838 	if (val)
839 		dut->ap_rts = atoi(val);
840 
841 	val = get_param(cmd, "FRGMNT");
842 	if (val)
843 		dut->ap_frgmnt = atoi(val);
844 
845 	/* TODO: PWRSAVE */
846 
847 	val = get_param(cmd, "BCNINT");
848 	if (val)
849 		dut->ap_bcnint = atoi(val);
850 
851 	val = get_param(cmd, "RADIO");
852 	if (val) {
853 		enum driver_type drv = get_driver_type(dut);
854 
855 		if (strcasecmp(val, "on") == 0) {
856 			if (drv == DRIVER_OPENWRT)
857 				ath_radio(dut, val);
858 			if (drv == DRIVER_ATHEROS)
859 				ath_ap_start_hostapd(dut);
860 			else if (cmd_ap_config_commit(dut, conn, cmd) <= 0)
861 				return STATUS_SENT;
862 		} else if (strcasecmp(val, "off") == 0) {
863 			if (drv == DRIVER_OPENWRT) {
864 				ath_radio(dut, val);
865 			} else if (dut->use_hostapd_pid_file) {
866 				kill_hostapd_process_pid(dut);
867 			} else if (kill_process(dut, "(hostapd)", 1,
868 						SIGTERM) == 0 ||
869 				   system("killall hostapd") == 0) {
870 				sigma_dut_print(dut, DUT_MSG_INFO,
871 						"Killed hostapd on radio,off");
872 			}
873 		} else {
874 			send_resp(dut, conn, SIGMA_INVALID,
875 				  "errorCode,Unsupported RADIO value");
876 			return STATUS_SENT;
877 		}
878 	}
879 
880 	val = get_param(cmd, "P2PMgmtBit");
881 	if (val)
882 		dut->ap_p2p_mgmt = atoi(val);
883 
884 	/* TODO: ChannelUsage */
885 
886 	/* TODO: 40_INTOLERANT */
887 
888 	val = get_param(cmd, "ADDBA_REJECT");
889 	if (val) {
890 		if (strcasecmp(val, "Enable") == 0)
891 			dut->ap_addba_reject = VALUE_ENABLED;
892 		else if (strcasecmp(val, "Disable") == 0)
893 			dut->ap_addba_reject = VALUE_DISABLED;
894 	}
895 
896 	val = get_param(cmd, "AMPDU");
897 	if (val) {
898 		if (strcasecmp(val, "Enable") == 0)
899 			dut->ap_ampdu = VALUE_ENABLED;
900 		else if (strcasecmp(val, "Disable") == 0)
901 			dut->ap_ampdu = VALUE_DISABLED;
902 	}
903 
904 	val = get_param(cmd, "AMPDU_EXP");
905 	if (val)
906 		dut->ap_ampdu_exp = atoi(val);
907 
908 	val = get_param(cmd, "AMSDU");
909 	if (val) {
910 		if (strcasecmp(val, "Enable") == 0)
911 			dut->ap_amsdu = VALUE_ENABLED;
912 		else if (strcasecmp(val, "Disable") == 0)
913 			dut->ap_amsdu = VALUE_DISABLED;
914 	}
915 
916 	val = get_param(cmd, "NoAck");
917 	if (val) {
918 		if (strcasecmp(val, "on") == 0)
919 			dut->ap_noack = VALUE_ENABLED;
920 		else if (strcasecmp(val, "off") == 0)
921 			dut->ap_noack = VALUE_DISABLED;
922 	}
923 
924 	/* TODO: GREENFIELD */
925 	/* TODO: MCS_32 */
926 
927 	val = get_param(cmd, "OFFSET");
928 	if (val) {
929 		if (strcasecmp(val, "Above") == 0)
930 			dut->ap_chwidth_offset = SEC_CH_40ABOVE;
931 		else if (strcasecmp(val, "Below") == 0)
932 			dut->ap_chwidth_offset = SEC_CH_40BELOW;
933 	}
934 
935 	val = get_param(cmd, "MCS_FIXEDRATE");
936 	if (val) {
937 		dut->ap_fixed_rate = 1;
938 		dut->ap_mcs = atoi(val);
939 	}
940 
941 	val = get_param(cmd, "SPATIAL_RX_STREAM");
942 	if (val) {
943 		if (strcasecmp(val, "1SS") == 0 || strcasecmp(val, "1") == 0) {
944 			dut->ap_rx_streams = 1;
945 			if (dut->device_type == AP_testbed)
946 				dut->ap_vhtmcs_map = 0xfffc;
947 		} else if (strcasecmp(val, "2SS") == 0 ||
948 			   strcasecmp(val, "2") == 0) {
949 			dut->ap_rx_streams = 2;
950 			if (dut->device_type == AP_testbed)
951 				dut->ap_vhtmcs_map = 0xfff0;
952 		} else if (strcasecmp(val, "3SS") == 0 ||
953 			   strcasecmp(val, "3") == 0) {
954 			dut->ap_rx_streams = 3;
955 			if (dut->device_type == AP_testbed)
956 				dut->ap_vhtmcs_map = 0xffc0;
957 		} else if (strcasecmp(val, "4SS") == 0 ||
958 			   strcasecmp(val, "4") == 0) {
959 			dut->ap_rx_streams = 4;
960 		}
961 	}
962 
963 	val = get_param(cmd, "SPATIAL_TX_STREAM");
964 	if (val) {
965 		if (strcasecmp(val, "1SS") == 0 ||
966 		    strcasecmp(val, "1") == 0) {
967 			dut->ap_tx_streams = 1;
968 			if (dut->device_type == AP_testbed)
969 				dut->ap_vhtmcs_map =  0xfffc;
970 		} else if (strcasecmp(val, "2SS") == 0 ||
971 			   strcasecmp(val, "2") == 0) {
972 			dut->ap_tx_streams = 2;
973 			if (dut->device_type == AP_testbed)
974 				dut->ap_vhtmcs_map = 0xfff0;
975 		} else if (strcasecmp(val, "3SS") == 0 ||
976 			   strcasecmp(val, "3") == 0) {
977 			dut->ap_tx_streams = 3;
978 			if (dut->device_type == AP_testbed)
979 				dut->ap_vhtmcs_map = 0xffc0;
980 		} else if (strcasecmp(val, "4SS") == 0 ||
981 			   strcasecmp(val, "4") == 0) {
982 			dut->ap_tx_streams = 4;
983 		}
984 	}
985 
986 	val = get_param(cmd, "BSS_max_idle");
987 	if (val) {
988 		if (strncasecmp(val, "Enable", 7) == 0) {
989 			dut->wnm_bss_max_feature = VALUE_ENABLED;
990 		} else if (strncasecmp(val, "Disable", 8) == 0) {
991 			dut->wnm_bss_max_feature = VALUE_DISABLED;
992 		} else {
993 			send_resp(dut, conn, SIGMA_ERROR,
994 				  "errorCode,Invalid value for BSS_max_Feature");
995 			return STATUS_SENT;
996 		}
997 	}
998 
999 	val = get_param(cmd, "BSS_Idle_Protection_options");
1000 	if (val) {
1001 		int protection = (int) strtol(val, (char **) NULL, 10);
1002 
1003 		if (protection != 1 && protection != 0) {
1004 			send_resp(dut, conn, SIGMA_ERROR,
1005 				  "errorCode,Invalid value for BSS_Idle_Protection_options");
1006 			return STATUS_SENT;
1007 		}
1008 		dut->wnm_bss_max_protection = protection ?
1009 			VALUE_ENABLED : VALUE_DISABLED;
1010 	}
1011 
1012 	val = get_param(cmd, "BSS_max_Idle_period");
1013 	if (val) {
1014 		long int idle_time = strtol(val, (char **) NULL, 10);
1015 
1016 		if (idle_time == LONG_MIN || idle_time == LONG_MAX) {
1017 			send_resp(dut, conn, SIGMA_ERROR,
1018 				  "errorCode,Invalid value for BSS_max_Idle_period");
1019 			return STATUS_SENT;
1020 		}
1021 		dut->wnm_bss_max_idle_time = (int) idle_time;
1022 	}
1023 
1024 	val = get_param(cmd, "PROXY_ARP");
1025 	if (val)
1026 		dut->ap_proxy_arp = (int) strtol(val, (char **) NULL, 10);
1027 
1028 	val = get_param(cmd, "nss_mcs_cap");
1029 	if (val) {
1030 		int nss, mcs;
1031 		char token[20];
1032 		char *result = NULL;
1033 		char *saveptr;
1034 
1035 		if (strlen(val) >= sizeof(token))
1036 			return INVALID_SEND_STATUS;
1037 		strlcpy(token, val, sizeof(token));
1038 		result = strtok_r(token, ";", &saveptr);
1039 		if (!result) {
1040 			send_resp(dut, conn, SIGMA_ERROR,
1041 				  "errorCode,VHT NSS not specified");
1042 			return STATUS_SENT;
1043 		}
1044 		nss = atoi(result);
1045 		result = strtok_r(NULL, ";", &saveptr);
1046 		if (result == NULL) {
1047 			send_resp(dut, conn, SIGMA_ERROR,
1048 				  "errorCode,VHTMCS not specified");
1049 			return STATUS_SENT;
1050 		}
1051 		result = strtok_r(result, "-", &saveptr);
1052 		result = strtok_r(NULL, "-", &saveptr);
1053 		if (!result) {
1054 			send_resp(dut, conn, SIGMA_ERROR,
1055 				  "errorCode,VHT MCS not specified");
1056 			return STATUS_SENT;
1057 		}
1058 		mcs = atoi(result);
1059 		if (dut->program == PROGRAM_HE) {
1060 			uint16_t mcsnssmap = 0;
1061 
1062 			get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs);
1063 			dut->he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap;
1064 			dut->he_ul_mcs = mcs;
1065 		} else {
1066 			set_vht_mcsmap_nss(dut, nss, mcs);
1067 		}
1068 	}
1069 
1070 	/* TODO: MPDU_MIN_START_SPACING */
1071 	/* TODO: RIFS_TEST */
1072 	/* TODO: SGI20 */
1073 
1074 	val = get_param(cmd, "STBC_TX");
1075 	if (val)
1076 		dut->ap_tx_stbc = atoi(val);
1077 
1078 	val = get_param(cmd, "WIDTH");
1079 	if (val) {
1080 		if (strcasecmp(val, "20") == 0)
1081 			dut->ap_chwidth = AP_20;
1082 		else if (strcasecmp(val, "40") == 0)
1083 			dut->ap_chwidth = AP_40;
1084 		else if (strcasecmp(val, "80") == 0)
1085 			dut->ap_chwidth = AP_80;
1086 		else if (strcasecmp(val, "160") == 0)
1087 			dut->ap_chwidth = AP_160;
1088 		else if (strcasecmp(val, "80plus80") == 0) {
1089 			dut->ap_80plus80 = 1;
1090 			dut->ap_chwidth = AP_80_80;
1091 		} else if (strcasecmp(val, "Auto") == 0)
1092 			dut->ap_chwidth = AP_AUTO;
1093 		else {
1094 			send_resp(dut, conn, SIGMA_INVALID,
1095 				  "errorCode,Unsupported WIDTH");
1096 			return STATUS_SENT;
1097 		}
1098 	}
1099 
1100 	/* TODO: WIDTH_SCAN */
1101 
1102 	val = get_param(cmd, "TDLSProhibit");
1103 	dut->ap_tdls_prohibit = val && strcasecmp(val, "Enabled") == 0;
1104 	val = get_param(cmd, "TDLSChswitchProhibit");
1105 	dut->ap_tdls_prohibit_chswitch =
1106 		val && strcasecmp(val, "Enabled") == 0;
1107 	val = get_param(cmd, "HS2");
1108 	if (val && wlan_tag == 1)
1109 		dut->ap_hs2 = atoi(val);
1110 	val = get_param(cmd, "P2P_CROSS_CONNECT");
1111 	if (val)
1112 		dut->ap_p2p_cross_connect = strcasecmp(val, "Enabled") == 0;
1113 
1114 	val = get_param(cmd, "FakePubKey");
1115 	dut->ap_fake_pkhash = val && atoi(val);
1116 
1117 	val = get_param(cmd, "vht_tkip");
1118 	dut->ap_allow_vht_tkip = val && strcasecmp(val, "Enable") == 0;
1119 	val = get_param(cmd, "vht_wep");
1120 	dut->ap_allow_vht_wep = val && strcasecmp(val, "Enable") == 0;
1121 
1122 	val = get_param(cmd, "Protect_mode");
1123 	dut->ap_disable_protection = val && strcasecmp(val, "Disable") == 0;
1124 
1125 	val = get_param(cmd, "DYN_BW_SGNL");
1126 	if (val) {
1127 		switch (get_driver_type(dut)) {
1128 		case DRIVER_OPENWRT:
1129 			switch (get_openwrt_driver_type()) {
1130 			case OPENWRT_DRIVER_ATHEROS:
1131 				ath_config_dyn_bw_sig(dut, ifname, val);
1132 				break;
1133 			default:
1134 				send_resp(dut, conn, SIGMA_ERROR,
1135 					  "errorCode,Unsupported DYN_BW_SGNL with OpenWrt driver");
1136 				return STATUS_SENT;
1137 			}
1138 			break;
1139 		case DRIVER_WCN:
1140 		case DRIVER_LINUX_WCN:
1141 			ath_config_dyn_bw_sig(dut, ifname, val);
1142 			break;
1143 		default:
1144 			sigma_dut_print(dut, DUT_MSG_ERROR,
1145 					"Unsupported DYN_BW_SGL with the current driver");
1146 			break;
1147 		}
1148 	}
1149 
1150 	val = get_param(cmd, "SGI80");
1151 	if (val) {
1152 		if (strcasecmp(val, "enable") == 0)
1153 			dut->ap_sgi80 = 1;
1154 		else if (strcasecmp(val, "disable") == 0)
1155 			dut->ap_sgi80 = 0;
1156 		else {
1157 			send_resp(dut, conn, SIGMA_INVALID,
1158 				  "errorCode,Unsupported SGI80");
1159 			return STATUS_SENT;
1160 		}
1161 	}
1162 
1163 	val = get_param(cmd, "LDPC");
1164 	if (val) {
1165 		if (strcasecmp(val, "enable") == 0)
1166 			dut->ap_ldpc = VALUE_ENABLED;
1167 		else if (strcasecmp(val, "disable") == 0)
1168 			dut->ap_ldpc = VALUE_DISABLED;
1169 		else {
1170 			send_resp(dut, conn, SIGMA_INVALID,
1171 				  "errorCode,Unsupported LDPC");
1172 			return STATUS_SENT;
1173 		}
1174 		switch (get_driver_type(dut)) {
1175 		case DRIVER_WCN:
1176 		case DRIVER_LINUX_WCN:
1177 			wcn_config_ap_ldpc(dut, ifname);
1178 			break;
1179 		default:
1180 			break;
1181 		}
1182 	}
1183 
1184 	val = get_param(cmd, "BW_SGNL");
1185 	if (val) {
1186 		/*
1187 		 * With dynamic bandwidth signaling enabled we should see
1188 		 * RTS if the threshold is met.
1189 		 */
1190 		if (strcasecmp(val, "enable") == 0) {
1191 			dut->ap_sig_rts = VALUE_ENABLED;
1192 		} else if (strcasecmp(val, "disable") == 0) {
1193 			dut->ap_sig_rts = VALUE_DISABLED;
1194 		} else {
1195 			send_resp(dut, conn, SIGMA_INVALID,
1196 				  "errorCode,Unsupported BW_SGNL");
1197 			return STATUS_SENT;
1198 		}
1199 	}
1200 
1201 	val = get_param(cmd, "RTS_FORCE");
1202 	if (val) {
1203 		switch (get_driver_type(dut)) {
1204 		case DRIVER_OPENWRT:
1205 			switch (get_openwrt_driver_type()) {
1206 			case OPENWRT_DRIVER_ATHEROS:
1207 				ath_config_rts_force(dut, ifname, val);
1208 				break;
1209 			default:
1210 				send_resp(dut, conn, SIGMA_ERROR,
1211 					  "errorCode,Unsupported RTS_FORCE with OpenWrt driver");
1212 				return STATUS_SENT;
1213 			}
1214 			break;
1215 		case DRIVER_MAC80211:
1216 			mac80211_config_rts_force(dut, ifname, val);
1217 			break;
1218 		default:
1219 			sigma_dut_print(dut, DUT_MSG_ERROR,
1220 					"Unsupported RTS_FORCE with the current driver");
1221 			break;
1222 		}
1223 	}
1224 
1225 	val = get_param(cmd, "Zero_crc");
1226 	if (val) {
1227 		switch (get_driver_type(dut)) {
1228 		case DRIVER_ATHEROS:
1229 			ath_set_zero_crc(dut, val);
1230 			break;
1231 		case DRIVER_OPENWRT:
1232 			switch (get_openwrt_driver_type()) {
1233 			case OPENWRT_DRIVER_ATHEROS:
1234 				ath_set_zero_crc(dut, val);
1235 				break;
1236 			default:
1237 				send_resp(dut, conn, SIGMA_ERROR,
1238 					  "errorCode,Unsupported zero_crc with the current driver");
1239 				return STATUS_SENT;
1240 			}
1241 			break;
1242 		default:
1243 			send_resp(dut, conn, SIGMA_ERROR,
1244 				  "errorCode,Unsupported zero_crc with the current driver");
1245 			return STATUS_SENT;
1246 		}
1247 	}
1248 
1249 	val = get_param(cmd, "TxBF");
1250 	if (val) {
1251 		dut->ap_txBF = strcasecmp(val, "enable") == 0;
1252 		dut->he_sounding = VALUE_DISABLED;
1253 		dut->he_set_sta_1x1 = VALUE_ENABLED;
1254 	}
1255 
1256 	val = get_param(cmd, "MU_TxBF");
1257 	if (val) {
1258 		if (strcasecmp(val, "enable") == 0) {
1259 			dut->ap_txBF = 1;
1260 			dut->ap_mu_txBF = 1;
1261 			dut->he_sounding = VALUE_DISABLED;
1262 		} else if (strcasecmp(val, "disable") == 0) {
1263 			dut->ap_txBF = 0;
1264 			dut->ap_mu_txBF = 0;
1265 		} else {
1266 			sigma_dut_print(dut, DUT_MSG_ERROR,
1267 					"Unsupported MU_TxBF");
1268 		}
1269 	}
1270 
1271 	/* UNSUPPORTED: tx_lgi_rate */
1272 
1273 	val = get_param(cmd, "wpsnfc");
1274 	if (val)
1275 		dut->ap_wpsnfc = atoi(val);
1276 
1277 	val = get_param(cmd, "GROUP_ID");
1278 	if (val) {
1279 		switch (get_driver_type(dut)) {
1280 		case DRIVER_OPENWRT:
1281 			switch (get_openwrt_driver_type()) {
1282 			case OPENWRT_DRIVER_ATHEROS:
1283 				ath_ap_set_group_id(dut, ifname, val);
1284 				break;
1285 			default:
1286 				send_resp(dut, conn, SIGMA_ERROR,
1287 					  "errorCode,Unsupported group_id with the current driver");
1288 				return STATUS_SENT;
1289 			}
1290 			break;
1291 		default:
1292 			send_resp(dut, conn, SIGMA_ERROR,
1293 				  "errorCode,Unsupported group_id with the current driver");
1294 			return STATUS_SENT;
1295 		}
1296 	}
1297 
1298 	val = get_param(cmd, "CTS_WIDTH");
1299 	if (val) {
1300 		switch (get_driver_type(dut)) {
1301 		case DRIVER_OPENWRT:
1302 			switch (get_openwrt_driver_type()) {
1303 			case OPENWRT_DRIVER_ATHEROS:
1304 				ath_set_cts_width(dut, ifname, val);
1305 				break;
1306 			default:
1307 				send_resp(dut, conn, SIGMA_ERROR,
1308 					  "errorCode,Unsupported cts_width with the current driver");
1309 				return STATUS_SENT;
1310 			}
1311 			break;
1312 		default:
1313 			send_resp(dut, conn, SIGMA_ERROR,
1314 				  "errorCode,Unsupported cts_width with the current driver");
1315 			return STATUS_SENT;
1316 		}
1317 	}
1318 
1319 	val = get_param(cmd, "MU_NDPA_FrameFormat");
1320 	if (val)
1321 		dut->ap_ndpa_frame = atoi(val);
1322 
1323 	val = get_param(cmd, "interworking");
1324 	if (val && strcmp(val, "1") == 0)
1325 		dut->ap_interworking = 1;
1326 
1327 	val = get_param(cmd, "GAS_CB_DELAY");
1328 	if (val)
1329 		dut->ap_gas_cb_delay = atoi(val);
1330 
1331 	val = get_param(cmd, "LCI");
1332 	if (val) {
1333 		if (strlen(val) > sizeof(dut->ap_val_lci) - 1)
1334 			return INVALID_SEND_STATUS;
1335 		dut->ap_lci = 1;
1336 		snprintf(dut->ap_val_lci, sizeof(dut->ap_val_lci), "%s", val);
1337 		ath_set_lci_config(dut, val, cmd);
1338 	}
1339 
1340 	val = get_param(cmd, "InfoZ");
1341 	if (val) {
1342 		if (strlen(val) > sizeof(dut->ap_infoz) - 1)
1343 			return INVALID_SEND_STATUS;
1344 		snprintf(dut->ap_infoz, sizeof(dut->ap_infoz), "%s", val);
1345 	}
1346 
1347 	val = get_param(cmd, "LocCivicAddr");
1348 	if (val) {
1349 		if (strlen(val) > sizeof(dut->ap_val_lcr) - 1)
1350 			return INVALID_SEND_STATUS;
1351 		dut->ap_lcr = 1;
1352 		snprintf(dut->ap_val_lcr, sizeof(dut->ap_val_lcr), "%s", val);
1353 		if (dut->ap_lci == 0)
1354 			ath_set_lci_config(dut, val, cmd);
1355 	}
1356 
1357 	val = get_param(cmd, "NeighAPBSSID");
1358 	if (val) {
1359 		if (dut->ap_neighap < 3) {
1360 			if (parse_mac_address(
1361 				    dut, val,
1362 				    dut->ap_val_neighap[dut->ap_neighap]) < 0) {
1363 				send_resp(dut, conn, SIGMA_INVALID,
1364 					  "Failed to parse MAC address");
1365 				return STATUS_SENT;
1366 			}
1367 			dut->ap_neighap++;
1368 			if (dut->ap_lci == 1)
1369 				dut->ap_scan = 1;
1370 		}
1371 	}
1372 
1373 	val = get_param(cmd, "OpChannel");
1374 	if (val) {
1375 		if (dut->ap_opchannel < 3) {
1376 			dut->ap_val_opchannel[dut->ap_opchannel] = atoi(val);
1377 			dut->ap_opchannel++;
1378 		}
1379 	}
1380 
1381 	val = get_param(cmd, "URI-FQDNdescriptor");
1382 	if (val) {
1383 		if (strcasecmp(val, "HELD") == 0) {
1384 			dut->ap_fqdn_held = 1;
1385 		} else if (strcasecmp(val, "SUPL") == 0) {
1386 			dut->ap_fqdn_supl = 1;
1387 		} else {
1388 			send_resp(dut, conn, SIGMA_INVALID,
1389 				  "errorCode,Unsupported URI-FQDNdescriptor");
1390 			return STATUS_SENT;
1391 		}
1392 	}
1393 
1394 	val = get_param(cmd, "Reg_Domain");
1395 	if (val) {
1396 		if (strcasecmp(val, "Local") == 0) {
1397 			dut->ap_reg_domain = REG_DOMAIN_LOCAL;
1398 		} else if (strcasecmp(val, "Global") == 0) {
1399 			dut->ap_reg_domain = REG_DOMAIN_GLOBAL;
1400 		} else {
1401 			send_resp(dut, conn, SIGMA_ERROR,
1402 				  "errorCode,Wrong value for Reg_Domain");
1403 			return STATUS_SENT;
1404 		}
1405 	}
1406 
1407 	val = get_param(cmd, "NAME");
1408 	if (val) {
1409 		if (strcasecmp(val, "ap1mbo") == 0)
1410 			dut->ap_name = 1;
1411 		else if (strcasecmp(val, "ap2mbo") == 0)
1412 			dut->ap_name = 2;
1413 		else
1414 			dut->ap_name = 0;
1415 	}
1416 
1417 	val = get_param(cmd, "FT_OA");
1418 	if (val) {
1419 		if (strcasecmp(val, "Enable") == 0) {
1420 			dut->ap_ft_oa = 1;
1421 		} else if (strcasecmp(val, "Disable") == 0) {
1422 			dut->ap_ft_oa = 0;
1423 		} else {
1424 			send_resp(dut, conn, SIGMA_ERROR,
1425 				  "errorCode,Wrong value for FT_OA");
1426 			return STATUS_SENT;
1427 		}
1428 	}
1429 
1430 	val = get_param(cmd, "FT_DS");
1431 	if (val) {
1432 		if (strcasecmp(val, "Enable") == 0) {
1433 			dut->ap_ft_ds = VALUE_ENABLED;
1434 		} else if (strcasecmp(val, "Disable") == 0) {
1435 			dut->ap_ft_ds = VALUE_DISABLED;
1436 		} else {
1437 			send_resp(dut, conn, SIGMA_ERROR,
1438 				  "errorCode,Unsupported value for FT_DS");
1439 			return STATUS_SENT_ERROR;
1440 		}
1441 	}
1442 
1443 	val = get_param(cmd, "Cellular_Cap_Pref");
1444 	if (val)
1445 		dut->ap_cell_cap_pref = atoi(val);
1446 
1447 	val = get_param(cmd, "DOMAIN");
1448 	if (val) {
1449 		if (strlen(val) >= sizeof(dut->ap_mobility_domain)) {
1450 			send_resp(dut, conn, SIGMA_ERROR,
1451 				  "errorCode,Too long DOMAIN");
1452 			return STATUS_SENT;
1453 		}
1454 		snprintf(dut->ap_mobility_domain,
1455 			 sizeof(dut->ap_mobility_domain), "%s", val);
1456 	}
1457 
1458 	val = get_param(cmd, "ft_bss_list");
1459 	if (val) {
1460 		char *mac_str;
1461 		int i;
1462 		char *saveptr;
1463 		char *mac_list_str;
1464 
1465 		mac_list_str = strdup(val);
1466 		if (!mac_list_str)
1467 			return INVALID_SEND_STATUS;
1468 		mac_str = strtok_r(mac_list_str, " ", &saveptr);
1469 		for (i = 0; mac_str && i < MAX_FT_BSS_LIST; i++) {
1470 			if (parse_mac_address(dut, mac_str,
1471 					      dut->ft_bss_mac_list[i]) < 0) {
1472 				sigma_dut_print(dut, DUT_MSG_ERROR,
1473 						"MAC Address not in proper format");
1474 				break;
1475 			}
1476 			dut->ft_bss_mac_cnt++;
1477 			mac_str = strtok_r(NULL, " ", &saveptr);
1478 		}
1479 		sigma_dut_print(dut, DUT_MSG_DEBUG,
1480 				"Storing the following FT BSS MAC List");
1481 		for (i = 0; i < dut->ft_bss_mac_cnt; i++) {
1482 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1483 					"MAC[%d] %02x:%02x:%02x:%02x:%02x:%02x",
1484 					i,
1485 					dut->ft_bss_mac_list[i][0],
1486 					dut->ft_bss_mac_list[i][1],
1487 					dut->ft_bss_mac_list[i][2],
1488 					dut->ft_bss_mac_list[i][3],
1489 					dut->ft_bss_mac_list[i][4],
1490 					dut->ft_bss_mac_list[i][5]);
1491 		}
1492 		free(mac_list_str);
1493 	}
1494 
1495 	val = get_param(cmd, "OCESupport");
1496 	if (val) {
1497 		if (strcasecmp(val, "enable") == 0) {
1498 			dut->ap_oce = VALUE_ENABLED;
1499 		} else if (strcasecmp(val, "disable") == 0) {
1500 			dut->ap_oce = VALUE_DISABLED;
1501 			dut->ap_filsdscv = VALUE_DISABLED;
1502 		} else {
1503 			send_resp(dut, conn, SIGMA_INVALID,
1504 				  "errorCode,Unsupported OCE");
1505 			return STATUS_SENT;
1506 		}
1507 	}
1508 
1509 	val = get_param(cmd, "FILSDscvInterval");
1510 	if (val)
1511 		dut->ap_fils_dscv_int = atoi(val);
1512 
1513 	val = get_param(cmd, "BroadcastSSID");
1514 	if (val) {
1515 		if (strcasecmp(val, "enable") == 0) {
1516 			dut->ap_broadcast_ssid = VALUE_ENABLED;
1517 		} else if (strcasecmp(val, "disable") == 0) {
1518 			dut->ap_broadcast_ssid = VALUE_DISABLED;
1519 		} else {
1520 			send_resp(dut, conn, SIGMA_INVALID,
1521 				  "errorCode,Unsupported hidden SSID");
1522 			return STATUS_SENT;
1523 		}
1524 	}
1525 
1526 	val = get_param(cmd, "FILSDscv");
1527 	if (val) {
1528 		if (strcasecmp(val, "enable") == 0) {
1529 			dut->ap_filsdscv = VALUE_ENABLED;
1530 		} else if (strcasecmp(val, "disable") == 0) {
1531 			dut->ap_filsdscv = VALUE_DISABLED;
1532 		} else {
1533 			send_resp(dut, conn, SIGMA_INVALID,
1534 				  "errorCode,Unsupported FILSDscv");
1535 			return STATUS_SENT;
1536 		}
1537 	}
1538 
1539 	val = get_param(cmd, "FILSHLP");
1540 	if (val) {
1541 		if (strcasecmp(val, "enable") == 0) {
1542 			dut->ap_filshlp = VALUE_ENABLED;
1543 		} else if (strcasecmp(val, "disable") == 0) {
1544 			dut->ap_filshlp = VALUE_DISABLED;
1545 		} else {
1546 			send_resp(dut, conn, SIGMA_INVALID,
1547 				  "errorCode,Unsupported FILSHLP");
1548 			return STATUS_SENT;
1549 		}
1550 	}
1551 
1552 	val = get_param(cmd, "NAIRealm");
1553 	if (val) {
1554 		dut->ap_nairealm_int = 1;
1555 		if (strlen(val) > sizeof(dut->ap_nairealm) - 1)
1556 			return INVALID_SEND_STATUS;
1557 		snprintf(dut->ap_nairealm, sizeof(dut->ap_nairealm), "%s", val);
1558 	}
1559 
1560 	val = get_param(cmd, "DeauthDisassocTx");
1561 	if (val) {
1562 		if (strcasecmp(val, "disable") == 0) {
1563 			deauth_disassoc(dut, ifname, val);
1564 		} else {
1565 			send_resp(dut, conn, SIGMA_INVALID,
1566 				  "errorCode,Unsupported DeauthDisassocTx");
1567 			return STATUS_SENT;
1568 		}
1569 	}
1570 
1571 	val = get_param(cmd, "RNR");
1572 	if (val) {
1573 		if (strcasecmp(val, "enable") == 0) {
1574 			dut->ap_rnr = VALUE_ENABLED;
1575 		} else if (strcasecmp(val, "disable") == 0) {
1576 			dut->ap_rnr = VALUE_DISABLED;
1577 		} else {
1578 			send_resp(dut, conn, SIGMA_INVALID,
1579 				  "errorCode,Unsupported RNR");
1580 			return STATUS_SENT;
1581 		}
1582 	}
1583 
1584 	val = get_param(cmd, "BLEChannelUtil");
1585 	if (val)
1586 		dut->ap_blechanutil = atoi(val);
1587 
1588 	val = get_param(cmd, "BLEAvailAdminCap");
1589 	if (val)
1590 		dut->ap_ble_admit_cap = atoi(val);
1591 
1592 	val = get_param(cmd, "DataPPDUDuration");
1593 	if (val)
1594 		dut->ap_datappdudura = atoi(val);
1595 
1596 	val = get_param(cmd, "AirTimeFract");
1597 	if (val)
1598 		dut->ap_airtimefract = atoi(val);
1599 
1600 	val = get_param(cmd, "dhcpServIPADDR");
1601 	if (val) {
1602 		if (strlen(val) > sizeof(dut->ap_dhcpserv_ipaddr) - 1)
1603 			return INVALID_SEND_STATUS;
1604 		snprintf(dut->ap_dhcpserv_ipaddr,
1605 			 sizeof(dut->ap_dhcpserv_ipaddr), "%s", val);
1606 		dut->ap_dhcp_stop = 1;
1607 	}
1608 
1609 	val = get_param(cmd, "ESP_IE");
1610 	if (val) {
1611 		if (strcasecmp(val, "enable") == 0) {
1612 			dut->ap_esp = VALUE_ENABLED;
1613 		} else if (strcasecmp(val, "disable") == 0) {
1614 			dut->ap_esp = VALUE_DISABLED;
1615 		} else {
1616 			send_resp(dut, conn, SIGMA_INVALID,
1617 				  "errorCode,Unsupported ESP_IE");
1618 			return STATUS_SENT;
1619 		}
1620 	}
1621 
1622 	val = get_param(cmd, "BAWinSize");
1623 	if (val)
1624 		dut->ap_bawinsize = atoi(val);
1625 
1626 	val = get_param(cmd, "BLEStaCount");
1627 	if (val)
1628 		dut->ap_blestacnt = atoi(val);
1629 
1630 	val = get_param(cmd, "PPDUTxType");
1631 	if (val) {
1632 		if (strcasecmp(val, "MU") == 0) {
1633 			dut->ap_he_ppdu = PPDU_MU;
1634 		} else if (strcasecmp(val, "HE-SU") == 0) {
1635 			/* Do nothing */
1636 		} else if (strcasecmp(val, "SU") == 0) {
1637 			/* Do nothing */
1638 		} else if (strcasecmp(val, "legacy") == 0) {
1639 			/* Do nothing */
1640 		} else if (strcasecmp(val, "ER") == 0) {
1641 			/* Do nothing */
1642 		} else if (strcasecmp(val, "TB") == 0) {
1643 			/* Do nothing */
1644 		} else {
1645 			send_resp(dut, conn, SIGMA_ERROR,
1646 				  "errorCode,Unsupported PPDUTxType");
1647 			return STATUS_SENT_ERROR;
1648 		}
1649 	}
1650 
1651 	val = get_param(cmd, "WscIEFragment");
1652 	if (val && strcasecmp(val, "enable") == 0) {
1653 		sigma_dut_print(dut, DUT_MSG_DEBUG,
1654 				"Enable WSC IE fragmentation");
1655 		dut->wsc_fragment = 1;
1656 	}
1657 
1658 	val = get_param(cmd, "WpsVersion");
1659 	if (val)
1660 		dut->wps_forced_version = get_wps_forced_version(dut, val);
1661 
1662 	val = get_param(cmd, "WscEAPFragment");
1663 	if (val && strcasecmp(val, "enable") == 0)
1664 		dut->eap_fragment = 1;
1665 
1666 	val = get_param(cmd, "MSDUSize");
1667 	if (val) {
1668 		int mtu;
1669 
1670 		dut->amsdu_size = atoi(val);
1671 		if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
1672 		    dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
1673 			sigma_dut_print(dut, DUT_MSG_ERROR,
1674 					"MSDUSize %d is above max %d or below min %d",
1675 					dut->amsdu_size,
1676 					IEEE80211_MAX_DATA_LEN_DMG,
1677 					IEEE80211_SNAP_LEN_DMG);
1678 			dut->amsdu_size = 0;
1679 			return ERROR_SEND_STATUS;
1680 		}
1681 
1682 		mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
1683 		sigma_dut_print(dut, DUT_MSG_DEBUG,
1684 				"Setting amsdu_size to %d", mtu);
1685 		snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
1686 			 get_station_ifname(dut), mtu);
1687 
1688 		if (system(buf) != 0) {
1689 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
1690 					buf);
1691 			return ERROR_SEND_STATUS;
1692 		}
1693 	}
1694 
1695 	val = get_param(cmd, "BAckRcvBuf");
1696 	if (val) {
1697 		dut->back_rcv_buf = atoi(val);
1698 		if (dut->back_rcv_buf == 0) {
1699 			sigma_dut_print(dut, DUT_MSG_ERROR,
1700 					"Failed to convert %s or value is 0",
1701 					val);
1702 			return ERROR_SEND_STATUS;
1703 		}
1704 
1705 		sigma_dut_print(dut, DUT_MSG_DEBUG,
1706 				"Setting BAckRcvBuf to %s", val);
1707 	}
1708 
1709 	val = get_param(cmd, "ExtSchIE");
1710 	if (val && !strcasecmp(val, "Enable")) {
1711 		int num_allocs = MAX_ESE_ALLOCS;
1712 
1713 		if (sta_extract_60g_ese(dut, cmd, dut->ap_ese_allocs,
1714 					&num_allocs)) {
1715 			send_resp(dut, conn, SIGMA_INVALID,
1716 				  "errorCode,Invalid ExtSchIE");
1717 			return STATUS_SENT;
1718 		}
1719 		dut->ap_num_ese_allocs = num_allocs;
1720 	}
1721 
1722 	if (is_60g_sigma_dut(dut)) {
1723 		unsigned int abft_len = 1; /* default is one slot */
1724 
1725 		val = get_param(cmd, "ABFTLRang");
1726 		if (val) {
1727 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1728 					"ABFTLRang parameter %s", val);
1729 			if (strcasecmp(val, "Gt1") == 0)
1730 				abft_len = 2; /* 2 slots in this case */
1731 		}
1732 
1733 		if (sta_set_60g_abft_len(dut, conn, abft_len)) {
1734 			send_resp(dut, conn, SIGMA_ERROR,
1735 				  "ErrorCode,Can't set ABFT length");
1736 			return STATUS_SENT;
1737 		}
1738 	}
1739 
1740 	val = get_param(cmd, "OFDMA");
1741 	if (val) {
1742 		if (strcasecmp(val, "UL") == 0) {
1743 			dut->ap_he_ulofdma = VALUE_ENABLED;
1744 		} else if (strcasecmp(val, "DL") == 0) {
1745 			dut->ap_he_dlofdma = VALUE_ENABLED;
1746 		} else if (strcasecmp(val, "DL-20and80") == 0) {
1747 			dut->ap_he_dlofdma = VALUE_ENABLED;
1748 		} else {
1749 			send_resp(dut, conn, SIGMA_ERROR,
1750 				  "errorCode,Unsupported OFDMA value");
1751 			return STATUS_SENT_ERROR;
1752 		}
1753 	}
1754 
1755 	val = get_param(cmd, "NumSoundDim");
1756 	if (val)
1757 		dut->ap_numsounddim = atoi(val);
1758 
1759 	val = get_param(cmd, "BCC");
1760 	if (val) {
1761 		if (strcasecmp(val, "enable") == 0) {
1762 			dut->ap_bcc = VALUE_ENABLED;
1763 			dut->ap_ldpc = VALUE_DISABLED;
1764 		} else if (strcasecmp(val, "disable") == 0) {
1765 			dut->ap_ldpc = VALUE_ENABLED;
1766 			dut->ap_bcc = VALUE_DISABLED;
1767 		} else {
1768 			send_resp(dut, conn, SIGMA_ERROR,
1769 				  "errorCode,Unsupported BCC value");
1770 			return STATUS_SENT_ERROR;
1771 		}
1772 		switch (get_driver_type(dut)) {
1773 		case DRIVER_WCN:
1774 		case DRIVER_LINUX_WCN:
1775 			wcn_config_ap_ldpc(dut, ifname);
1776 			break;
1777 		default:
1778 			break;
1779 		}
1780 	}
1781 
1782 	val = get_param(cmd, "FrgmntSupport");
1783 	if (val) {
1784 		if (strcasecmp(val, "enable") == 0) {
1785 			dut->ap_he_frag = VALUE_ENABLED;
1786 		} else if (strcasecmp(val, "disable") == 0) {
1787 			dut->ap_he_frag = VALUE_DISABLED;
1788 		} else {
1789 			send_resp(dut, conn, SIGMA_ERROR,
1790 				  "errorCode,Unsupported FrgmntSupport value");
1791 			return STATUS_SENT_ERROR;
1792 		}
1793 	}
1794 
1795 	val = get_param(cmd, "ADDBAReq_BufSize");
1796 	if (val) {
1797 		if (strcasecmp(val, "le64") == 0) {
1798 			dut->ap_ba_bufsize = BA_BUFSIZE_64;
1799 		} else if (strcasecmp(val, "gt64") == 0) {
1800 			dut->ap_ba_bufsize = BA_BUFSIZE_256;
1801 		} else {
1802 			send_resp(dut, conn, SIGMA_ERROR,
1803 				  "errorCode,Unsupported ADDBAReq Buffer Size");
1804 			return STATUS_SENT_ERROR;
1805 		}
1806 	}
1807 
1808 	val = get_param(cmd, "ADDBAResp_BufSize");
1809 	if (val) {
1810 		if (strcasecmp(val, "gt64") == 0) {
1811 			dut->ap_ba_bufsize = BA_BUFSIZE_256;
1812 		} else {
1813 			send_resp(dut, conn, SIGMA_ERROR,
1814 				  "errorCode,Unsupported ADDBAResp Buffer Size");
1815 			return STATUS_SENT_ERROR;
1816 		}
1817 	}
1818 
1819 	val = get_param(cmd, "MU_EDCA");
1820 	if (val) {
1821 		if (strcasecmp(val, "override") == 0) {
1822 			dut->ap_mu_edca = VALUE_ENABLED;
1823 		} else if (strcasecmp(val, "disable") == 0) {
1824 			dut->ap_mu_edca = VALUE_DISABLED;
1825 		} else {
1826 			send_resp(dut, conn, SIGMA_ERROR,
1827 				  "errorCode,Unsupported mu_edca param value");
1828 			return STATUS_SENT_ERROR;
1829 		}
1830 	}
1831 
1832 	val = get_param(cmd, "MIMO");
1833 	if (val) {
1834 		if (strcasecmp(val, "DL") == 0) {
1835 			dut->ap_he_mimo = MIMO_DL;
1836 			dut->he_sounding = VALUE_DISABLED;
1837 		} else if (strcasecmp(val, "UL") == 0) {
1838 			dut->ap_he_mimo = MIMO_UL;
1839 		} else {
1840 			send_resp(dut, conn, SIGMA_ERROR,
1841 				  "errorCode,Unsupported mimo param value");
1842 			return STATUS_SENT_ERROR;
1843 		}
1844 	}
1845 
1846 	val = get_param(cmd, "HE_TXOPDurRTSThr");
1847 	if (val) {
1848 		if (strcasecmp(val, "enable") == 0) {
1849 			dut->ap_he_rtsthrshld = VALUE_ENABLED;
1850 		} else if (strcasecmp(val, "disable") == 0) {
1851 			dut->ap_he_rtsthrshld = VALUE_DISABLED;
1852 		} else {
1853 			send_resp(dut, conn, SIGMA_ERROR,
1854 				  "errorCode,Unsupported HE_TXOPDurRTSThr value");
1855 			return STATUS_SENT_ERROR;
1856 		}
1857 	}
1858 
1859 	val = get_param(cmd, "MBSSID");
1860 	if (val) {
1861 		if (strcasecmp(val, "enable") == 0) {
1862 			dut->ap_mbssid = VALUE_ENABLED;
1863 		} else if (strcasecmp(val, "disable") == 0) {
1864 			dut->ap_mbssid = VALUE_DISABLED;
1865 		} else {
1866 			send_resp(dut, conn, SIGMA_ERROR,
1867 				  "errorCode,Unsupported MBSSID Value");
1868 			return STATUS_SENT_ERROR;
1869 		}
1870 	}
1871 
1872 	val = get_param(cmd, "TWT_RespSupport");
1873 	if (val) {
1874 		if (strcasecmp(val, "enable") == 0) {
1875 			dut->ap_twtresp = VALUE_ENABLED;
1876 		} else if (strcasecmp(val, "disable") == 0) {
1877 			dut->ap_twtresp = VALUE_DISABLED;
1878 		} else {
1879 			send_resp(dut, conn, SIGMA_ERROR,
1880 				  "errorCode,Unsupported TWT_RespSupport value");
1881 			return STATUS_SENT_ERROR;
1882 		}
1883 	}
1884 
1885 	val = get_param(cmd, "MinMPDUStartSpacing");
1886 	if (val)
1887 		dut->he_mmss = atoi(val);
1888 
1889 	val = get_param(cmd, "SRCtrl_SRValue15Allowed");
1890 	if (val)
1891 		dut->he_srctrl_allow = atoi(val);
1892 
1893 	val = get_param(cmd, "ocvc");
1894 	if (val)
1895 		dut->ap_ocvc = atoi(val);
1896 
1897 	return SUCCESS_SEND_STATUS;
1898 }
1899 
1900 
1901 static void ath_inject_frame(struct sigma_dut *dut, const char *ifname, int tid)
1902 {
1903 	char buf[256];
1904 	int tid_to_dscp[] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
1905 
1906 	if (tid < 0 ||
1907 	    tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
1908 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
1909 		return;
1910 	}
1911 
1912 	snprintf(buf, sizeof(buf),
1913 		 "wlanconfig %s list sta | grep : | cut -b 1-17 > %s",
1914 		 ifname, VI_QOS_TMP_FILE);
1915 	if (system(buf) != 0)
1916 		return;
1917 
1918 	snprintf(buf, sizeof(buf),
1919 		 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
1920 		 ifname, VI_QOS_TMP_FILE);
1921 	if (system(buf) != 0)
1922 		sigma_dut_print(dut, DUT_MSG_ERROR, "Retrieve HWaddr failed");
1923 
1924 	snprintf(buf, sizeof(buf), "sed -n '3,$p' %s >> %s",
1925 		 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
1926 	if (system(buf) != 0) {
1927 		sigma_dut_print(dut, DUT_MSG_ERROR,
1928 				"Output redirection to VI_QOS_TMP_FILE failed");
1929 	}
1930 
1931 	snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
1932 		 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
1933 	if (system(buf) != 0) {
1934 		sigma_dut_print(dut, DUT_MSG_ERROR,
1935 				"Append TID to VI_QOS_FILE failed ");
1936 	}
1937 
1938 	snprintf(buf, sizeof(buf), "ethinject %s %s", ifname, VI_QOS_FILE);
1939 	if (system(buf) != 0)
1940 		sigma_dut_print(dut, DUT_MSG_ERROR, "Ethinject frame failed");
1941 }
1942 
1943 
1944 static int ath_ap_send_addba_req(struct sigma_dut *dut, struct sigma_conn *conn,
1945 				 struct sigma_cmd *cmd)
1946 {
1947 	const char *val;
1948 	const char *ifname;
1949 	char buf[256];
1950 	int tid = 0;
1951 
1952 	ifname = get_main_ifname(dut);
1953 	val = get_param(cmd, "TID");
1954 	if (val) {
1955 		tid = atoi(val);
1956 		if (tid)
1957 			ath_inject_frame(dut, ifname, tid);
1958 	}
1959 
1960 	/* NOTE: This is the command sequence on Peregrine for ADDBA */
1961 	run_iwpriv(dut, ifname, "setaddbaoper 1");
1962 
1963 	snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4",
1964 		 ifname, tid);
1965 	if (system(buf) != 0) {
1966 		sigma_dut_print(dut, DUT_MSG_ERROR,
1967 				"wifitool senddelba failed");
1968 	}
1969 
1970 	snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64",
1971 		 ifname, tid);
1972 	if (system(buf) != 0) {
1973 		sigma_dut_print(dut, DUT_MSG_ERROR,
1974 				"wifitool sendaddba failed");
1975 	}
1976 
1977 	return 1;
1978 }
1979 
1980 
1981 static int ath10k_debug_enable_addba_req(struct sigma_dut *dut, int tid,
1982 					 const char *sta_mac,
1983 					 const char *dir_path)
1984 {
1985 	DIR *dir;
1986 	struct dirent *entry;
1987 	char buf[128], path[128];
1988 	int ret = 0, res;
1989 
1990 	dir = opendir(dir_path);
1991 	if (!dir)
1992 		return 0;
1993 
1994 	while ((entry = readdir(dir))) {
1995 		ret = 1;
1996 
1997 		if (strcmp(entry->d_name, ".") == 0 ||
1998 		    strcmp(entry->d_name, "..") == 0)
1999 			continue;
2000 
2001 		res = snprintf(path, sizeof(path) - 1, "%s/%s",
2002 			       dir_path, entry->d_name);
2003 		if (res < 0 || res >= sizeof(path))
2004 			continue;
2005 
2006 		if (strcmp(entry->d_name, sta_mac) == 0) {
2007 			res = snprintf(buf, sizeof(buf),
2008 				       "echo 1 > %s/aggr_mode", path);
2009 			if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
2010 				sigma_dut_print(dut, DUT_MSG_ERROR,
2011 						"Failed to set aggr mode for ath10k");
2012 			}
2013 
2014 			res = snprintf(buf, sizeof(buf),
2015 				       "echo %d 32 > %s/addba", tid, path);
2016 			if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
2017 				sigma_dut_print(dut, DUT_MSG_ERROR,
2018 						"Failed to set addbareq for ath10k");
2019 			}
2020 
2021 			break;
2022 		}
2023 
2024 		/* Recursively search subdirectories */
2025 		ath10k_debug_enable_addba_req(dut, tid, sta_mac, path);
2026 	}
2027 
2028 	closedir(dir);
2029 
2030 	return ret;
2031 }
2032 
2033 
2034 static int ath10k_ap_send_addba_req(struct sigma_dut *dut,
2035 				    struct sigma_cmd *cmd)
2036 {
2037 	const char *val;
2038 	int tid = 0;
2039 
2040 	val = get_param(cmd, "TID");
2041 	if (val)
2042 		tid = atoi(val);
2043 
2044 	val = get_param(cmd, "sta_mac_address");
2045 	if (!val) {
2046 		sigma_dut_print(dut, DUT_MSG_ERROR,
2047 				"Failed to parse station MAC address");
2048 		return 0;
2049 	}
2050 
2051 	return ath10k_debug_enable_addba_req(dut, tid, val,
2052 					     "/sys/kernel/debug/ieee80211");
2053 }
2054 
2055 
2056 static enum sigma_cmd_result cmd_ap_send_addba_req(struct sigma_dut *dut,
2057 						   struct sigma_conn *conn,
2058 						   struct sigma_cmd *cmd)
2059 {
2060 	/* const char *name = get_param(cmd, "NAME"); */
2061 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
2062 	struct stat s;
2063 
2064 	switch (get_driver_type(dut)) {
2065 	case DRIVER_ATHEROS:
2066 		return ath_ap_send_addba_req(dut, conn, cmd);
2067 #ifdef __linux__
2068 	case DRIVER_WIL6210:
2069 		return send_addba_60g(dut, conn, cmd, "sta_mac_address");
2070 #endif /* __linux__ */
2071 	case DRIVER_OPENWRT:
2072 		switch (get_openwrt_driver_type()) {
2073 		case OPENWRT_DRIVER_ATHEROS:
2074 			return ath_ap_send_addba_req(dut, conn, cmd);
2075 		default:
2076 			send_resp(dut, conn, SIGMA_ERROR,
2077 				  "errorCode,ap_send_addba_req not supported with this driver");
2078 			return 0;
2079 		}
2080 	case DRIVER_WCN:
2081 	case DRIVER_LINUX_WCN:
2082 		/* AP automatically sends ADDBA request after association. */
2083 		sigma_dut_print(dut, DUT_MSG_INFO,
2084 				"ap_send_addba_req command ignored");
2085 		return 1;
2086 	case DRIVER_MAC80211:
2087 		if (stat("/sys/module/ath10k_core", &s) == 0)
2088 			return ath10k_ap_send_addba_req(dut, cmd);
2089 		/* fall through */
2090 	default:
2091 		send_resp(dut, conn, SIGMA_ERROR,
2092 			  "errorCode,ap_send_addba_req not supported with this driver");
2093 		return 0;
2094 	}
2095 }
2096 
2097 
2098 static enum sigma_cmd_result cmd_ap_set_security(struct sigma_dut *dut,
2099 						 struct sigma_conn *conn,
2100 						 struct sigma_cmd *cmd)
2101 {
2102 	/* const char *name = get_param(cmd, "NAME"); */
2103 	const char *val;
2104 	unsigned int wlan_tag = 1;
2105 	const char *security;
2106 
2107 	val = get_param(cmd, "WLAN_TAG");
2108 	if (val)
2109 		wlan_tag = atoi(val);
2110 
2111 	security = get_param(cmd, "Security");
2112 
2113 	if (wlan_tag > 1) {
2114 		val = get_param(cmd, "KEYMGNT");
2115 		if (!val)
2116 			val = get_param(cmd, "KeyMgmtType");
2117 		if (val) {
2118 			if (strcasecmp(val, "NONE") == 0) {
2119 				dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OPEN;
2120 			} else if (strcasecmp(val, "OSEN") == 0 &&
2121 				   wlan_tag == 2) {
2122 				/*
2123 				 * OSEN only supported on WLAN_TAG = 2 for now
2124 				 */
2125 				dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OSEN;
2126 			} else if (strcasecmp(val, "WPA2-PSK") == 0 ||
2127 				   (security &&
2128 				    strcasecmp(security, "PSK") == 0 &&
2129 				    strcasecmp(val, "WPA2") == 0)) {
2130 				dut->ap_tag_key_mgmt[wlan_tag - 2] =
2131 					AP2_WPA2_PSK;
2132 			} else if (strcasecmp(val, "OWE") == 0 &&
2133 				   wlan_tag == 2) {
2134 				dut->ap_tag_key_mgmt[wlan_tag - 2] =
2135 					AP2_WPA2_OWE;
2136 			} else {
2137 				send_resp(dut, conn, SIGMA_INVALID,
2138 					  "errorCode,Unsupported KEYMGNT");
2139 				return 0;
2140 			}
2141 			return 1;
2142 		}
2143 	}
2144 
2145 	val = get_param(cmd, "KEYMGNT");
2146 	if (!val)
2147 		val = get_param(cmd,"KeyMgmtType");
2148 	if (val) {
2149 		if (strcasecmp(val, "WPA2-PSK") == 0 ||
2150 		    (security && strcasecmp(security, "PSK") == 0 &&
2151 		     strcasecmp(val, "WPA2") == 0)) {
2152 			dut->ap_key_mgmt = AP_WPA2_PSK;
2153 			dut->ap_cipher = AP_CCMP;
2154 		} else if (strcasecmp(val, "WPA2-EAP") == 0 ||
2155 			   strcasecmp(val, "WPA2-Ent") == 0) {
2156 			dut->ap_key_mgmt = AP_WPA2_EAP;
2157 			dut->ap_cipher = AP_CCMP;
2158 		} else if (strcasecmp(val, "SuiteB") == 0) {
2159 			dut->ap_key_mgmt = AP_SUITEB;
2160 			dut->ap_cipher = AP_GCMP_256;
2161 			dut->ap_pmf = AP_PMF_REQUIRED;
2162 		} else if (strcasecmp(val, "WPA-PSK") == 0) {
2163 			dut->ap_key_mgmt = AP_WPA_PSK;
2164 			dut->ap_cipher = AP_TKIP;
2165 		} else if (strcasecmp(val, "WPA-EAP") == 0 ||
2166 			   strcasecmp(val, "WPA-Ent") == 0) {
2167 			dut->ap_key_mgmt = AP_WPA_EAP;
2168 			dut->ap_cipher = AP_TKIP;
2169 		} else if (strcasecmp(val, "WPA2-Mixed") == 0) {
2170 			dut->ap_key_mgmt = AP_WPA2_EAP_MIXED;
2171 			dut->ap_cipher = AP_CCMP_TKIP;
2172 		} else if (strcasecmp(val, "WPA2-PSK-Mixed") == 0) {
2173 			dut->ap_key_mgmt = AP_WPA2_PSK_MIXED;
2174 			dut->ap_cipher = AP_CCMP_TKIP;
2175 		} else if (strcasecmp(val, "WPA2-SAE") == 0 ||
2176 			   strcasecmp(val, "SAE") == 0) {
2177 			dut->ap_key_mgmt = AP_WPA2_SAE;
2178 			dut->ap_cipher = AP_CCMP;
2179 			dut->ap_pmf = AP_PMF_REQUIRED;
2180 		} else if (strcasecmp(val, "WPA2-PSK-SAE") == 0) {
2181 			dut->ap_key_mgmt = AP_WPA2_PSK_SAE;
2182 			dut->ap_cipher = AP_CCMP;
2183 			dut->ap_pmf = AP_PMF_OPTIONAL;
2184 		} else if (strcasecmp(val, "OWE") == 0) {
2185 			dut->ap_key_mgmt = AP_WPA2_OWE;
2186 			dut->ap_cipher = AP_CCMP;
2187 			dut->ap_pmf = AP_PMF_REQUIRED;
2188 		} else if (strcasecmp(val, "WPA2-ENT-OSEN") == 0) {
2189 			dut->ap_key_mgmt = AP_WPA2_EAP_OSEN;
2190 			dut->ap_cipher = AP_CCMP;
2191 			dut->ap_pmf = AP_PMF_OPTIONAL;
2192 		} else if (strcasecmp(val, "OSEN") == 0) {
2193 			dut->ap_key_mgmt = AP_OSEN;
2194 			dut->ap_cipher = AP_CCMP;
2195 		} else if (strcasecmp(val, "FT-EAP") == 0) {
2196 			dut->ap_key_mgmt = AP_WPA2_FT_EAP;
2197 			dut->ap_cipher = AP_CCMP;
2198 			dut->ap_pmf = AP_PMF_OPTIONAL;
2199 		} else if (strcasecmp(val, "FT-PSK") == 0) {
2200 			dut->ap_key_mgmt = AP_WPA2_FT_PSK;
2201 			dut->ap_cipher = AP_CCMP;
2202 			dut->ap_pmf = AP_PMF_OPTIONAL;
2203 		} else if (strcasecmp(val, "WPA2-ENT-256") == 0) {
2204 			dut->ap_key_mgmt = AP_WPA2_EAP_SHA256;
2205 			dut->ap_cipher = AP_CCMP;
2206 			dut->ap_pmf = AP_PMF_OPTIONAL;
2207 		} else if (strcasecmp(val, "WPA2-PSK-256") == 0) {
2208 			dut->ap_key_mgmt = AP_WPA2_PSK_SHA256;
2209 			dut->ap_cipher = AP_CCMP;
2210 			dut->ap_pmf = AP_PMF_OPTIONAL;
2211 		} else if (strcasecmp(val, "WPA2-ENT-FT-EAP") == 0) {
2212 			dut->ap_key_mgmt = AP_WPA2_ENT_FT_EAP;
2213 			dut->ap_cipher = AP_CCMP;
2214 			dut->ap_pmf = AP_PMF_OPTIONAL;
2215 		} else if (strcasecmp(val, "NONE") == 0) {
2216 			dut->ap_key_mgmt = AP_OPEN;
2217 			dut->ap_cipher = AP_PLAIN;
2218 		} else {
2219 			send_resp(dut, conn, SIGMA_INVALID,
2220 				  "errorCode,Unsupported KEYMGNT");
2221 			return 0;
2222 		}
2223 	}
2224 
2225 	val = get_param(cmd, "ECGroupID");
2226 	if (val) {
2227 		free(dut->ap_sae_groups);
2228 		dut->ap_sae_groups = strdup(val);
2229 	}
2230 
2231 	val = get_param(cmd, "AntiCloggingThreshold");
2232 	if (val)
2233 		dut->sae_anti_clogging_threshold = atoi(val);
2234 
2235 	val = get_param(cmd, "Reflection");
2236 	if (val)
2237 		dut->sae_reflection = strcasecmp(val, "SAE") == 0;
2238 
2239 	val = get_param(cmd, "InvalidSAEElement");
2240 	if (val) {
2241 		free(dut->sae_commit_override);
2242 		dut->sae_commit_override = strdup(val);
2243 	}
2244 
2245 	val = get_param(cmd, "SAEPasswords");
2246 	if (val) {
2247 		free(dut->ap_sae_passwords);
2248 		dut->ap_sae_passwords = strdup(val);
2249 	}
2250 
2251 	val = get_param(cmd, "SAE_Confirm_Immediate");
2252 	if (val)
2253 		dut->sae_confirm_immediate = get_enable_disable(val);
2254 
2255 	val = get_param(cmd, "sae_pwe");
2256 	if (val) {
2257 		if (strcasecmp(val, "h2e") == 0) {
2258 			dut->sae_pwe = SAE_PWE_H2E;
2259 		} else if (strcasecmp(val, "loop") == 0 ||
2260 			   strcasecmp(val, "looping") == 0) {
2261 			dut->sae_pwe = SAE_PWE_LOOP;
2262 		} else {
2263 			send_resp(dut, conn, SIGMA_ERROR,
2264 				  "errorCode,Unsupported sae_pwe value");
2265 			return STATUS_SENT_ERROR;
2266 		}
2267 	}
2268 
2269 	val = get_param(cmd, "RSNXE_Content");
2270 	if (val) {
2271 		if (strncasecmp(val, "EapolM3:", 8) != 0) {
2272 			send_resp(dut, conn, SIGMA_ERROR,
2273 				  "errorCode,Unsupported RSNXE_Content value");
2274 			return STATUS_SENT_ERROR;
2275 		}
2276 		val += 8;
2277 		free(dut->rsnxe_override_eapol);
2278 		dut->rsnxe_override_eapol = strdup(val);
2279 	}
2280 
2281 	val = get_param(cmd, "ENCRYPT");
2282 	if (!val)
2283 		val = get_param(cmd, "EncpType");
2284 	if (val) {
2285 		if (strcasecmp(val, "WEP") == 0) {
2286 			dut->ap_cipher = AP_WEP;
2287 		} else if (strcasecmp(val, "TKIP") == 0) {
2288 			dut->ap_cipher = AP_TKIP;
2289 		} else if (strcasecmp(val, "AES") == 0 ||
2290 			   strcasecmp(val, "AES-CCMP") == 0) {
2291 			dut->ap_cipher = AP_CCMP;
2292 		} else if (strcasecmp(val, "AES-GCMP") == 0) {
2293 			dut->ap_cipher = AP_GCMP_128;
2294 		} else {
2295 			send_resp(dut, conn, SIGMA_INVALID,
2296 				  "errorCode,Unsupported ENCRYPT");
2297 			return 0;
2298 		}
2299 	}
2300 
2301 	val = get_param(cmd, "PairwiseCipher");
2302 	if (val) {
2303 		if (strcasecmp(val, "AES-GCMP-256") == 0) {
2304 			dut->ap_cipher = AP_GCMP_256;
2305 		} else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2306 			dut->ap_cipher = AP_CCMP_256;
2307 		} else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2308 			dut->ap_cipher = AP_GCMP_128;
2309 		} else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2310 			dut->ap_cipher = AP_CCMP;
2311 		} else if (strcasecmp(val, "AES-CCMP-128 AES-GCMP-256") == 0 ||
2312 			   strcasecmp(val, "AES-GCMP-256 AES-CCMP-128") == 0) {
2313 			dut->ap_cipher = AP_CCMP_128_GCMP_256;
2314 		} else {
2315 			send_resp(dut, conn, SIGMA_INVALID,
2316 				  "errorCode,Unsupported PairwiseCipher");
2317 			return 0;
2318 		}
2319 	}
2320 
2321 	val = get_param(cmd, "GroupCipher");
2322 	if (val) {
2323 		if (strcasecmp(val, "AES-GCMP-256") == 0) {
2324 			dut->ap_group_cipher = AP_GCMP_256;
2325 		} else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2326 			dut->ap_group_cipher = AP_CCMP_256;
2327 		} else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2328 			dut->ap_group_cipher = AP_GCMP_128;
2329 		} else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2330 			dut->ap_group_cipher = AP_CCMP;
2331 		} else {
2332 			send_resp(dut, conn, SIGMA_INVALID,
2333 				  "errorCode,Unsupported GroupCipher");
2334 			return 0;
2335 		}
2336 	}
2337 
2338 	val = get_param(cmd, "GroupMgntCipher");
2339 	if (val) {
2340 		if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2341 			dut->ap_group_mgmt_cipher = AP_BIP_GMAC_256;
2342 		} else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2343 			dut->ap_group_mgmt_cipher = AP_BIP_CMAC_256;
2344 		} else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2345 			dut->ap_group_mgmt_cipher = AP_BIP_GMAC_128;
2346 		} else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2347 			dut->ap_group_mgmt_cipher = AP_BIP_CMAC_128;
2348 		} else {
2349 			send_resp(dut, conn, SIGMA_INVALID,
2350 				  "errorCode,Unsupported GroupMgntCipher");
2351 			return 0;
2352 		}
2353 	}
2354 
2355 	val = get_param(cmd, "WEPKEY");
2356 	if (val) {
2357 		size_t len;
2358 		if (dut->ap_cipher != AP_WEP) {
2359 			send_resp(dut, conn, SIGMA_INVALID,
2360 				  "errorCode,Unexpected WEPKEY without WEP "
2361 				  "configuration");
2362 			return 0;
2363 		}
2364 		len = strlen(val);
2365 		if (len != 10 && len != 26) {
2366 			send_resp(dut, conn, SIGMA_INVALID,
2367 				  "errorCode,Unexpected WEPKEY length");
2368 			return 0;
2369 		}
2370 		snprintf(dut->ap_wepkey, sizeof(dut->ap_wepkey), "%s", val);
2371 	}
2372 
2373 	val = get_param(cmd, "PSK");
2374 	if (!val)
2375 		val = get_param(cmd, "passphrase");
2376 	if (val) {
2377 		if (dut->ap_key_mgmt != AP_WPA2_SAE &&
2378 		    (dut->ap_akm_values & (AKM_WPA_PSK | AKM_SAE)) !=
2379 		    AKM_SAE &&
2380 		    strlen(val) > 64) {
2381 			sigma_dut_print(dut, DUT_MSG_ERROR,
2382 					"Too long PSK/passphtase");
2383 			return -1;
2384 		}
2385 		if (strlen(val) > sizeof(dut->ap_passphrase) - 1)
2386 			return -1;
2387 		snprintf(dut->ap_passphrase, sizeof(dut->ap_passphrase),
2388 			 "%s", val);
2389 	}
2390 
2391 	val = get_param(cmd, "PSKHEX");
2392 	if (val) {
2393 		if (strlen(val) != 64)
2394 			return -1;
2395 		strlcpy(dut->ap_psk, val, sizeof(dut->ap_psk));
2396 	}
2397 
2398 	if (dut->program == PROGRAM_OCE && dut->dev_role == DEVROLE_STA_CFON)
2399 		dut->ap_pmf = AP_PMF_OPTIONAL;
2400 
2401 	val = get_param(cmd, "PMF");
2402 	if (val) {
2403 		if (strcasecmp(val, "Disabled") == 0) {
2404 			dut->ap_pmf = AP_PMF_DISABLED;
2405 		} else if (strcasecmp(val, "Optional") == 0) {
2406 			dut->ap_pmf = AP_PMF_OPTIONAL;
2407 		} else if (strcasecmp(val, "Required") == 0) {
2408 			dut->ap_pmf = AP_PMF_REQUIRED;
2409 		} else {
2410 			send_resp(dut, conn, SIGMA_INVALID,
2411 				  "errorCode,Unsupported PMF");
2412 			return 0;
2413 		}
2414 	}
2415 
2416 	dut->ap_add_sha256 = 0;
2417 	val = get_param(cmd, "SHA256AD");
2418 	if (val == NULL)
2419 		val = get_param(cmd, "SHA256");
2420 	if (val) {
2421 		if (strcasecmp(val, "Disabled") == 0) {
2422 		} else if (strcasecmp(val, "Enabled") == 0) {
2423 			dut->ap_add_sha256 = 1;
2424 		} else {
2425 			send_resp(dut, conn, SIGMA_INVALID,
2426 				  "errorCode,Unsupported SHA256");
2427 			return 0;
2428 		}
2429 	}
2430 
2431 	val = get_param(cmd, "PreAuthentication");
2432 	if (val) {
2433 		if (strcasecmp(val, "disabled") == 0) {
2434 			dut->ap_rsn_preauth = 0;
2435 		} else if (strcasecmp(val, "enabled") == 0) {
2436 			dut->ap_rsn_preauth = 1;
2437 		} else {
2438 			send_resp(dut, conn, SIGMA_INVALID,
2439 				  "errorCode,Unsupported PreAuthentication value");
2440 			return 0;
2441 		}
2442 	}
2443 
2444 	val = get_param(cmd, "AKMSuiteType");
2445 	if (val) {
2446 		const char *in_pos = val;
2447 
2448 		dut->ap_akm_values = 0;
2449 		while (*in_pos) {
2450 			int akm = atoi(in_pos);
2451 
2452 			if (akm < 0 || akm >= 32) {
2453 				send_resp(dut, conn, SIGMA_ERROR,
2454 					  "errorCode,Unsupported AKMSuiteType value");
2455 				return STATUS_SENT;
2456 			}
2457 
2458 			dut->ap_akm_values |= 1 << akm;
2459 
2460 			in_pos = strchr(in_pos, ';');
2461 			if (!in_pos)
2462 				break;
2463 			while (*in_pos == ';')
2464 				in_pos++;
2465 		}
2466 		dut->ap_akm = 1;
2467 		if (dut->ap_akm_values & (1 << 14))
2468 			dut->ap_add_sha384 = 1;
2469 		if (dut->ap_akm_values & (1 << 15))
2470 			dut->ap_add_sha384 = 1;
2471 	}
2472 
2473 	if (dut->ap_key_mgmt == AP_OPEN && !dut->ap_akm_values) {
2474 		dut->ap_hs2 = 0;
2475 		dut->ap_pmf = AP_PMF_DISABLED;
2476 	}
2477 
2478 	val = get_param(cmd, "PMKSACaching");
2479 	if (val) {
2480 		dut->ap_pmksa = 1;
2481 		if (strcasecmp(val, "disabled") == 0) {
2482 			dut->ap_pmksa_caching = 1;
2483 		} else if (strcasecmp(val, "enabled") == 0) {
2484 			dut->ap_pmksa_caching = 0;
2485 		} else {
2486 			send_resp(dut, conn, SIGMA_INVALID,
2487 				  "errorCode,Unsupported PMKSACaching value");
2488 			return 0;
2489 		}
2490 	}
2491 
2492 	val = get_param(cmd, "BeaconProtection");
2493 	if (val)
2494 		dut->ap_beacon_prot = atoi(val);
2495 
2496 	val = get_param(cmd, "Transition_Disable");
2497 	if (val) {
2498 		if (atoi(val)) {
2499 			val = get_param(cmd, "Transition_Disable_Index");
2500 			if (!val) {
2501 				send_resp(dut, conn, SIGMA_INVALID,
2502 					  "errorCode,Transition_Disable without Transition_Disable_Index");
2503 				return STATUS_SENT;
2504 			}
2505 			dut->ap_transition_disable = 1 << atoi(val);
2506 		} else {
2507 			dut->ap_transition_disable = 0;
2508 		}
2509 	}
2510 
2511 	return 1;
2512 }
2513 
2514 
2515 int sta_cfon_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
2516 			  struct sigma_cmd *cmd)
2517 {
2518 	int status;
2519 
2520 	status = cmd_ap_set_wireless(dut, conn, cmd);
2521 	if (status != 1)
2522 		return status;
2523 	status = cmd_ap_set_security(dut, conn, cmd);
2524 	if (status != 1)
2525 		return status;
2526 	return cmd_ap_config_commit(dut, conn, cmd);
2527 }
2528 
2529 
2530 static enum sigma_cmd_result cmd_ap_set_radius(struct sigma_dut *dut,
2531 					       struct sigma_conn *conn,
2532 					       struct sigma_cmd *cmd)
2533 {
2534 	/* const char *name = get_param(cmd, "NAME"); */
2535 	const char *val;
2536 	unsigned int wlan_tag = 1, radius_port = 0;
2537 	char *radius_ipaddr = NULL, *radius_password = NULL;
2538 
2539 	val = get_param(cmd, "WLAN_TAG");
2540 	if (val) {
2541 		wlan_tag = atoi(val);
2542 		if (wlan_tag != 1 && wlan_tag != 2) {
2543 			send_resp(dut, conn, SIGMA_INVALID,
2544 				  "errorCode,Invalid WLAN_TAG");
2545 			return 0;
2546 		}
2547 	}
2548 
2549 	val = get_param(cmd, "PORT");
2550 	if (val)
2551 		radius_port = atoi(val);
2552 
2553 	if (wlan_tag == 1) {
2554 		if (radius_port)
2555 			dut->ap_radius_port = radius_port;
2556 		radius_ipaddr = dut->ap_radius_ipaddr;
2557 		radius_password = dut->ap_radius_password;
2558 	} else if (wlan_tag == 2) {
2559 		if (radius_port)
2560 			dut->ap2_radius_port = radius_port;
2561 		radius_ipaddr = dut->ap2_radius_ipaddr;
2562 		radius_password = dut->ap2_radius_password;
2563 	}
2564 
2565 	val = get_param(cmd, "IPADDR");
2566 	if (val) {
2567 		if (strlen(val) > sizeof(dut->ap_radius_ipaddr) - 1)
2568 			return -1;
2569 		snprintf(radius_ipaddr, sizeof(dut->ap_radius_ipaddr),
2570 			 "%s", val);
2571 	}
2572 
2573 	val = get_param(cmd, "PASSWORD");
2574 	if (val) {
2575 		if (strlen(val) > sizeof(dut->ap_radius_password) - 1)
2576 			return -1;
2577 		snprintf(radius_password,
2578 			 sizeof(dut->ap_radius_password), "%s", val);
2579 	}
2580 
2581 	return 1;
2582 }
2583 
2584 
2585 static void owrt_ap_set_qcawifi(struct sigma_dut *dut, const char *key,
2586 				const char *val)
2587 {
2588 	if (!val) {
2589 		run_system_wrapper(dut, "uci delete wireless.qcawifi.%s", key);
2590 		return;
2591 	}
2592 
2593 	run_system(dut, "uci set wireless.qcawifi=qcawifi");
2594 	run_system_wrapper(dut, "uci set wireless.qcawifi.%s=%s", key, val);
2595 }
2596 
2597 
2598 static void owrt_ap_set_radio(struct sigma_dut *dut, int id,
2599 			      const char *key, const char *val)
2600 {
2601 	char buf[100];
2602 
2603 	if (val == NULL) {
2604 		snprintf(buf, sizeof(buf),
2605 			 "uci delete wireless.wifi%d.%s", id, key);
2606 		run_system(dut, buf);
2607 		return;
2608 	}
2609 
2610 	snprintf(buf, sizeof(buf), "uci set wireless.wifi%d.%s=%s",
2611 		 id, key, val);
2612 	run_system(dut, buf);
2613 }
2614 
2615 
2616 static void owrt_ap_set_list_radio(struct sigma_dut *dut, int id,
2617 				   const char *key, const char *val)
2618 {
2619 	char buf[256];
2620 
2621 	if (val == NULL) {
2622 		snprintf(buf, sizeof(buf),
2623 			 "uci del_list wireless.wifi%d.%s", id, key);
2624 		run_system(dut, buf);
2625 		return;
2626 	}
2627 
2628 	snprintf(buf, sizeof(buf), "uci add_list wireless.wifi%d.%s=%s",
2629 		 id, key, val);
2630 	run_system(dut, buf);
2631 }
2632 
2633 
2634 static void owrt_ap_set_vap(struct sigma_dut *dut, int id, const char *key,
2635 			    const char *val)
2636 {
2637 	char buf[256];
2638 
2639 	if (val == NULL) {
2640 		snprintf(buf, sizeof(buf),
2641 			 "uci delete wireless.@wifi-iface[%d].%s", id, key);
2642 		run_system(dut, buf);
2643 		return;
2644 	}
2645 
2646 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2647 		 id, key, val);
2648 	run_system(dut, buf);
2649 }
2650 
2651 
2652 static void owrt_ap_set_list_vap(struct sigma_dut *dut, int id,
2653 				 const char *key, const char *val)
2654 {
2655 	char buf[1024];
2656 
2657 	if (val == NULL) {
2658 		snprintf(buf, sizeof(buf),
2659 			 "uci del_list wireless.@wifi-iface[%d].%s", id, key);
2660 		run_system(dut, buf);
2661 		return;
2662 	}
2663 
2664 	snprintf(buf, sizeof(buf),
2665 		 "uci add_list wireless.@wifi-iface[%d].%s=%s",
2666 		 id, key, val);
2667 	run_system(dut, buf);
2668 }
2669 
2670 
2671 static void owrt_ap_add_vap(struct sigma_dut *dut, int id, const char *key,
2672 			    const char *val)
2673 {
2674 	char buf[256];
2675 	int res;
2676 
2677 	if (val == NULL) {
2678 		res = snprintf(buf, sizeof(buf),
2679 			       "uci delete wireless.@wifi-iface[%d].%s",
2680 			       id, key);
2681 		if (res >= 0 && res < sizeof(buf))
2682 			run_system(dut, buf);
2683 		return;
2684 	}
2685 
2686 	run_system(dut, "uci add wireless wifi-iface");
2687 	res = snprintf(buf, sizeof(buf),
2688 		       "uci set wireless.@wifi-iface[%d].%s=%s",
2689 		       id, key, val);
2690 	if (res >= 0 && res < sizeof(buf))
2691 		run_system(dut, buf);
2692 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2693 		 id, "network", "lan");
2694 	run_system(dut, buf);
2695 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2696 		 id, "mode", "ap");
2697 	run_system(dut, buf);
2698 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2699 		 id, "encryption", "none");
2700 	run_system(dut, buf);
2701 }
2702 
2703 
2704 #define OPENWRT_MAX_NUM_RADIOS (MAX_RADIO + 1)
2705 static int owrt_ap_config_radio(struct sigma_dut *dut)
2706 {
2707 	int radio_id[MAX_RADIO] = { 0, 1, 2 };
2708 	int radio_count, radio_no;
2709 	char buf[64];
2710 
2711 	for (radio_count = 0; radio_count < OPENWRT_MAX_NUM_RADIOS;
2712 	     radio_count++) {
2713 		snprintf(buf, sizeof(buf), "%s%d", "wifi", radio_count);
2714 		for (radio_no = 0; radio_no < MAX_RADIO; radio_no++) {
2715 			if (!sigma_radio_ifname[radio_no] ||
2716 			    strcmp(sigma_radio_ifname[radio_no], buf) != 0)
2717 				continue;
2718 			owrt_ap_set_radio(dut, radio_count, "disabled", "0");
2719 			owrt_ap_set_vap(dut, radio_count, "device", buf);
2720 			radio_id[radio_no] = radio_count;
2721 		}
2722 	}
2723 
2724 	/* Hardware mode (11a/b/g/n/ac) & HT mode selection */
2725 	switch (dut->ap_mode) {
2726 	case AP_11g:
2727 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11g");
2728 		break;
2729 	case AP_11b:
2730 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11b");
2731 		break;
2732 	case AP_11ng:
2733 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng");
2734 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2735 		break;
2736 	case AP_11a:
2737 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11a");
2738 		break;
2739 	case AP_11na:
2740 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11na");
2741 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2742 		break;
2743 	case AP_11ac:
2744 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ac");
2745 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2746 		break;
2747 	case AP_11ax:
2748 		if (dut->ap_channel >= 36) {
2749 			owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axa");
2750 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2751 		} else {
2752 			owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axg");
2753 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2754 		}
2755 		break;
2756 	case AP_inval:
2757 		sigma_dut_print(dut, DUT_MSG_ERROR,
2758 				"MODE NOT SPECIFIED!");
2759 		return -1;
2760 	default:
2761 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng");
2762 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2763 		break;
2764 	}
2765 
2766 	if (dut->ap_is_dual) {
2767 		/* Hardware mode (11a/b/g/n/ac) & HT mode selection */
2768 		switch (dut->ap_mode_1) {
2769 		case AP_11g:
2770 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11g");
2771 			break;
2772 		case AP_11b:
2773 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11b");
2774 			break;
2775 		case AP_11ng:
2776 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng");
2777 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2778 			break;
2779 		case AP_11a:
2780 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11a");
2781 			break;
2782 		case AP_11na:
2783 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11na");
2784 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2785 			break;
2786 		case AP_11ac:
2787 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ac");
2788 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT80");
2789 			break;
2790 		case AP_11ax:
2791 			if (dut->ap_channel >= 36) {
2792 				owrt_ap_set_radio(dut, radio_id[1],
2793 						  "hwmode", "11axa");
2794 				owrt_ap_set_radio(dut, radio_id[1],
2795 						  "htmode", "HT80");
2796 			} else {
2797 				owrt_ap_set_radio(dut, radio_id[1],
2798 						  "hwmode", "11axg");
2799 				owrt_ap_set_radio(dut, radio_id[1],
2800 						  "htmode", "HT20");
2801 			}
2802 			break;
2803 		case AP_inval:
2804 			sigma_dut_print(dut, DUT_MSG_ERROR,
2805 					"MODE NOT SPECIFIED!");
2806 			return -1;
2807 		default:
2808 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng");
2809 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2810 			break;
2811 		}
2812 
2813 	}
2814 
2815 	/* Channel */
2816 	snprintf(buf, sizeof(buf), "%d", dut->ap_channel);
2817 	owrt_ap_set_radio(dut, radio_id[0], "channel", buf);
2818 
2819 	switch (dut->ap_chwidth) {
2820 		case AP_20:
2821 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2822 			break;
2823 		case AP_40:
2824 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT40");
2825 			break;
2826 		case AP_80:
2827 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2828 			break;
2829 		case AP_160:
2830 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT160");
2831 			break;
2832 		case AP_80_80:
2833 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80_80");
2834 			break;
2835 		case AP_AUTO:
2836 		default:
2837 			break;
2838 	}
2839 
2840 	if (dut->ap_channel == 140 || dut->ap_channel == 144) {
2841 		if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
2842 			owrt_ap_set_radio(dut, radio_id[0], "set_ch_144", "3");
2843 	}
2844 
2845 	if (dut->ap_is_dual) {
2846 		snprintf(buf, sizeof(buf), "%d", dut->ap_channel_1);
2847 		owrt_ap_set_radio(dut, radio_id[1], "channel", buf);
2848 	}
2849 
2850 	/* Country Code */
2851 	if (dut->ap_reg_domain == REG_DOMAIN_GLOBAL) {
2852 		const char *country;
2853 
2854 		country = dut->ap_countrycode[0] ? dut->ap_countrycode : "US";
2855 		snprintf(buf, sizeof(buf), "%s4", country);
2856 		owrt_ap_set_radio(dut, radio_id[0], "country", buf);
2857 		if (dut->ap_is_dual)
2858 			owrt_ap_set_radio(dut, radio_id[1], "country", buf);
2859 	} else if (dut->ap_countrycode[0]) {
2860 		owrt_ap_set_radio(dut, radio_id[0], "country",
2861 				  dut->ap_countrycode);
2862 	}
2863 
2864 	if (dut->ap_disable_protection == 1) {
2865 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'0 0'");
2866 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'1 0'");
2867 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'2 0'");
2868 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'3 0'");
2869 	}
2870 
2871 	if (dut->ap_oce == VALUE_ENABLED &&
2872 	    get_driver_type(dut) == DRIVER_OPENWRT)
2873 		owrt_ap_set_radio(dut, radio_id[0], "bcnburst", "1");
2874 
2875 	if (dut->ap_mbssid == VALUE_ENABLED)
2876 		owrt_ap_set_qcawifi(dut, "mbss_ie_enable", "1");
2877 
2878 	if (dut->program == PROGRAM_HE) {
2879 		owrt_ap_set_radio(dut, radio_id[0], "he_bsscolor", "'1 1'");
2880 		if (dut->ap_is_dual)
2881 			owrt_ap_set_radio(dut, radio_id[1], "he_bsscolor",
2882 					  "'2 1'");
2883 		owrt_ap_set_qcawifi(dut, "ap_bss_color_collision_detection",
2884 				    "1");
2885 	}
2886 
2887 	return 1;
2888 }
2889 
2890 
2891 static int owrt_ap_config_vap_hs2(struct sigma_dut *dut, int vap_id)
2892 {
2893 	char buf[256];
2894 
2895 	snprintf(buf, sizeof(buf), "%d", dut->ap_hs2);
2896 	owrt_ap_set_vap(dut, vap_id, "hs20", buf);
2897 	owrt_ap_set_vap(dut, vap_id, "qbssload", "1");
2898 	owrt_ap_set_vap(dut, vap_id, "hs20_deauth_req_timeout","3");
2899 
2900 	owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name",
2901 			     "'eng:Wi-Fi Alliance'");
2902 
2903 	owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name",
2904 			     "'chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f'");
2905 
2906 	if (dut->ap_wan_metrics == 1)
2907 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2908 				"'01:2500:384:0:0:10'");
2909 	else if (dut->ap_wan_metrics == 1)
2910 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2911 				"'01:1500:384:20:20:10'");
2912 	else if (dut->ap_wan_metrics == 2)
2913 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2914 				"'01:1500:384:20:20:10'");
2915 	else if (dut->ap_wan_metrics == 3)
2916 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2917 				"'01:2000:1000:20:20:10'");
2918 	else if (dut->ap_wan_metrics == 4)
2919 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2920 				"'01:8000:1000:20:20:10'");
2921 	else if (dut->ap_wan_metrics == 5)
2922 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2923 				"'01:9000:5000:20:20:10'");
2924 
2925 	if (dut->ap_conn_capab == 1) {
2926 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", "'1:0:0'");
2927 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2928 				     "'6:20:1'");
2929 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2930 				     "'6:22:0'");
2931 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2932 				     "'6:80:1'");
2933 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2934 				     "'6:443:1'");
2935 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2936 				     "'6:1723:0'");
2937 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2938 				     "'6:5060:0'");
2939 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2940 				     "'17:500:1'");
2941 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2942 				     "'17:5060:0'");
2943 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2944 				     "'17:4500:1'");
2945 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2946 				     "'50:0:1'");
2947 	} else if (dut->ap_conn_capab == 2) {
2948 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2949 				     "'6:80:1'");
2950 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2951 				     "'6:443:1'");
2952 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2953 				     "'17:5060:1'");
2954 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2955 				     "'6:5060:1'");
2956 	} else if (dut->ap_conn_capab == 3) {
2957 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2958 				     "'6:80:1'");
2959 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2960 				     "'6:443:1'");
2961 	}
2962 
2963 	if (dut->ap_oper_class == 1)
2964 		snprintf(buf, sizeof(buf), "%s", "51");
2965 	else if (dut->ap_oper_class == 2)
2966 		snprintf(buf, sizeof(buf), "%s", "73");
2967 	else if (dut->ap_oper_class == 3)
2968 		snprintf(buf, sizeof(buf), "%s", "5173");
2969 
2970 	if (dut->ap_oper_class)
2971 		owrt_ap_set_vap(dut, vap_id, "hs20_operating_class", buf);
2972 
2973 	if (dut->ap_osu_provider_list) {
2974 		char *osu_friendly_name = NULL;
2975 		char *osu_icon = NULL;
2976 		char *osu_ssid = NULL;
2977 		char *osu_nai = NULL;
2978 		char *osu_service_desc = NULL;
2979 		char *hs20_icon_filename = NULL;
2980 		char hs20_icon[150];
2981 		int osu_method;
2982 
2983 		hs20_icon_filename = "icon_red_zxx.png";
2984 		if (dut->ap_osu_icon_tag == 2)
2985 			hs20_icon_filename = "wifi-abgn-logo_270x73.png";
2986 		snprintf(hs20_icon, sizeof(hs20_icon),
2987 			 "'128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s'",
2988 			 hs20_icon_filename);
2989 		osu_icon = "icon_red_zxx.png";
2990 		osu_ssid = "OSU";
2991 		osu_friendly_name = "'kor:SP 빨강 테스트 전용'";
2992 		osu_service_desc = "'kor:테스트 목적으로 무료 서비스'";
2993 		osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 :
2994 			dut->ap_osu_method[0];
2995 
2996 		if (strlen(dut->ap_osu_server_uri[0]))
2997 			owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri",
2998 					     dut->ap_osu_server_uri[0]);
2999 		else
3000 			owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri",
3001 					     "'https://osu-server.r2-testbed.wi-fi.org/'");
3002 		switch (dut->ap_osu_provider_list) {
3003 		case 1:
3004 		case 101:
3005 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3006 					     "'eng:SP Red Test Only'");
3007 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3008 					     "'eng:Free service for test purpose'");
3009 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3010 					     hs20_icon);
3011 
3012 			hs20_icon_filename = "icon_red_eng.png";
3013 			if (dut->ap_osu_icon_tag == 2)
3014 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3015 
3016 			snprintf(hs20_icon, sizeof(hs20_icon),
3017 				 "'160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s'",
3018 				 hs20_icon_filename);
3019 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3020 					     "icon_red_eng.png");
3021 			break;
3022 		case 2:
3023 		case 102:
3024 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3025 					     "'eng:Wireless Broadband Alliance'");
3026 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3027 					     "'eng:Free service for test purpose'");
3028 			hs20_icon_filename = "icon_orange_zxx.png";
3029 			if (dut->ap_osu_icon_tag == 2)
3030 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3031 
3032 			snprintf(hs20_icon, sizeof(hs20_icon),
3033 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3034 				 hs20_icon_filename);
3035 			osu_icon = "icon_orange_zxx.png";
3036 			osu_friendly_name = "'kor:와이어리스 브로드밴드 얼라이언스'";
3037 			break;
3038 		case 3:
3039 		case 103:
3040 			osu_friendly_name = "'spa:SP Red Test Only'";
3041 			osu_service_desc = "'spa:Free service for test purpose'";
3042 			break;
3043 		case 4:
3044 		case 104:
3045 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3046 					     "'eng:SP Orange Test Only'");
3047 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3048 					     "'eng:Free service for test purpose'");
3049 			hs20_icon_filename = "icon_orange_eng.png";
3050 			if (dut->ap_osu_icon_tag == 2)
3051 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3052 
3053 			snprintf(hs20_icon, sizeof(hs20_icon),
3054 				 "'160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s'",
3055 				 hs20_icon_filename);
3056 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3057 					     hs20_icon);
3058 			osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3059 
3060 			hs20_icon_filename = "icon_orange_zxx.png";
3061 			if (dut->ap_osu_icon_tag == 2)
3062 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3063 
3064 			snprintf(hs20_icon, sizeof(hs20_icon),
3065 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3066 				 hs20_icon_filename);
3067 			osu_icon = "icon_orange_zxx.png";
3068 			break;
3069 		case 5:
3070 		case 105:
3071 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3072 					     "'eng:SP Orange Test Only'");
3073 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3074 					     "'eng:Free service for test purpose'");
3075 			osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3076 
3077 			hs20_icon_filename = "icon_orange_zxx.png";
3078 			if (dut->ap_osu_icon_tag == 2)
3079 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3080 
3081 			snprintf(hs20_icon, sizeof(hs20_icon),
3082 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3083 				 hs20_icon_filename);
3084 			osu_icon = "icon_orange_zxx.png";
3085 			break;
3086 		case 6:
3087 		case 106:
3088 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3089 					     "'eng:SP Green Test Only'");
3090 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3091 					     "'kor:SP 초록 테스트 전용'");
3092 
3093 			hs20_icon_filename = "icon_green_zxx.png";
3094 			if (dut->ap_osu_icon_tag == 2)
3095 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3096 
3097 			snprintf(hs20_icon, sizeof(hs20_icon),
3098 				 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'",
3099 				 hs20_icon_filename);
3100 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3101 					     hs20_icon);
3102 
3103 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3104 					     "'icon_green_zxx.png'");
3105 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 :
3106 				dut->ap_osu_method[0];
3107 
3108 			snprintf(buf, sizeof(buf), "%d", osu_method);
3109 			owrt_ap_set_vap(dut, vap_id, "osu_method_list", buf);
3110 
3111 			if (strlen(dut->ap_osu_server_uri[1]))
3112 				owrt_ap_set_list_vap(dut, vap_id,
3113 						     "osu_server_uri",
3114 						     dut->ap_osu_server_uri[1]);
3115 			else
3116 				owrt_ap_set_list_vap(dut, vap_id,
3117 						     "osu_server_uri",
3118 						     "'https://osu-server.r2-testbed.wi-fi.org/'");
3119 
3120 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3121 					     "'eng:SP Orange Test Only'");
3122 
3123 			hs20_icon_filename = "icon_orange_zxx.png";
3124 			if (dut->ap_osu_icon_tag == 2)
3125 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3126 
3127 			snprintf(hs20_icon, sizeof(hs20_icon),
3128 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3129 				 hs20_icon_filename);
3130 
3131 			osu_icon = "icon_orange_zxx.png";
3132 			osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3133 			osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 :
3134 				dut->ap_osu_method[1];
3135 			osu_service_desc = NULL;
3136 			break;
3137 		case 7:
3138 		case 107:
3139 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3140 					     "'eng:SP Green Test Only'");
3141 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3142 					     "'eng:Free service for test purpose'");
3143 
3144 			hs20_icon_filename = "icon_green_eng.png";
3145 			if (dut->ap_osu_icon_tag == 2)
3146 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3147 
3148 			snprintf(hs20_icon, sizeof(hs20_icon),
3149 				 "'160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s'",
3150 				 hs20_icon_filename);
3151 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3152 					     hs20_icon);
3153 
3154 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3155 					     "'icon_green_eng.png'");
3156 			osu_friendly_name = "'kor:SP 초록 테스트 전용'";
3157 
3158 			hs20_icon_filename = "icon_green_zxx.png";
3159 			if (dut->ap_osu_icon_tag == 2)
3160 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3161 
3162 			snprintf(hs20_icon, sizeof(hs20_icon),
3163 				 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'",
3164 				 hs20_icon_filename);
3165 			osu_icon = "icon_green_zxx.png";
3166 			break;
3167 		case 8:
3168 		case 108:
3169 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3170 					     "'eng:SP Red Test Only'");
3171 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3172 					     "'eng:Free service for test purpose'");
3173 			osu_ssid = "OSU-Encrypted";
3174 			osu_nai = "'anonymous@hotspot.net'";
3175 			break;
3176 		case 9:
3177 		case 109:
3178 			osu_ssid = "OSU-OSEN";
3179 			osu_nai = "'test-anonymous@wi-fi.org'";
3180 			osu_friendly_name = "'eng:SP Orange Test Only'";
3181 			hs20_icon_filename = "icon_orange_zxx.png";
3182 			if (dut->ap_osu_icon_tag == 2)
3183 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3184 
3185 			snprintf(hs20_icon, sizeof(hs20_icon),
3186 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3187 				 hs20_icon_filename);
3188 			osu_icon = "icon_orange_zxx.png";
3189 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 :
3190 				dut->ap_osu_method[0];
3191 			osu_service_desc = NULL;
3192 			break;
3193 		default:
3194 			break;
3195 		}
3196 
3197 		if (strlen(dut->ap_osu_ssid)) {
3198 			if (dut->ap_tag_ssid[0][0] &&
3199 			    strcmp(dut->ap_tag_ssid[0],
3200 				   dut->ap_osu_ssid) != 0 &&
3201 			    strcmp(dut->ap_tag_ssid[0], osu_ssid) != 0) {
3202 				sigma_dut_print(dut, DUT_MSG_ERROR,
3203 						"OSU_SSID and WLAN_TAG2 SSID differ");
3204 				return -2;
3205 			}
3206 
3207 			snprintf(buf, sizeof(buf), "'\"%s\"'",
3208 				 dut->ap_osu_ssid);
3209 		} else {
3210 			snprintf(buf, sizeof(buf), "'\"%s\"'", osu_ssid);
3211 		}
3212 
3213 		owrt_ap_set_vap(dut, vap_id, "osu_ssid", buf);
3214 
3215 
3216 		if (osu_friendly_name)
3217 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3218 					     osu_friendly_name);
3219 		if (osu_service_desc)
3220 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3221 					     osu_service_desc);
3222 		if (osu_nai)
3223 			owrt_ap_set_vap(dut, vap_id, "osu_nai", osu_nai);
3224 
3225 		owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", hs20_icon);
3226 
3227 		if (osu_icon)
3228 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3229 					     osu_icon);
3230 
3231 		if (dut->ap_osu_provider_list > 100) {
3232 			owrt_ap_set_list_vap(dut, vap_id, "osu_method_list",
3233 					     "0");
3234 		} else {
3235 			snprintf(buf, sizeof(buf), "%d", osu_method);
3236 			owrt_ap_set_list_vap(dut, vap_id, "osu_method_list",
3237 					     buf);
3238 		}
3239 	}
3240 
3241 	return 0;
3242 }
3243 
3244 
3245 static int set_anqp_elem_value(struct sigma_dut *dut, const char *ifname,
3246 			       char *anqp_string, size_t str_size)
3247 {
3248 	unsigned char bssid[ETH_ALEN];
3249 	unsigned char dummy_mac[] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50 };
3250 	int preference = 0xff;
3251 
3252 	if (get_hwaddr(ifname, bssid) < 0)
3253 		return -1;
3254 	snprintf(anqp_string, str_size,
3255 		 "272:3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x",
3256 		 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5],
3257 		 preference,
3258 		 dummy_mac[0], dummy_mac[1], dummy_mac[2],
3259 		 dummy_mac[3], dummy_mac[4], dummy_mac[5],
3260 		 preference - 1);
3261 	return 0;
3262 }
3263 
3264 
3265 static const char * get_hostapd_ifname(struct sigma_dut *dut)
3266 {
3267 	enum driver_type drv;
3268 
3269 	/* Use the configured hostapd ifname */
3270 	if (dut->hostapd_ifname && if_nametoindex(dut->hostapd_ifname) > 0)
3271 		return dut->hostapd_ifname;
3272 
3273 	/* Use configured main ifname */
3274 	if (dut->main_ifname) {
3275 		if (dut->use_5g && dut->main_ifname_5g &&
3276 		    if_nametoindex(dut->main_ifname_5g) > 0)
3277 			return dut->main_ifname_5g;
3278 		if (!dut->use_5g && dut->main_ifname_2g &&
3279 		    if_nametoindex(dut->main_ifname_2g) > 0)
3280 			return dut->main_ifname_2g;
3281 		if (if_nametoindex(dut->main_ifname) > 0)
3282 			return dut->main_ifname;
3283 	}
3284 
3285 	/* Return based on driver type (indirectly started hostapd) */
3286 	drv = get_driver_type(dut);
3287 	if (drv == DRIVER_ATHEROS) {
3288 		if (dut->use_5g && if_nametoindex("ath1") > 0)
3289 			return "ath1";
3290 		return "ath0";
3291 	}
3292 
3293 	if (drv == DRIVER_OPENWRT) {
3294 		if (sigma_radio_ifname[0] &&
3295 		    strcmp(sigma_radio_ifname[0], "wifi2") == 0)
3296 			return "ath2";
3297 		if (sigma_radio_ifname[0] &&
3298 		    strcmp(sigma_radio_ifname[0], "wifi1") == 0)
3299 			return "ath1";
3300 		return "ath0";
3301 	}
3302 
3303 	/* wlan1-is-likely-5-GHz design */
3304 	if (dut->use_5g && if_nametoindex("wlan1") > 0)
3305 		return "wlan1";
3306 
3307 	/* If nothing else matches, hope for the best and guess this is wlan0 */
3308 	return "wlan0";
3309 }
3310 
3311 
3312 static void get_if_name(struct sigma_dut *dut, char *ifname_str,
3313 			size_t str_size, int wlan_tag)
3314 {
3315 	const char *ifname;
3316 	enum driver_type drv;
3317 
3318 	ifname = get_hostapd_ifname(dut);
3319 	drv = get_driver_type(dut);
3320 
3321 	if (drv == DRIVER_OPENWRT && wlan_tag > 1) {
3322 		/* Handle tagged-ifname only on OPENWRT for now */
3323 		snprintf(ifname_str, str_size, "%s%d", ifname, wlan_tag - 1);
3324 	} else if ((drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN) &&
3325 		   wlan_tag == 2) {
3326 		snprintf(ifname_str, str_size, "%s_1", ifname);
3327 	} else {
3328 		snprintf(ifname_str, str_size, "%s", ifname);
3329 	}
3330 }
3331 
3332 
3333 static int sae_pw_id_used(struct sigma_dut *dut)
3334 {
3335 	return dut->ap_sae_passwords &&
3336 		strchr(dut->ap_sae_passwords, ':');
3337 }
3338 
3339 
3340 static int owrt_ap_config_vap(struct sigma_dut *dut)
3341 {
3342 	char buf[256], *temp;
3343 	int vap_id = 0, vap_count, i, j, res;
3344 	const char *ifname;
3345 	char ifname2[50];
3346 
3347 	if (sigma_radio_ifname[0] &&
3348 	    strcmp(sigma_radio_ifname[0], "wifi2") == 0)
3349 		ifname = "ath2";
3350 	else if (sigma_radio_ifname[0] &&
3351 		 strcmp(sigma_radio_ifname[0], "wifi1") == 0)
3352 		ifname = "ath1";
3353 	else
3354 		ifname = "ath0";
3355 
3356 	for (vap_count = 0; vap_count < OPENWRT_MAX_NUM_RADIOS; vap_count++) {
3357 		snprintf(buf, sizeof(buf), "wifi%d", vap_count);
3358 
3359 		for (vap_id = 0; vap_id < MAX_RADIO; vap_id++) {
3360 			if (sigma_radio_ifname[vap_id] &&
3361 			    strcmp(sigma_radio_ifname[vap_id], buf) == 0)
3362 				break;
3363 		}
3364 		if (vap_id == MAX_RADIO)
3365 			continue;
3366 
3367 		/* Single VAP configuration */
3368 		if (!dut->ap_is_dual)
3369 			vap_id = vap_count;
3370 
3371 		for (j = 0; j < MAX_WLAN_TAGS - 1; j++) {
3372 			/*
3373 			 * We keep a separate array of ap_tag_ssid and
3374 			 * ap_tag_key_mgmt for tags starting from WLAN_TAG=2.
3375 			 * So j=0 => WLAN_TAG = 2
3376 			 */
3377 			int wlan_tag = j + 2;
3378 
3379 			if (wlan_tag == 2 && dut->program == PROGRAM_WPA3 &&
3380 			   (dut->ap_interface_5g || dut->ap_interface_2g)) {
3381 				res = snprintf(
3382 					dut->ap_tag_ssid[wlan_tag - 2],
3383 					sizeof(dut->ap_tag_ssid[wlan_tag - 2]),
3384 					"%s-owe", dut->ap_ssid);
3385 				if (res < 0 ||
3386 				    res >= sizeof(dut->ap_tag_ssid[wlan_tag -
3387 								   2]))
3388 					dut->ap_tag_ssid[wlan_tag - 2][0] =
3389 						'\0';
3390 			}
3391 
3392 			if (dut->ap_tag_ssid[j][0] == '\0')
3393 				continue;
3394 
3395 			snprintf(buf, sizeof(buf), "%s%d", "wifi", vap_count);
3396 			owrt_ap_add_vap(dut, vap_count + (wlan_tag - 1),
3397 					"device", buf);
3398 			/* SSID */
3399 			snprintf(buf, sizeof(buf), "\"%s\"",
3400 				 dut->ap_tag_ssid[j]);
3401 			owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3402 					"ssid", buf);
3403 
3404 			if (dut->ap_key_mgmt == AP_WPA2_OWE &&
3405 			    dut->ap_tag_ssid[0][0] &&
3406 			    dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
3407 				/* OWE transition mode */
3408 				snprintf(buf, sizeof(buf), "%s", ifname);
3409 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3410 						"owe_transition_ifname", buf);
3411 			}
3412 
3413 			if (dut->ap_key_mgmt == AP_OPEN &&
3414 			    dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3415 				/* OWE transition mode */
3416 				snprintf(buf, sizeof(buf), "%s", ifname);
3417 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3418 						"owe_transition_ifname", buf);
3419 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3420 						"hidden", "1");
3421 			}
3422 
3423 			if (ap_ft_enabled(dut)) {
3424 				unsigned char self_mac[ETH_ALEN];
3425 				char mac_str[20];
3426 
3427 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3428 						"mobility_domain",
3429 						dut->ap_mobility_domain);
3430 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3431 						"ft_over_ds",
3432 						dut->ap_ft_ds == VALUE_ENABLED ?
3433 						"1" : "0");
3434 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3435 						"ieee80211r", "1");
3436 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3437 						"nasid", "nas1.example.com");
3438 				if (get_hwaddr(sigma_radio_ifname[0],
3439 					       self_mac) < 0)
3440 					return -1;
3441 				snprintf(mac_str, sizeof(mac_str),
3442 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3443 					 self_mac[0], self_mac[1], self_mac[2],
3444 					 self_mac[3], self_mac[4], self_mac[5]);
3445 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3446 						"ap_macaddr", mac_str);
3447 				snprintf(mac_str, sizeof(mac_str),
3448 					 "%02x%02x%02x%02x%02x%02x",
3449 					 self_mac[0], self_mac[1], self_mac[2],
3450 					 self_mac[3], self_mac[4], self_mac[5]);
3451 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3452 						"r1_key_holder", mac_str);
3453 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3454 						"ft_psk_generate_local", "1");
3455 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3456 						"kh_key_hex",
3457 						"000102030405060708090a0b0c0d0e0f");
3458 				snprintf(mac_str, sizeof(mac_str),
3459 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3460 					 dut->ft_bss_mac_list[0][0],
3461 					 dut->ft_bss_mac_list[0][1],
3462 					 dut->ft_bss_mac_list[0][2],
3463 					 dut->ft_bss_mac_list[0][3],
3464 					 dut->ft_bss_mac_list[0][4],
3465 					 dut->ft_bss_mac_list[0][5]);
3466 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3467 						"ap2_macaddr", mac_str);
3468 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3469 						"ap2_r1_key_holder", mac_str);
3470 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3471 						"nasid2", "nas2.example.com");
3472 			}
3473 
3474 			if (dut->ap_tag_key_mgmt[j] == AP2_OSEN &&
3475 			    wlan_tag == 2) {
3476 				/* Only supported for WLAN_TAG=2 */
3477 				owrt_ap_set_vap(dut, vap_count + 1, "osen",
3478 						"1");
3479 				snprintf(buf, sizeof(buf), "wpa2");
3480 				owrt_ap_set_vap(dut, vap_count + 1,
3481 						"encryption", buf);
3482 				snprintf(buf, sizeof(buf), "%s",
3483 					 dut->ap2_radius_ipaddr);
3484 				owrt_ap_set_vap(dut, vap_count + 1,
3485 						"auth_server", buf);
3486 				snprintf(buf, sizeof(buf), "%d",
3487 					 dut->ap2_radius_port);
3488 				owrt_ap_set_vap(dut, vap_count + 1,
3489 						"auth_port", buf);
3490 				snprintf(buf, sizeof(buf), "%s",
3491 					 dut->ap2_radius_password);
3492 				owrt_ap_set_vap(dut, vap_count + 1,
3493 						"auth_secret", buf);
3494 			} else if (dut->ap_tag_key_mgmt[j] == AP2_WPA2_PSK) {
3495 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3496 						"encryption", "psk2+ccmp");
3497 				snprintf(buf, sizeof(buf), "\"%s\"",
3498 					 dut->ap_passphrase);
3499 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3500 						"key", buf);
3501 				snprintf(buf, sizeof(buf), "%d", dut->ap_pmf);
3502 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3503 						"ieee80211w", buf);
3504 			} else if (dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3505 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3506 						"owe", "1");
3507 				snprintf(buf, sizeof(buf), "ccmp");
3508 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3509 						"encryption", buf);
3510 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3511 						"ieee80211w", "2");
3512 				if (dut->ap_sae_groups) {
3513 					snprintf(buf, sizeof(buf), "\'%s\'",
3514 						 dut->ap_sae_groups);
3515 					owrt_ap_set_list_vap(dut, vap_count +
3516 							     (wlan_tag - 1),
3517 							     "owe_groups", buf);
3518 					if (dut->owe_ptk_workaround)
3519 						owrt_ap_set_list_vap(
3520 							dut, vap_count +
3521 							(wlan_tag - 1),
3522 							"owe_ptk_workaround",
3523 							"1");
3524 				}
3525 			}
3526 		}
3527 
3528 		/* Now set anqp_elem and ft_oa for wlan_tag = 1 */
3529 		if (dut->program == PROGRAM_MBO &&
3530 		    get_driver_type(dut) == DRIVER_OPENWRT) {
3531 			unsigned char self_mac[ETH_ALEN];
3532 			char mac_str[20];
3533 			char anqp_string[200];
3534 
3535 			if (set_anqp_elem_value(dut, sigma_radio_ifname[0],
3536 						anqp_string,
3537 						sizeof(anqp_string)) < 0)
3538 				return -1;
3539 			owrt_ap_set_list_vap(dut, vap_count, "anqp_elem",
3540 					     anqp_string);
3541 
3542 			if (ap_ft_enabled(dut)) {
3543 				owrt_ap_set_vap(dut, vap_count,
3544 						"mobility_domain",
3545 						dut->ap_mobility_domain);
3546 				owrt_ap_set_vap(dut, vap_count,
3547 						"ft_over_ds",
3548 						dut->ap_ft_ds == VALUE_ENABLED ?
3549 						"1" : "0");
3550 				owrt_ap_set_vap(dut, vap_count,
3551 						"ieee80211r", "1");
3552 				owrt_ap_set_vap(dut, vap_count,
3553 						"nasid", "nas1.example.com");
3554 				get_hwaddr(sigma_radio_ifname[0], self_mac);
3555 				snprintf(mac_str, sizeof(mac_str),
3556 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3557 					 self_mac[0], self_mac[1], self_mac[2],
3558 					 self_mac[3], self_mac[4], self_mac[5]);
3559 				owrt_ap_set_vap(dut, vap_count,
3560 						"ap_macaddr", mac_str);
3561 				snprintf(mac_str, sizeof(mac_str),
3562 					 "%02x%02x%02x%02x%02x%02x",
3563 					 self_mac[0], self_mac[1], self_mac[2],
3564 					 self_mac[3], self_mac[4], self_mac[5]);
3565 				owrt_ap_set_vap(dut, vap_count,
3566 						"r1_key_holder", mac_str);
3567 				owrt_ap_set_vap(dut, vap_count,
3568 						"ft_psk_generate_local", "1");
3569 				owrt_ap_set_vap(dut, vap_count,
3570 						"kh_key_hex",
3571 						"000102030405060708090a0b0c0d0e0f");
3572 				snprintf(mac_str, sizeof(mac_str),
3573 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3574 					 dut->ft_bss_mac_list[0][0],
3575 					 dut->ft_bss_mac_list[0][1],
3576 					 dut->ft_bss_mac_list[0][2],
3577 					 dut->ft_bss_mac_list[0][3],
3578 					 dut->ft_bss_mac_list[0][4],
3579 					 dut->ft_bss_mac_list[0][5]);
3580 				owrt_ap_set_vap(dut, vap_count,
3581 						"ap2_macaddr", mac_str);
3582 				owrt_ap_set_vap(dut, vap_count,
3583 						"ap2_r1_key_holder", mac_str);
3584 				owrt_ap_set_vap(dut, vap_count,
3585 						"nasid2", "nas2.example.com");
3586 			}
3587 		}
3588 
3589 		if (dut->ap_oce == VALUE_ENABLED &&
3590 		    get_driver_type(dut) == DRIVER_OPENWRT) {
3591 			owrt_ap_set_vap(dut, vap_id, "oce", "1");
3592 			owrt_ap_set_vap(dut, vap_id, "qbssload", "1");
3593 			owrt_ap_set_vap(dut, vap_id, "bpr_enable", "1");
3594 
3595 			if (dut->ap_80plus80 == 1)
3596 				owrt_ap_set_vap(dut, vap_id, "cfreq2", "5775");
3597 
3598 			if (dut->ap_akm == 1) {
3599 				owrt_ap_set_vap(dut, vap_id, "wpa_group_rekey",
3600 						"3600");
3601 				owrt_ap_set_vap(dut, vap_id, "key", "12345678");
3602 				owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3603 						"1");
3604 				owrt_ap_set_vap(dut, vap_id, "fils_cache_id",
3605 						"1234");
3606 				owrt_ap_set_vap(dut, vap_id,
3607 						"erp_send_reauth_start", "1");
3608 			}
3609 
3610 			if (dut->ap_filshlp == VALUE_ENABLED) {
3611 				struct ifreq ifr;
3612 				char *ifname;
3613 				int s;
3614 				struct sockaddr_in *ipaddr;
3615 
3616 				s = socket(AF_INET, SOCK_DGRAM, 0);
3617 				if (s < 0) {
3618 					sigma_dut_print(dut, DUT_MSG_ERROR,
3619 							"Failed to open socket");
3620 					return -1;
3621 				}
3622 				ifr.ifr_addr.sa_family = AF_INET;
3623 
3624 				memset(&ifr, 0, sizeof(ifr));
3625 				ifname = "br-lan";
3626 				strlcpy(ifr.ifr_name, ifname,
3627 					sizeof(ifr.ifr_name));
3628 				if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
3629 					perror("ioctl");
3630 					close(s);
3631 					return -1;
3632 				}
3633 
3634 				ipaddr = (struct sockaddr_in*)&ifr.ifr_addr;
3635 				snprintf(buf, sizeof(buf), "%s",
3636 					 inet_ntoa(ipaddr->sin_addr));
3637 				owrt_ap_set_vap(dut, vap_id, "own_ip_addr",
3638 						buf);
3639 				snprintf(buf, sizeof(buf), "%s",
3640 					 dut->ap_dhcpserv_ipaddr);
3641 				owrt_ap_set_vap(dut, vap_id, "dhcp_server",
3642 						buf);
3643 				owrt_ap_set_vap(dut, vap_id,
3644 						"dhcp_rapid_commit_proxy", "1");
3645 				owrt_ap_set_vap(dut, vap_id,
3646 						"fils_hlp_wait_time", "300");
3647 			}
3648 
3649 			if (dut->ap_filsdscv == VALUE_ENABLED) {
3650 				owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3651 						"1");
3652 				owrt_ap_set_vap(dut, vap_id, "fils_fd_period",
3653 						"20");
3654 			}
3655 		}
3656 
3657 		if (dut->ap_filsdscv == VALUE_DISABLED) {
3658 			owrt_ap_set_vap(dut, vap_id, "ieee80211ai", "0");
3659 			owrt_ap_set_vap(dut, vap_id, "fils_fd_period", "0");
3660 		}
3661 
3662 		if (dut->ap_oce == VALUE_DISABLED &&
3663 		    get_driver_type(dut) == DRIVER_OPENWRT) {
3664 			owrt_ap_set_vap(dut, vap_id, "oce", "0");
3665 			owrt_ap_set_vap(dut, vap_id, "qbssload", "0");
3666 			owrt_ap_set_vap(dut, vap_id, "bpr_enable", "0");
3667 
3668 			if (dut->ap_filsdscv == VALUE_DISABLED) {
3669 				owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3670 						"0");
3671 				owrt_ap_set_vap(dut, vap_id, "fils_fd_period",
3672 						"0");
3673 			}
3674 
3675 			if (dut->device_type == AP_testbed)
3676 				owrt_ap_set_vap(dut, vap_id, "mbo", "1");
3677 		}
3678 
3679 		/* NAIRealm */
3680 		if (dut->ap_nairealm_int == 1) {
3681 			snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_nairealm);
3682 			owrt_ap_set_vap(dut, vap_id, "fils_realm", buf);
3683 			owrt_ap_set_vap(dut, vap_id, "erp_domain", buf);
3684 		}
3685 
3686 		/* SSID */
3687 		snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_ssid);
3688 		owrt_ap_set_vap(dut, vap_count, "ssid", buf);
3689 
3690 		/* Encryption */
3691 		switch (dut->ap_key_mgmt) {
3692 		case AP_OPEN:
3693 			if (dut->ap_cipher == AP_WEP) {
3694 				owrt_ap_set_vap(dut, vap_count, "encryption",
3695 						"wep-mixed");
3696 				owrt_ap_set_vap(dut, vap_count, "key",
3697 						dut->ap_wepkey);
3698 			} else {
3699 				owrt_ap_set_vap(dut, vap_count, "encryption",
3700 						"none");
3701 			}
3702 			if (dut->ap_key_mgmt == AP_OPEN &&
3703 			    dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3704 				/* OWE transition mode */
3705 				snprintf(ifname2, sizeof(ifname2), "%s1",
3706 					 ifname);
3707 				owrt_ap_set_vap(dut, vap_count,
3708 						"owe_transition_ifname",
3709 						ifname2);
3710 			}
3711 			break;
3712 		case AP_WPA2_PSK:
3713 		case AP_WPA2_PSK_MIXED:
3714 		case AP_WPA_PSK:
3715 		case AP_WPA2_SAE:
3716 		case AP_WPA2_PSK_SAE:
3717 			if (dut->ap_key_mgmt == AP_WPA2_PSK ||
3718 			    dut->ap_key_mgmt == AP_WPA2_PSK_SAE) {
3719 				snprintf(buf, sizeof(buf), "psk2");
3720 			} else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) {
3721 				snprintf(buf, sizeof(buf), "psk-mixed");
3722 			} else if (dut->ap_key_mgmt == AP_WPA2_SAE) {
3723 				snprintf(buf, sizeof(buf), "ccmp");
3724 			} else {
3725 				snprintf(buf, sizeof(buf), "psk");
3726 			}
3727 
3728 			if (dut->ap_key_mgmt != AP_WPA2_SAE) {
3729 				if (dut->ap_cipher == AP_CCMP_TKIP)
3730 					strlcat(buf, "+ccmp+tkip", sizeof(buf));
3731 				else if (dut->ap_cipher == AP_TKIP)
3732 					strlcat(buf, "+tkip", sizeof(buf));
3733 				else if (dut->ap_cipher == AP_GCMP_128)
3734 					strlcat(buf, "+gcmp", sizeof(buf));
3735 				else
3736 					strlcat(buf, "+ccmp", sizeof(buf));
3737 			}
3738 
3739 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3740 
3741 			if (!dut->ap_passphrase[0] && dut->ap_psk[0]) {
3742 				snprintf(buf, sizeof(buf), "\"%s\"",
3743 					 dut->ap_psk);
3744 				owrt_ap_set_vap(dut, vap_count, "key", buf);
3745 			} else {
3746 				snprintf(buf, sizeof(buf), "\"%s\"",
3747 					 dut->ap_passphrase);
3748 				owrt_ap_set_vap(dut, vap_count, "key", buf);
3749 			}
3750 
3751 			if (dut->ap_key_mgmt == AP_WPA2_SAE ||
3752 			    dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
3753 				owrt_ap_set_vap(dut, vap_count, "sae", "1");
3754 			else
3755 				owrt_ap_set_vap(dut, vap_count, "sae", "0");
3756 
3757 			if (dut->ap_key_mgmt == AP_WPA2_SAE) {
3758 				snprintf(buf, sizeof(buf), "%s",
3759 					 dut->ap_passphrase);
3760 				owrt_ap_set_vap(dut, vap_count, "sae_password",
3761 						buf);
3762 			} else {
3763 				snprintf(buf, sizeof(buf), "%s",
3764 					 dut->ap_passphrase);
3765 				owrt_ap_set_vap(dut, vap_count,
3766 						"wpa_passphrase", buf);
3767 			}
3768 			break;
3769 		case AP_WPA2_EAP:
3770 		case AP_WPA2_EAP_MIXED:
3771 		case AP_WPA_EAP:
3772 			if (dut->ap_key_mgmt == AP_WPA2_EAP) {
3773 				snprintf(buf, sizeof(buf), "wpa2");
3774 			} else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) {
3775 				snprintf(buf, sizeof(buf), "wpa-mixed");
3776 			} else {
3777 				snprintf(buf, sizeof(buf), "wpa");
3778 			}
3779 
3780 			if (dut->ap_cipher == AP_CCMP_TKIP)
3781 				strlcat(buf, "+ccmp+tkip", sizeof(buf));
3782 			else if (dut->ap_cipher == AP_TKIP)
3783 				strlcat(buf, "+tkip", sizeof(buf));
3784 			else
3785 				strlcat(buf, "+ccmp", sizeof(buf));
3786 
3787 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3788 			snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr);
3789 			owrt_ap_set_vap(dut, vap_count, "auth_server", buf);
3790 			snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port);
3791 			owrt_ap_set_vap(dut, vap_count, "auth_port", buf);
3792 			snprintf(buf, sizeof(buf), "%s",
3793 				 dut->ap_radius_password);
3794 			owrt_ap_set_vap(dut, vap_count, "auth_secret", buf);
3795 			break;
3796 		case AP_WPA2_EAP_OSEN:
3797 		case AP_OSEN:
3798 		case AP_WPA2_FT_EAP:
3799 		case AP_WPA2_FT_PSK:
3800 		case AP_WPA2_EAP_SHA256:
3801 		case AP_WPA2_PSK_SHA256:
3802 		case AP_WPA2_ENT_FT_EAP:
3803 			/* TODO */
3804 			break;
3805 		case AP_SUITEB:
3806 			owrt_ap_set_vap(dut, vap_count, "suite_b", "192");
3807 			snprintf(buf, sizeof(buf), "gcmp");
3808 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3809 			snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr);
3810 			owrt_ap_set_vap(dut, vap_count, "auth_server", buf);
3811 			snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port);
3812 			owrt_ap_set_vap(dut, vap_count, "auth_port", buf);
3813 			snprintf(buf, sizeof(buf), "%s",
3814 				 dut->ap_radius_password);
3815 			owrt_ap_set_vap(dut, vap_count, "auth_secret", buf);
3816 			snprintf(buf, sizeof(buf), "%d",
3817 				 dut->ap_group_mgmt_cipher);
3818 			owrt_ap_set_vap(dut, vap_count, "group_mgmt_cipher",
3819 					buf);
3820 			break;
3821 		case AP_WPA2_OWE:
3822 			owrt_ap_set_vap(dut, vap_count, "owe", "1");
3823 			snprintf(buf, sizeof(buf), "ccmp");
3824 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3825 			if (dut->ap_sae_groups) {
3826 				snprintf(buf, sizeof(buf), "\'%s\'",
3827 					 dut->ap_sae_groups);
3828 				owrt_ap_set_list_vap(dut, vap_count,
3829 						     "owe_groups", buf);
3830 				if (dut->owe_ptk_workaround)
3831 					owrt_ap_set_list_vap(
3832 						dut, vap_count,
3833 						"owe_ptk_workaround", "1");
3834 			}
3835 
3836 			if (dut->ap_key_mgmt == AP_WPA2_OWE &&
3837 			    dut->ap_tag_ssid[0][0] &&
3838 			    dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
3839 				/* OWE transition mode */
3840 				snprintf(ifname2, sizeof(ifname2), "%s1",
3841 					 ifname);
3842 				owrt_ap_set_vap(dut, vap_count,
3843 						"owe_transition_ifname",
3844 						ifname2);
3845 				owrt_ap_set_vap(dut, vap_count, "hidden", "1");
3846 			}
3847 			break;
3848 		}
3849 
3850 		if (!dut->ap_is_dual)
3851 			break;
3852 	}
3853 
3854 	if (dut->ap_is_dual)
3855 		return 1;
3856 
3857 	/* PMF */
3858 	snprintf(buf, sizeof(buf), "%d", dut->ap_pmf);
3859 	owrt_ap_set_vap(dut, vap_id, "ieee80211w", buf);
3860 
3861 	/* Add SHA256 */
3862 	snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha256);
3863 	owrt_ap_set_vap(dut, vap_id, "add_sha256", buf);
3864 
3865 	/* Add SHA384 for akmsuitetype 15 */
3866 	if (dut->ap_akm == 1) {
3867 		snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha384);
3868 		owrt_ap_set_vap(dut, vap_id, "add_sha384", buf);
3869 	}
3870 
3871 	/* Enable RSN preauthentication, if asked to */
3872 	snprintf(buf, sizeof(buf), "%d", dut->ap_rsn_preauth);
3873 	owrt_ap_set_vap(dut, vap_id, "rsn_preauth", buf);
3874 
3875 	/* Hotspot 2.0 */
3876 	if (dut->ap_hs2) {
3877 		int ret;
3878 
3879 		ret = owrt_ap_config_vap_hs2(dut, vap_id);
3880 		if (ret)
3881 			return ret;
3882 	}
3883 
3884 	/* Interworking */
3885 	if (dut->ap_interworking) {
3886 		snprintf(buf, sizeof(buf), "%d", dut->ap_access_net_type);
3887 		owrt_ap_set_vap(dut, vap_id, "access_network_type", buf);
3888 		snprintf(buf, sizeof(buf), "%d", dut->ap_internet);
3889 		owrt_ap_set_vap(dut, vap_id, "internet", buf);
3890 		snprintf(buf, sizeof(buf), "%d", dut->ap_venue_group);
3891 		owrt_ap_set_vap(dut, vap_id, "venue_group", buf);
3892 		snprintf(buf, sizeof(buf), "%d", dut->ap_venue_type);
3893 		owrt_ap_set_vap(dut, vap_id, "venue_type", buf);
3894 		snprintf(buf, sizeof(buf), "%s", dut->ap_hessid);
3895 		owrt_ap_set_vap(dut, vap_id, "hessid", buf);
3896 
3897 		if (dut->ap_gas_cb_delay > 0) {
3898 			snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay);
3899 			owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf);
3900 		}
3901 
3902 		if (dut->ap_roaming_cons[0]) {
3903 			char *rcons, *temp_ptr;
3904 
3905 			rcons = strdup(dut->ap_roaming_cons);
3906 			if (rcons == NULL)
3907 				return -1;
3908 
3909 			temp_ptr = strchr(rcons, ';');
3910 
3911 			if (temp_ptr)
3912 				*temp_ptr++ = '\0';
3913 
3914 			owrt_ap_set_list_vap(dut, vap_id, "roaming_consortium",
3915 					     rcons);
3916 
3917 			if (temp_ptr)
3918 				owrt_ap_set_list_vap(dut, vap_id,
3919 						     "roaming_consortium",
3920 						     temp_ptr);
3921 
3922 			free(rcons);
3923 		}
3924 	}
3925 
3926 	if (dut->ap_venue_name) {
3927 		owrt_ap_set_list_vap(dut, vap_id, "venue_name",
3928 				     "'P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"'");
3929 		owrt_ap_set_list_vap(dut, vap_id, "venue_name",
3930 				     "\'"ANQP_VENUE_NAME_1_CHI"\'");
3931 	}
3932 
3933 	if (dut->ap_net_auth_type == 1) {
3934 		owrt_ap_set_list_vap(dut, vap_id, "network_auth_type",
3935 				     "'00https://tandc-server.wi-fi.org'");
3936 	} else if (dut->ap_net_auth_type == 2) {
3937 		owrt_ap_set_list_vap(dut, vap_id, "network_auth_type", "'01'");
3938 	}
3939 
3940 	if (dut->ap_nai_realm_list == 1) {
3941 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3942 				     "'0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]'");
3943 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3944 				     "'0,wi-fi.org;example.com,13[5:6]'");
3945 
3946 	} else if (dut->ap_nai_realm_list == 2) {
3947 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3948 				     "'0,wi-fi.org,21[2:4][5:7]'");
3949 	} else if (dut->ap_nai_realm_list == 3) {
3950 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3951 				     "'0,cisco.com;wi-fi.org,21[2:4][5:7]'");
3952 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3953 				     "'0,wi-fi.org;example.com,13[5:6]'");
3954 	} else if (dut->ap_nai_realm_list == 4) {
3955 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3956 				     "'0,mail.example.com,21[2:4][5:7],13[5:6]'");
3957 	} else if (dut->ap_nai_realm_list == 5) {
3958 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3959 				     "'0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]'");
3960 	} else if (dut->ap_nai_realm_list == 6) {
3961 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3962 				     "'0,wi-fi.org;mail.example.com,21[2:4][5:7]'");
3963 	} else if (dut->ap_nai_realm_list == 7) {
3964 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3965 				     "'0,wi-fi.org,13[5:6]'");
3966 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3967 				     "'0,wi-fi.org,21[2:4][5:7]'");
3968 	}
3969 
3970 	if (dut->ap_domain_name_list[0])
3971 		owrt_ap_set_list_vap(dut, vap_id, "domain_name",
3972 				     dut->ap_domain_name_list);
3973 
3974 	if (dut->ap_ip_addr_type_avail)
3975 		owrt_ap_set_vap(dut, vap_id, "ipaddr_type_availability",
3976 				"'0c'");
3977 
3978 	temp = buf;
3979 
3980 	*temp++ = '\'';
3981 
3982 	for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) {
3983 		if (i)
3984 			*temp++ = ';';
3985 
3986 		snprintf(temp,
3987 			 sizeof(dut->ap_plmn_mcc[i]) +
3988 			 sizeof(dut->ap_plmn_mnc[i]) + 1,
3989 			 "%s,%s",
3990 			 dut->ap_plmn_mcc[i],
3991 			 dut->ap_plmn_mnc[i]);
3992 
3993 		temp += strlen(dut->ap_plmn_mcc[i]) +
3994 			strlen(dut->ap_plmn_mnc[i]) + 1;
3995 	}
3996 
3997 	*temp++ = '\'';
3998 	*temp++ = '\0';
3999 
4000 	if (i)
4001 		owrt_ap_set_vap(dut, vap_id, "anqp_3gpp_cell_net", buf);
4002 
4003 	if (dut->ap_qos_map_set == 1)
4004 		owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_1);
4005 	else if (dut->ap_qos_map_set == 2)
4006 		owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_2);
4007 
4008 	/* Proxy-ARP */
4009 	snprintf(buf, sizeof(buf), "%d", dut->ap_proxy_arp);
4010 	owrt_ap_set_vap(dut, vap_id, "proxyarp", buf);
4011 
4012 	/* DGAF */
4013 	snprintf(buf, sizeof(buf), "%d", dut->ap_dgaf_disable);
4014 	/* parse to hostapd */
4015 	owrt_ap_set_vap(dut, vap_id, "disable_dgaf", buf);
4016 	/* parse to wifi driver */
4017 	owrt_ap_set_vap(dut, vap_id, "dgaf_disable", buf);
4018 
4019 	/* HCBSSLoad */
4020 	if (dut->ap_bss_load) {
4021 		unsigned int bssload = 0;
4022 
4023 		if (dut->ap_bss_load == 1) {
4024 			/* STA count: 1, CU: 50, AAC: 65535 */
4025 			bssload = 0x0132ffff;
4026 		} else if (dut->ap_bss_load == 2) {
4027 			/* STA count: 1, CU: 200, AAC: 65535 */
4028 			bssload = 0x01c8ffff;
4029 		} else if (dut->ap_bss_load == 3) {
4030 			/* STA count: 1, CU: 75, AAC: 65535 */
4031 			bssload = 0x014bffff;
4032 		}
4033 
4034 		snprintf(buf, sizeof(buf), "%d", bssload);
4035 		owrt_ap_set_vap(dut, vap_id, "hcbssload", buf);
4036 	}
4037 
4038 	/* L2TIF */
4039 	if  (dut->ap_l2tif)
4040 		owrt_ap_set_vap(dut, vap_id, "l2tif", "1");
4041 
4042 	if (dut->ap_disable_protection == 1)
4043 		owrt_ap_set_vap(dut, vap_id, "enablertscts", "0");
4044 
4045 	if (dut->ap_txBF) {
4046 		owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "1");
4047 		owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "1");
4048 		if (dut->program == PROGRAM_HE) {
4049 			owrt_ap_set_vap(dut, vap_id, "he_subfer", "1");
4050 			owrt_ap_set_vap(dut, vap_id, "cwmenable", "0");
4051 		}
4052 	} else {
4053 		owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0");
4054 		owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0");
4055 		if (dut->program == PROGRAM_HE)
4056 			owrt_ap_set_vap(dut, vap_id, "he_subfer", "0");
4057 	}
4058 
4059 	if (dut->ap_mu_txBF) {
4060 		owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "1");
4061 		if (dut->program == PROGRAM_HE) {
4062 			owrt_ap_set_vap(dut, vap_id, "he_mubfer", "1");
4063 			owrt_ap_set_vap(dut, vap_id, "he_mubfee", "1");
4064 		}
4065 	} else {
4066 		owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "0");
4067 		if (dut->program == PROGRAM_HE) {
4068 			owrt_ap_set_vap(dut, vap_id, "he_mubfer", "0");
4069 			owrt_ap_set_vap(dut, vap_id, "he_mubfee", "0");
4070 		}
4071 	}
4072 
4073 	if (dut->ap_tx_stbc) {
4074 		/* STBC and beamforming are mutually exclusive features */
4075 		owrt_ap_set_vap(dut, vap_id, "implicitbf", "0");
4076 	}
4077 
4078 	/* enable dfsmode */
4079 	snprintf(buf, sizeof(buf), "%d", dut->ap_dfs_mode);
4080 	owrt_ap_set_vap(dut, vap_id, "doth", buf);
4081 
4082 	if (dut->program == PROGRAM_LOC && dut->ap_interworking) {
4083 		char anqpval[1024];
4084 
4085 		owrt_ap_set_vap(dut, vap_id, "interworking", "1");
4086 
4087 		if (dut->ap_lci == 1 && strlen(dut->ap_tag_ssid[0]) == 0) {
4088 			snprintf(anqpval, sizeof(anqpval),
4089 				"'265:0010%s%s060101'",
4090 				dut->ap_val_lci, dut->ap_infoz);
4091 			owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4092 		}
4093 
4094 		if (dut->ap_lcr == 1) {
4095 			snprintf(anqpval, sizeof(anqpval),
4096 				"'266:0000b2555302ae%s'",
4097 				dut->ap_val_lcr);
4098 			owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4099 		}
4100 
4101 		if (dut->ap_fqdn_held == 1 && dut->ap_fqdn_supl == 1)
4102 			owrt_ap_set_list_vap(dut, vap_id, "anqp_elem",
4103 					     "'267:00110168656c642e6578616d706c652e636f6d0011027375706c2e6578616d706c652e636f6d'");
4104 	}
4105 
4106 	if (dut->program == PROGRAM_MBO) {
4107 		owrt_ap_set_vap(dut, vap_id, "interworking", "1");
4108 		owrt_ap_set_vap(dut, vap_id, "mbo", "1");
4109 		owrt_ap_set_vap(dut, vap_id, "rrm", "1");
4110 		owrt_ap_set_vap(dut, vap_id, "mbo_cell_conn_pref", "1");
4111 
4112 		owrt_ap_set_list_vap(dut, vap_id, "anqp_elem",
4113 				     "'272:34108cfdf0020df1f7000000733000030101'");
4114 		snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay);
4115 		owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf);
4116 	}
4117 
4118 	if (ap_ft_enabled(dut)) {
4119 		unsigned char self_mac[ETH_ALEN];
4120 		char mac_str[20];
4121 
4122 		owrt_ap_set_vap(dut, vap_id, "ft_over_ds",
4123 				dut->ap_ft_ds == VALUE_ENABLED ? "1" : "0");
4124 		owrt_ap_set_vap(dut, vap_id, "ieee80211r", "1");
4125 		if (get_hwaddr(sigma_radio_ifname[0], self_mac) < 0)
4126 			return -1;
4127 		snprintf(mac_str, sizeof(mac_str),
4128 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4129 			 self_mac[0], self_mac[1], self_mac[2],
4130 			 self_mac[3], self_mac[4], self_mac[5]);
4131 		owrt_ap_set_vap(dut, vap_id, "ap_macaddr", mac_str);
4132 		snprintf(mac_str, sizeof(mac_str),
4133 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4134 			 self_mac[0], self_mac[1], self_mac[2],
4135 			 self_mac[3], self_mac[4], self_mac[5]);
4136 		owrt_ap_set_vap(dut, vap_id, "r1_key_holder", mac_str);
4137 		owrt_ap_set_vap(dut, vap_id, "ft_psk_generate_local", "1");
4138 		owrt_ap_set_vap(dut, vap_id, "kh_key_hex",
4139 				"000102030405060708090a0b0c0d0e0f");
4140 		snprintf(mac_str, sizeof(mac_str),
4141 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4142 			 dut->ft_bss_mac_list[0][0],
4143 			 dut->ft_bss_mac_list[0][1],
4144 			 dut->ft_bss_mac_list[0][2],
4145 			 dut->ft_bss_mac_list[0][3],
4146 			 dut->ft_bss_mac_list[0][4],
4147 			 dut->ft_bss_mac_list[0][5]);
4148 		owrt_ap_set_vap(dut, vap_id, "ap2_macaddr", mac_str);
4149 		owrt_ap_set_vap(dut, vap_id, "mobility_domain",
4150 				dut->ap_mobility_domain);
4151 		owrt_ap_set_vap(dut, vap_id, "ap2_r1_key_holder", mac_str);
4152 	}
4153 
4154 	if ((ap_ft_enabled(dut) && dut->ap_name == 0) ||
4155 	    (ap_ft_enabled(dut) && dut->ap_name == 2)) {
4156 		owrt_ap_set_vap(dut, vap_id, "nasid2", "nas2.example.com");
4157 		owrt_ap_set_vap(dut, vap_id, "nasid", "nas1.example.com");
4158 	}
4159 
4160 	if (ap_ft_enabled(dut) && dut->ap_name == 1) {
4161 		owrt_ap_set_vap(dut, vap_id, "nasid2", "nas1.example.com");
4162 		owrt_ap_set_vap(dut, vap_id, "nasid", "nas2.example.com");
4163 	}
4164 
4165 	if (dut->ap_broadcast_ssid == VALUE_DISABLED)
4166 		owrt_ap_set_vap(dut, vap_id, "hidden", "1");
4167 
4168 	/* Enable/disable PMKSA caching, if asked to */
4169 	if (dut->ap_pmksa == 1) {
4170 		snprintf(buf, sizeof(buf), "%d", dut->ap_pmksa_caching);
4171 		owrt_ap_set_vap(dut, vap_id, "disable_pmksa_caching", buf);
4172 	}
4173 
4174 	if (dut->ap_beacon_prot)
4175 		owrt_ap_set_vap(dut, vap_id, "beacon_prot", "1");
4176 
4177 	if (dut->ap_transition_disable) {
4178 		snprintf(buf, sizeof(buf), "0x%02x",
4179 			 dut->ap_transition_disable);
4180 		owrt_ap_set_vap(dut, vap_id, "transition_disable", buf);
4181 	}
4182 
4183 	if (dut->rsne_override) {
4184 		snprintf(buf, sizeof(buf), "%s", dut->rsne_override);
4185 		owrt_ap_set_vap(dut, vap_count, "own_ie_override", buf);
4186 	}
4187 
4188 	if (dut->rsnxe_override_eapol)
4189 		owrt_ap_set_vap(dut, vap_count, "rsnxe_override_eapol",
4190 				dut->rsnxe_override_eapol);
4191 
4192 	if (dut->sae_commit_override) {
4193 		snprintf(buf, sizeof(buf), "%s", dut->sae_commit_override);
4194 		owrt_ap_set_vap(dut, vap_count, "sae_commit_override", buf);
4195 	}
4196 
4197 	if (dut->ap_sae_groups) {
4198 		snprintf(buf, sizeof(buf), "\'%s\'", dut->ap_sae_groups);
4199 		owrt_ap_set_list_vap(dut, vap_count, "sae_groups", buf);
4200 	}
4201 
4202 	if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) {
4203 		const char *sae_pwe = NULL;
4204 
4205 		if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut))
4206 			sae_pwe = "3";
4207 		else if (dut->sae_pwe == SAE_PWE_LOOP)
4208 			sae_pwe = "0";
4209 		else if (dut->sae_pwe == SAE_PWE_H2E)
4210 			sae_pwe = "1";
4211 		else if (dut->sae_h2e_default)
4212 			sae_pwe = "2";
4213 		if (sae_pwe)
4214 			owrt_ap_set_vap(dut, vap_count, "sae_pwe", sae_pwe);
4215 	}
4216 
4217 	if (dut->sae_anti_clogging_threshold >= 0) {
4218 		snprintf(buf, sizeof(buf), "%d",
4219 			 dut->sae_anti_clogging_threshold);
4220 		owrt_ap_set_vap(dut, vap_count, "sae_anti_clogging_threshold",
4221 				buf);
4222 	}
4223 
4224 	if (dut->sae_reflection)
4225 		owrt_ap_set_vap(dut, vap_count, "sae_reflection_attack", "1");
4226 	if (dut->sae_confirm_immediate)
4227 		owrt_ap_set_vap(dut, vap_count, "sae_confirm_immediate", "2");
4228 
4229 	if (dut->ap_he_dlofdma == VALUE_ENABLED && dut->ap_he_ppdu == PPDU_MU) {
4230 		dut->ap_txBF = 0;
4231 		dut->ap_mu_txBF = 0;
4232 		owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0");
4233 		owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0");
4234 		owrt_ap_set_vap(dut, vap_id, "he_subfer", "0");
4235 	}
4236 
4237 	if (dut->program == PROGRAM_HE &&
4238 	    (dut->ap_txBF || dut->ap_he_ulofdma == VALUE_ENABLED ||
4239 	     dut->ap_he_mimo == MIMO_DL)) {
4240 		switch (dut->ap_chwidth) {
4241 		case AP_20:
4242 			owrt_ap_set_vap(dut, vap_id, "chwidth", "0");
4243 			break;
4244 		case AP_40:
4245 			owrt_ap_set_vap(dut, vap_id, "chwidth", "1");
4246 			break;
4247 		case AP_80:
4248 			owrt_ap_set_vap(dut, vap_id, "chwidth", "2");
4249 			break;
4250 		case AP_160:
4251 			owrt_ap_set_vap(dut, vap_id, "chwidth", "3");
4252 			break;
4253 		case AP_80_80:
4254 			owrt_ap_set_vap(dut, vap_id, "chwidth", "3");
4255 			break;
4256 		case AP_AUTO:
4257 		default:
4258 			break;
4259 		}
4260 	}
4261 
4262 	if (dut->ap_ocvc == 1)
4263 		owrt_ap_set_vap(dut, vap_count, "ocv", "1");
4264 	else if (dut->ap_ocvc == 0)
4265 		owrt_ap_set_vap(dut, vap_count, "ocv", "0");
4266 
4267 	return 1;
4268 }
4269 
4270 
4271 static int owrt_ap_config_vap_anqp(struct sigma_dut *dut)
4272 {
4273 	char anqpval[1024];
4274 	unsigned char addr[6];
4275 	unsigned char addr2[6];
4276 	struct ifreq ifr;
4277 	char *ifname;
4278 	int s;
4279 	int vap_id = 0;
4280 
4281 	s = socket(AF_INET, SOCK_DGRAM, 0);
4282 	if (s < 0) {
4283 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open socket");
4284 		return -1;
4285 	}
4286 
4287 	memset(&ifr, 0, sizeof(ifr));
4288 	ifname = "ath0";
4289 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
4290 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
4291 		perror("ioctl");
4292 		close(s);
4293 		return -1;
4294 	}
4295 	memcpy(addr, ifr.ifr_hwaddr.sa_data, 6);
4296 
4297 	memset(&ifr, 0, sizeof(ifr));
4298 	ifname = "ath01";
4299 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
4300 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
4301 		perror("ioctl");
4302 		close(s);
4303 		return -1;
4304 	}
4305 	close(s);
4306 	memcpy(addr2, ifr.ifr_hwaddr.sa_data, 6);
4307 
4308 	snprintf(anqpval, sizeof(anqpval),
4309 		 "'265:0010%s%s060101070d00%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'",
4310 		 dut->ap_val_lci, dut->ap_infoz,
4311 		 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
4312 		 addr2[0], addr2[1], addr2[2], addr2[3], addr2[4], addr2[5]);
4313 
4314 	owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4315 	return 0;
4316 }
4317 
4318 
4319 static int owrt_ap_post_config_commit(struct sigma_dut *dut,
4320 				      struct sigma_conn *conn,
4321 				      struct sigma_cmd *cmd)
4322 {
4323 	int ap_security = 0;
4324 	int i;
4325 
4326 	for (i = 0; i < MAX_WLAN_TAGS - 1; i++) {
4327 		if (dut->ap_tag_key_mgmt[i] != AP2_OPEN)
4328 			ap_security = 1;
4329 	}
4330 	if (dut->ap_key_mgmt != AP_OPEN)
4331 		ap_security = 1;
4332 	if (ap_security) {
4333 		/* allow some time for hostapd to start before returning
4334 		 * success */
4335 		usleep(500000);
4336 
4337 		if (run_hostapd_cli(dut, "ping") != 0) {
4338 			send_resp(dut, conn, SIGMA_ERROR,
4339 				  "errorCode,Failed to talk to hostapd");
4340 			return 0;
4341 		}
4342 	}
4343 
4344 	if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
4345 		ath_ap_set_params(dut);
4346 
4347 	/* Send response */
4348 	return 1;
4349 }
4350 
4351 
4352 static int cmd_owrt_ap_config_commit(struct sigma_dut *dut,
4353 				     struct sigma_conn *conn,
4354 				     struct sigma_cmd *cmd)
4355 {
4356 	if (dut->program == PROGRAM_DPP &&
4357 	    get_driver_type(dut) == DRIVER_OPENWRT) {
4358 		wpa_command(dut->hostapd_ifname, "DPP_BOOTSTRAP_REMOVE *");
4359 		wpa_command(dut->hostapd_ifname, "DPP_PKEX_REMOVE *");
4360 	}
4361 
4362 	/* Stop the AP */
4363 	run_system(dut, "wifi down");
4364 
4365 	/* Reset the wireless configuration */
4366 	run_system(dut, "rm -rf /etc/config/wireless");
4367 	switch (get_openwrt_driver_type()) {
4368 	case OPENWRT_DRIVER_ATHEROS:
4369 		run_system(dut, "wifi detect qcawifi > /etc/config/wireless");
4370 		break;
4371 	default:
4372 		run_system(dut, "wifi detect > /etc/config/wireless");
4373 		break;
4374 	}
4375 
4376 	/* Configure Radio & VAP, commit the config */
4377 	if (owrt_ap_config_radio(dut) < 0)
4378 		return ERROR_SEND_STATUS;
4379 	if (owrt_ap_config_vap(dut) < 0)
4380 		return ERROR_SEND_STATUS;
4381 	run_system(dut, "uci commit");
4382 
4383 	/* Start AP */
4384 	run_system(dut, "wifi up");
4385 	if (dut->program != PROGRAM_MBO &&
4386 	    dut->ap_lci == 1 && dut->ap_interworking &&
4387 	    strlen(dut->ap_tag_ssid[0]) > 0) {
4388 		/*
4389 		 * MBO has a different ANQP element value which is set in
4390 		 * owrt_ap_config_vap().
4391 		 */
4392 		owrt_ap_config_vap_anqp(dut);
4393 		run_system(dut, "uci commit");
4394 		run_system(dut, "wifi");
4395 	}
4396 
4397 	return owrt_ap_post_config_commit(dut, conn, cmd);
4398 }
4399 
4400 
4401 static void cmd_owrt_ap_hs2_reset(struct sigma_dut *dut)
4402 {
4403 	unsigned char bssid[6];
4404 	char buf[100];
4405 	char *ifname, *radio_name;
4406 	int vap_id = 0;
4407 
4408 	if (sigma_radio_ifname[0] &&
4409 	    strcmp(sigma_radio_ifname[0], "wifi2") == 0) {
4410 		ifname = "ath2";
4411 		radio_name = "wifi2";
4412 		vap_id = 2;
4413 	} else if (sigma_radio_ifname[0] &&
4414 		   strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
4415 		ifname = "ath1";
4416 		radio_name = "wifi1";
4417 		vap_id = 1;
4418 	} else {
4419 		ifname = "ath0";
4420 		radio_name = "wifi0";
4421 		vap_id = 0;
4422 	}
4423 
4424 	if (!get_hwaddr(ifname, bssid)) {
4425 		snprintf(buf, sizeof(buf), "%s", bssid);
4426 		owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4427 		snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4428 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4429 			 bssid[0], bssid[1], bssid[2], bssid[3],
4430 			 bssid[4], bssid[5]);
4431 	} else {
4432 		if (!get_hwaddr(radio_name, bssid)) {
4433 			snprintf(buf, sizeof(buf), "%s", dut->ap_hessid);
4434 			owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4435 			snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4436 				 "%02x:%02x:%02x:%02x:%02x:%02x",
4437 				 bssid[0], bssid[1], bssid[2], bssid[3],
4438 				 bssid[4], bssid[5]);
4439 		} else {
4440 			/* Select & enable/disable radios */
4441 			if (sigma_radio_ifname[0] &&
4442 			    strcmp(sigma_radio_ifname[0], "wifi2") == 0) {
4443 				/* We want to use wifi2 */
4444 				owrt_ap_set_radio(dut, 0, "disabled", "1");
4445 				owrt_ap_set_radio(dut, 1, "disabled", "1");
4446 				owrt_ap_set_radio(dut, 2, "disabled", "0");
4447 				owrt_ap_set_vap(dut, vap_id, "device", "wifi2");
4448 			} else if (sigma_radio_ifname[0] &&
4449 				   strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
4450 				/* We want to use wifi1 */
4451 				owrt_ap_set_radio(dut, 0, "disabled", "1");
4452 				owrt_ap_set_radio(dut, 1, "disabled", "0");
4453 				owrt_ap_set_vap(dut, vap_id, "device", "wifi1");
4454 			} else {
4455 				/* We want to use wifi0 */
4456 				owrt_ap_set_radio(dut, 0, "disabled", "0");
4457 				owrt_ap_set_radio(dut, 1, "disabled", "1");
4458 				owrt_ap_set_vap(dut, vap_id, "device", "wifi0");
4459 			}
4460 
4461 			run_system(dut, "uci commit");
4462 			run_system(dut, "wifi up");
4463 
4464 			if (!get_hwaddr(radio_name, bssid)) {
4465 				snprintf(buf, sizeof(buf), "%s",
4466 					 dut->ap_hessid);
4467 				owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4468 				snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4469 					 "%02x:%02x:%02x:%02x:%02x:%02x",
4470 					 bssid[0], bssid[1], bssid[2], bssid[3],
4471 					 bssid[4], bssid[5]);
4472 			}
4473 		}
4474 	}
4475 }
4476 
4477 
4478 static enum sigma_cmd_result cmd_ap_reboot(struct sigma_dut *dut,
4479 					   struct sigma_conn *conn,
4480 					   struct sigma_cmd *cmd)
4481 {
4482 	switch (get_driver_type(dut)) {
4483 	case DRIVER_ATHEROS:
4484 		run_system(dut, "apdown");
4485 		sleep(1);
4486 		run_system(dut, "reboot");
4487 		break;
4488 	case DRIVER_OPENWRT:
4489 		run_system(dut, "wifi down");
4490 		sleep(1);
4491 		run_system(dut, "reboot");
4492 		break;
4493 	default:
4494 		sigma_dut_print(dut, DUT_MSG_INFO, "Ignore ap_reboot command");
4495 		break;
4496 	}
4497 
4498 	return 1;
4499 }
4500 
4501 
4502 int ascii2hexstr(const char *str, char *hex)
4503 {
4504 	int i, length;
4505 
4506 	length = strlen(str);
4507 
4508 	for (i = 0; i < length; i++)
4509 		snprintf(hex + i * 2, 3, "%X", str[i]);
4510 
4511 	hex[length * 2] = '\0';
4512 	return 1;
4513 }
4514 
4515 
4516 static int kill_process(struct sigma_dut *dut, char *proc_name,
4517 			unsigned char is_proc_instance_one, int sig)
4518 {
4519 #ifdef __linux__
4520 	struct dirent *dp, *dp_in;
4521 	const char *direc = "/proc/";
4522 	char buf[100];
4523 	DIR *dir = opendir(direc);
4524 	DIR *dir_in;
4525 	FILE *fp;
4526 	char *pid, *temp;
4527 	char *saveptr;
4528 	int ret = -1, res;
4529 
4530 	if (dir == NULL)
4531 		return ret;
4532 
4533 	while ((dp = readdir(dir)) != NULL) {
4534 		if (dp->d_type != DT_DIR)
4535 			continue;
4536 
4537 		res = snprintf(buf, sizeof(buf), "%s%s", direc, dp->d_name);
4538 		if (res < 0 || res >= sizeof(buf))
4539 			continue;
4540 		dir_in = opendir(buf);
4541 		if (dir_in == NULL)
4542 			continue;
4543 		dp_in = readdir(dir_in);
4544 		closedir(dir_in);
4545 		if (dp_in == NULL)
4546 			continue;
4547 		res = snprintf(buf, sizeof(buf), "%s%s/stat",
4548 			       direc, dp->d_name);
4549 		if (res < 0 || res >= sizeof(buf))
4550 			continue;
4551 		fp = fopen(buf, "r");
4552 		if (fp == NULL)
4553 			continue;
4554 		if (fgets(buf, 100, fp) == NULL)
4555 			buf[0] = '\0';
4556 		fclose(fp);
4557 		pid = strtok_r(buf, " ", &saveptr);
4558 		temp = strtok_r(NULL, " ", &saveptr);
4559 		if (pid && temp &&
4560 		    strncmp(temp, proc_name, strlen(proc_name)) == 0) {
4561 			sigma_dut_print(dut, DUT_MSG_INFO,
4562 					"killing %s process with PID %s",
4563 					proc_name, pid);
4564 			snprintf(buf, sizeof(buf), "kill -%d %d", sig,
4565 				 atoi(pid));
4566 			run_system(dut, buf);
4567 			ret = 0;
4568 			if (is_proc_instance_one)
4569 				break;
4570 		}
4571 	}
4572 
4573 	closedir(dir);
4574 
4575 	return ret;
4576 #else /* __linux__ */
4577 	return -1;
4578 #endif /* __linux__ */
4579 }
4580 
4581 
4582 static int run_ndc(struct sigma_dut *dut, char *buf)
4583 {
4584 	sigma_dut_print(dut, DUT_MSG_INFO, "CMD NDC:: %s", buf);
4585 	sleep(2);
4586 	return run_system(dut, buf);
4587 }
4588 
4589 
4590 static int sigma_write_cfg(struct sigma_dut *dut, const char *pfile,
4591 			   const char *field, const char *value)
4592 {
4593 	FILE *fcfg, *ftmp;
4594 	char buf[MAX_CONF_LINE_LEN + 1];
4595 	int len, found = 0, res;
4596 
4597 	/* Open the configuration file */
4598 	fcfg = fopen(pfile, "r");
4599 	if (!fcfg) {
4600 		sigma_dut_print(dut, DUT_MSG_ERROR,
4601 				"Failed to open hostapd conf file");
4602 		return -1;
4603 	}
4604 
4605 	snprintf(buf, sizeof(buf), "%s~", pfile);
4606 	/* Open a temporary file */
4607 	ftmp = fopen(buf, "w+");
4608 	if (!ftmp) {
4609 		fclose(fcfg);
4610 		sigma_dut_print(dut, DUT_MSG_ERROR,
4611 				"Failed to open temp buf");
4612 		return -1;
4613 	}
4614 
4615 	/* Read the values from the configuration file */
4616 	len = strlen(field);
4617 	while (fgets(buf, MAX_CONF_LINE_LEN, fcfg)) {
4618 		char *pline = buf;
4619 
4620 		/* commented line */
4621 		if (buf[0] == '#')
4622 			pline++;
4623 
4624 		/* Identify the configuration parameter to be updated */
4625 		if (!found && strncmp(pline, field, len) == 0 &&
4626 		    pline[len] == '=') {
4627 			snprintf(buf, sizeof(buf), "%s=%s\n", field, value);
4628 			found = 1;
4629 			sigma_dut_print(dut, DUT_MSG_INFO,
4630 					"Updated hostapd conf file");
4631 		}
4632 
4633 		fprintf(ftmp, "%s", buf);
4634 	}
4635 
4636 	if (!found) {
4637 		/* Configuration line not found */
4638 		/* Add the new line at the end of file */
4639 		fprintf(ftmp, "%s=%s\n", field, value);
4640 		sigma_dut_print(dut, DUT_MSG_INFO,
4641 				"Adding a new line in hostapd conf file");
4642 	}
4643 
4644 	fclose(fcfg);
4645 	fclose(ftmp);
4646 
4647 	snprintf(buf, sizeof(buf), "%s~", pfile);
4648 
4649 	/* Restore the updated configuration file */
4650 	res = rename(buf, pfile);
4651 
4652 	/* Remove the temporary file. Ignore the return value */
4653 	unlink(buf);
4654 
4655 	/* chmod is needed because open() may not set permissions properly
4656 	 * depending on the current umask */
4657 	if (chmod(pfile, 0660) < 0) {
4658 		unlink(pfile);
4659 		sigma_dut_print(dut, DUT_MSG_ERROR,
4660 				"Error changing permissions");
4661 		return -1;
4662 	}
4663 
4664 	if (res < 0) {
4665 		sigma_dut_print(dut, DUT_MSG_ERROR,
4666 				"Error restoring conf file");
4667 		return -1;
4668 	}
4669 
4670 	return 0;
4671 }
4672 
4673 
4674 static int cmd_wcn_ap_config_commit(struct sigma_dut *dut,
4675 				    struct sigma_conn *conn,
4676 				    struct sigma_cmd *cmd)
4677 {
4678 	char buf[100];
4679 	struct stat s;
4680 	int num_tries = 0, ret;
4681 
4682 	if (kill_process(dut, "(netd)", 1, SIGKILL) == 0 ||
4683 	    system("killall netd") == 0) {
4684 		/* Avoid Error: Error connecting (Connection refused)
4685 		 * Wait some time to allow netd to reinitialize.
4686 		 */
4687 		usleep(1500000);
4688 	}
4689 
4690 	while (num_tries < 10) {
4691 		ret = run_ndc(dut, "ndc softap stopap");
4692 		num_tries++;
4693 		if (WIFEXITED(ret))
4694 			ret = WEXITSTATUS(ret);
4695 		/* On success, NDC exits with 0 */
4696 		if (ret == 0)
4697 			break;
4698 		sigma_dut_print(dut, DUT_MSG_INFO,
4699 				"Try No. %d: ndc softap stopap failed, exit code %d",
4700 				num_tries, ret);
4701 	}
4702 
4703 	if (ret != 0)
4704 		sigma_dut_print(dut, DUT_MSG_ERROR,
4705 				"ndc softap stopap command failed for 10 times - giving up");
4706 
4707 #ifdef ANDROID
4708 	/* Unload/Load driver to cleanup the state of the driver */
4709 	system("rmmod -f wlan");
4710 	usleep(500000);
4711 	system("insmod /system/lib/modules/wlan.ko");
4712 #else /* ANDROID */
4713 	run_ndc(dut, "ndc softap qccmd set enable_softap=0");
4714 	run_ndc(dut, "ndc softap qccmd set enable_softap=1");
4715 #endif /* ANDROID */
4716 
4717 	switch (dut->ap_mode) {
4718 	case AP_11g:
4719 		run_ndc(dut, "ndc softap qccmd set hw_mode=g-only");
4720 		break;
4721 	case AP_11b:
4722 		run_ndc(dut, "ndc softap qccmd set hw_mode=b-only");
4723 		break;
4724 	case AP_11ng:
4725 		run_ndc(dut, "ndc softap qccmd set hw_mode=n");
4726 		break;
4727 	case AP_11a:
4728 		run_ndc(dut, "ndc softap qccmd set hw_mode=a-only");
4729 		break;
4730 	case AP_11na:
4731 		run_ndc(dut, "ndc softap qccmd set hw_mode=n");
4732 		break;
4733 	case AP_11ac:
4734 		run_ndc(dut, "ndc softap qccmd set hw_mode=ac");
4735 		break;
4736 	default:
4737 		break;
4738 	}
4739 
4740 	snprintf(buf, sizeof(buf), "ndc softap qccmd set channel=%d",
4741 		 dut->ap_channel);
4742 	run_ndc(dut, buf);
4743 
4744 	/*
4745 	 * ndc doesn't support double quotes as SSID string, so re-write
4746 	 * hostapd configuration file to update SSID.
4747 	 */
4748 	if (dut->ap_ssid[0] != '\0')
4749 		sigma_write_cfg(dut, ANDROID_CONFIG_FILE, "ssid", dut->ap_ssid);
4750 
4751 	switch (dut->ap_key_mgmt) {
4752 	case AP_OPEN:
4753 		if (dut->ap_cipher == AP_WEP) {
4754 			run_ndc(dut, "ndc softap qccmd set security_mode=1");
4755 			snprintf(buf, sizeof(buf),
4756 				 "ndc softap qccmd set wep_key0=%s",
4757 				 dut->ap_wepkey);
4758 			run_ndc(dut, buf);
4759 		} else {
4760 			run_ndc(dut, "ndc softap qccmd set security_mode=0");
4761 		}
4762 		break;
4763 	case AP_WPA2_PSK:
4764 	case AP_WPA2_PSK_MIXED:
4765 	case AP_WPA_PSK:
4766 		if (dut->ap_key_mgmt == AP_WPA2_PSK)
4767 			run_ndc(dut, "ndc softap qccmd set security_mode=3");
4768 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
4769 			run_ndc(dut, "ndc softap qccmd set security_mode=4");
4770 		else
4771 			run_ndc(dut, "ndc softap qccmd set security_mode=2");
4772 
4773 		/*
4774 		 * ndc doesn't support some special characters as passphrase,
4775 		 * so re-write hostapd configuration file to update Passphrase.
4776 		 */
4777 		if (dut->ap_passphrase[0] != '\0')
4778 			sigma_write_cfg(dut, ANDROID_CONFIG_FILE,
4779 					"wpa_passphrase", dut->ap_passphrase);
4780 
4781 		if (dut->ap_cipher == AP_CCMP_TKIP)
4782 			run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4783 				"TKIP CCMP");
4784 		else if (dut->ap_cipher == AP_TKIP)
4785 			run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4786 				"TKIP");
4787 		else
4788 			run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4789 				"CCMP &");
4790 		break;
4791 	case AP_WPA2_SAE:
4792 	case AP_WPA2_PSK_SAE:
4793 	case AP_WPA2_EAP:
4794 	case AP_WPA2_EAP_MIXED:
4795 	case AP_WPA_EAP:
4796 	case AP_SUITEB:
4797 	case AP_WPA2_OWE:
4798 	case AP_WPA2_EAP_OSEN:
4799 	case AP_OSEN:
4800 	case AP_WPA2_FT_EAP:
4801 	case AP_WPA2_FT_PSK:
4802 	case AP_WPA2_EAP_SHA256:
4803 	case AP_WPA2_PSK_SHA256:
4804 	case AP_WPA2_ENT_FT_EAP:
4805 		/* Not supported */
4806 		break;
4807 	}
4808 
4809 	switch (dut->ap_pmf) {
4810 	case AP_PMF_DISABLED:
4811 		run_ndc(dut, "ndc softap qccmd set ieee80211w=0");
4812 		break;
4813 	case AP_PMF_OPTIONAL:
4814 		run_ndc(dut, "ndc softap qccmd set ieee80211w=1");
4815 		if (dut->ap_add_sha256)
4816 			run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256");
4817 		else
4818 			run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK");
4819 		break;
4820 	case AP_PMF_REQUIRED:
4821 		run_ndc(dut, "ndc softap qccmd set ieee80211w=2");
4822 		run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK-SHA256");
4823 		break;
4824 	}
4825 
4826 	if (dut->ap_countrycode[0]) {
4827 		snprintf(buf, sizeof(buf),
4828 			 "ndc softap qccmd set country_code=%s",
4829 			 dut->ap_countrycode);
4830 		run_ndc(dut, buf);
4831 	}
4832 
4833 	if (dut->ap_regulatory_mode == AP_80211D_MODE_ENABLED)
4834 		run_ndc(dut, "ndc softap qccmd set ieee80211d=1");
4835 
4836 	if (dut->ap_dfs_mode == AP_DFS_MODE_ENABLED)
4837 		run_ndc(dut, "ndc softap qccmd set ieee80211h=1");
4838 
4839 	run_ndc(dut, "ndc softap startap");
4840 
4841 	snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl,
4842 		 get_main_ifname(dut));
4843 	num_tries = 0;
4844 	while (num_tries < 10 && (ret = stat(buf, &s) != 0)) {
4845 		run_ndc(dut, "ndc softap stopap");
4846 		run_ndc(dut, "ndc softap startap");
4847 		num_tries++;
4848 	}
4849 
4850 	if (num_tries == 10) {
4851 		sigma_dut_print(dut, DUT_MSG_INFO, "Tried 10 times with ctrl "
4852 				"iface %s :: reboot the APDUT", buf);
4853 		return ret;
4854 	}
4855 
4856 	sigma_dut_print(dut, DUT_MSG_INFO, "setting ip addr %s mask %s",
4857 			ap_inet_addr, ap_inet_mask);
4858 	snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up",
4859 		 get_main_ifname(dut), ap_inet_addr, ap_inet_mask);
4860 	if (system(buf) != 0) {
4861 		sigma_dut_print(dut, DUT_MSG_ERROR,
4862 				"Failed to intialize the interface");
4863 		return -1;
4864 	}
4865 
4866 	return 1;
4867 }
4868 
4869 
4870 static int append_hostapd_conf_hs2(struct sigma_dut *dut, FILE *f)
4871 {
4872 	fprintf(f, "hs20=1\nhs20_deauth_req_timeout=3\n"
4873 		"disable_dgaf=%d\n", dut->ap_dgaf_disable);
4874 
4875 	if (dut->ap_oper_name) {
4876 		fprintf(f, "hs20_oper_friendly_name=eng:Wi-Fi Alliance\n");
4877 		fprintf(f, "hs20_oper_friendly_name=chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f\n");
4878 	}
4879 
4880 	if (dut->ap_wan_metrics == 1)
4881 		fprintf(f, "hs20_wan_metrics=01:2500:384:0:0:10\n");
4882 	else if (dut->ap_wan_metrics == 2)
4883 		fprintf(f, "hs20_wan_metrics=01:1500:384:20:20:10\n");
4884 	else if (dut->ap_wan_metrics == 3)
4885 		fprintf(f, "hs20_wan_metrics=01:2000:1000:20:20:10\n");
4886 	else if (dut->ap_wan_metrics == 4)
4887 		fprintf(f, "hs20_wan_metrics=01:8000:1000:20:20:10\n");
4888 	else if (dut->ap_wan_metrics == 5)
4889 		fprintf(f, "hs20_wan_metrics=01:9000:5000:20:20:10\n");
4890 
4891 	if (dut->ap_conn_capab == 1) {
4892 		fprintf(f, "hs20_conn_capab=1:0:0\n");
4893 		fprintf(f, "hs20_conn_capab=6:20:1\n");
4894 		fprintf(f, "hs20_conn_capab=6:22:0\n");
4895 		fprintf(f, "hs20_conn_capab=6:80:1\n");
4896 		fprintf(f, "hs20_conn_capab=6:443:1\n");
4897 		fprintf(f, "hs20_conn_capab=6:1723:0\n");
4898 		fprintf(f, "hs20_conn_capab=6:5060:0\n");
4899 		fprintf(f, "hs20_conn_capab=17:500:1\n");
4900 		fprintf(f, "hs20_conn_capab=17:5060:0\n");
4901 		fprintf(f, "hs20_conn_capab=17:4500:1\n");
4902 		fprintf(f, "hs20_conn_capab=50:0:1\n");
4903 	} else if (dut->ap_conn_capab == 2) {
4904 		fprintf(f, "hs20_conn_capab=6:80:1\n");
4905 		fprintf(f, "hs20_conn_capab=6:443:1\n");
4906 		fprintf(f, "hs20_conn_capab=17:5060:1\n");
4907 		fprintf(f, "hs20_conn_capab=6:5060:1\n");
4908 	} else if (dut->ap_conn_capab == 3) {
4909 		fprintf(f, "hs20_conn_capab=6:80:1\n");
4910 		fprintf(f, "hs20_conn_capab=6:443:1\n");
4911 	} else if (dut->ap_conn_capab == 4) {
4912 		fprintf(f, "hs20_conn_capab=6:80:1\n");
4913 		fprintf(f, "hs20_conn_capab=6:443:1\n");
4914 		fprintf(f, "hs20_conn_capab=6:5060:1\n");
4915 		fprintf(f, "hs20_conn_capab=17:5060:1\n");
4916 	}
4917 
4918 	if (dut->ap_oper_class == 1)
4919 		fprintf(f, "hs20_operating_class=51\n");
4920 	else if (dut->ap_oper_class == 2)
4921 		fprintf(f, "hs20_operating_class=73\n");
4922 	else if (dut->ap_oper_class == 3)
4923 		fprintf(f, "hs20_operating_class=5173\n");
4924 
4925 	if (dut->ap_osu_provider_list) {
4926 		char *osu_friendly_name = NULL;
4927 		char *osu_icon = NULL;
4928 		char *osu_ssid = NULL;
4929 		char *osu_nai = NULL;
4930 		char *osu_nai2 = NULL;
4931 		char *osu_service_desc = NULL;
4932 		char *hs20_icon_filename = NULL;
4933 		char hs20_icon[150];
4934 		int osu_method;
4935 
4936 		hs20_icon_filename = "icon_red_zxx.png";
4937 		if (dut->ap_osu_icon_tag == 2)
4938 			hs20_icon_filename = "wifi-abgn-logo_270x73.png";
4939 		snprintf(hs20_icon, sizeof(hs20_icon),
4940 			 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s",
4941 			 hs20_icon_filename);
4942 		osu_icon = "icon_red_zxx.png";
4943 		osu_ssid = "OSU";
4944 		osu_friendly_name = "kor:SP 빨강 테스트 전용";
4945 		osu_service_desc = "kor:테스트 목적으로 무료 서비스";
4946 		osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0];
4947 
4948 		if (strlen(dut->ap_osu_server_uri[0]))
4949 			fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[0]);
4950 		else
4951 			fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
4952 
4953 		switch (dut->ap_osu_provider_list) {
4954 		case 1:
4955 		case 101:
4956 			fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
4957 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
4958 			hs20_icon_filename = "icon_red_eng.png";
4959 			if (dut->ap_osu_icon_tag == 2)
4960 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
4961 			fprintf(f, "hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s\n",
4962 				hs20_icon_filename);
4963 			fprintf(f, "osu_icon=icon_red_eng.png\n");
4964 			break;
4965 		case 2:
4966 		case 102:
4967 			fprintf(f, "osu_friendly_name=eng:Wireless Broadband Alliance\n");
4968 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
4969 			hs20_icon_filename = "icon_orange_zxx.png";
4970 			if (dut->ap_osu_icon_tag == 2)
4971 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
4972 			snprintf(hs20_icon, sizeof(hs20_icon),
4973 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
4974 				 hs20_icon_filename);
4975 			osu_icon = "icon_orange_zxx.png";
4976 			osu_friendly_name = "kor:와이어리스 브로드밴드 얼라이언스";
4977 			break;
4978 		case 3:
4979 		case 103:
4980 			osu_friendly_name = "spa:SP Red Test Only";
4981 			osu_service_desc = "spa:Free service for test purpose";
4982 			break;
4983 		case 4:
4984 		case 104:
4985 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
4986 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
4987 			hs20_icon_filename = "icon_orange_eng.png";
4988 			if (dut->ap_osu_icon_tag == 2)
4989 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
4990 			fprintf(f, "hs20_icon=160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s\n",
4991 				hs20_icon_filename);
4992 			fprintf(f, "osu_icon=icon_orange_eng.png\n");
4993 			osu_friendly_name = "kor:SP 오렌지 테스트 전용";
4994 
4995 			hs20_icon_filename = "icon_orange_zxx.png";
4996 			if (dut->ap_osu_icon_tag == 2)
4997 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
4998 			snprintf(hs20_icon, sizeof(hs20_icon),
4999 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5000 				 hs20_icon_filename);
5001 			osu_icon = "icon_orange_zxx.png";
5002 			break;
5003 		case 5:
5004 		case 105:
5005 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5006 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5007 			osu_friendly_name = "kor:SP 오렌지 테스트 전용";
5008 			hs20_icon_filename = "icon_orange_zxx.png";
5009 			if (dut->ap_osu_icon_tag == 2)
5010 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5011 			snprintf(hs20_icon, sizeof(hs20_icon),
5012 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5013 				 hs20_icon_filename);
5014 			osu_icon = "icon_orange_zxx.png";
5015 			break;
5016 		case 6:
5017 		case 106:
5018 			fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n");
5019 			fprintf(f, "osu_friendly_name=kor:SP 초록 테스트 전용\n");
5020 			hs20_icon_filename = "icon_green_zxx.png";
5021 			if (dut->ap_osu_icon_tag == 2)
5022 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5023 			fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s\n",
5024 				hs20_icon_filename);
5025 			fprintf(f, "osu_icon=icon_green_zxx.png\n");
5026 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 : dut->ap_osu_method[0];
5027 			fprintf(f, "osu_method_list=%d\n", osu_method);
5028 
5029 			if (strlen(dut->ap_osu_server_uri[1]))
5030 				fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]);
5031 			else
5032 				fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
5033 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5034 			hs20_icon_filename = "icon_orange_zxx.png";
5035 			if (dut->ap_osu_icon_tag == 2)
5036 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5037 			snprintf(hs20_icon, sizeof(hs20_icon),
5038 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5039 				 hs20_icon_filename);
5040 			osu_icon = "icon_orange_zxx.png";
5041 			osu_friendly_name = "kor:SP 오렌지 테스트 전용";
5042 			osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 : dut->ap_osu_method[1];
5043 			osu_service_desc = NULL;
5044 			break;
5045 		case 7:
5046 		case 107:
5047 			fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n");
5048 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5049 			hs20_icon_filename = "icon_green_eng.png";
5050 			if (dut->ap_osu_icon_tag == 2)
5051 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5052 			fprintf(f, "hs20_icon=160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s\n",
5053 				hs20_icon_filename);
5054 			fprintf(f, "osu_icon=icon_green_eng.png\n");
5055 			osu_friendly_name = "kor:SP 초록 테스트 전용";
5056 
5057 			hs20_icon_filename = "icon_green_zxx.png";
5058 			if (dut->ap_osu_icon_tag == 2)
5059 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5060 			snprintf(hs20_icon, sizeof(hs20_icon),
5061 				 "128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s",
5062 				 hs20_icon_filename);
5063 			osu_icon = "icon_green_zxx.png";
5064 			break;
5065 		case 8:
5066 		case 108:
5067 			fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
5068 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5069 			osu_ssid = "OSU-Encrypted";
5070 			osu_nai = "anonymous@hotspot.net";
5071 			break;
5072 		case 9:
5073 		case 109:
5074 			osu_ssid = "OSU-OSEN";
5075 			osu_nai = "test-anonymous@wi-fi.org";
5076 			osu_friendly_name = "eng:SP Orange Test Only";
5077 			hs20_icon_filename = "icon_orange_zxx.png";
5078 			if (dut->ap_osu_icon_tag == 2)
5079 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5080 			snprintf(hs20_icon, sizeof(hs20_icon),
5081 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5082 				 hs20_icon_filename);
5083 			osu_icon = "icon_orange_zxx.png";
5084 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0];
5085 			osu_service_desc = NULL;
5086 			break;
5087 		case 10:
5088 		case 110:
5089 			/* OSU Provider #1 */
5090 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5091 			fprintf(f, "osu_friendly_name=kor:SP 오렌지 테스트 전용\n");
5092 			fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/icon_orange_zxx.png\n");
5093 			fprintf(f, "osu_icon=icon_orange_zxx.png\n");
5094 			osu_method = (dut->ap_osu_method[0] == 0xFF) ?
5095 				1 : dut->ap_osu_method[0];
5096 			fprintf(f, "osu_method_list=%d\n", osu_method);
5097 			fprintf(f, "osu_nai=test-anonymous@wi-fi.org\n");
5098 			switch (dut->ap_osu_provider_nai_list) {
5099 			case 3:
5100 				fprintf(f,
5101 					"osu_nai2=test-anonymous@wi-fi.org\n");
5102 				break;
5103 			case 4:
5104 				fprintf(f, "osu_nai2=random@hotspot.net\n");
5105 				break;
5106 			}
5107 
5108 			/* OSU Provider #2 */
5109 			/* SP Red from defaults */
5110 			if (strlen(dut->ap_osu_server_uri[1]))
5111 				fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]);
5112 			else
5113 				fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
5114 			fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
5115 			snprintf(hs20_icon, sizeof(hs20_icon),
5116 				 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/icon_red_zxx.png");
5117 			osu_method = (dut->ap_osu_method[1] == 0xFF) ?
5118 				1 : dut->ap_osu_method[1];
5119 			osu_service_desc = NULL;
5120 			osu_nai = "anonymous@hotspot.net";
5121 			break;
5122 		default:
5123 			break;
5124 		}
5125 
5126 		switch (dut->ap_osu_provider_nai_list) {
5127 		case 1:
5128 			osu_nai2 = "anonymous@hotspot.net";
5129 			break;
5130 		case 2:
5131 			osu_nai2 = "test-anonymous@wi-fi.org";
5132 			break;
5133 		case 3:
5134 			/* OSU Provider NAI #1 written above */
5135 			/* OSU Provider NAI #2 */
5136 			osu_nai2 = "anonymous@hotspot.net";
5137 			break;
5138 		case 4:
5139 			/* OSU Provider NAI #1 written above */
5140 			/* OSU Provider NAI #2 */
5141 			osu_nai2 = "anonymous@hotspot.net";
5142 			break;
5143 		}
5144 
5145 		if (strlen(dut->ap_osu_ssid)) {
5146 			if (dut->ap_tag_ssid[0][0] &&
5147 			    strcmp(dut->ap_tag_ssid[0], dut->ap_osu_ssid) &&
5148 			    strcmp(dut->ap_tag_ssid[0], osu_ssid)) {
5149 				sigma_dut_print(dut, DUT_MSG_ERROR,
5150 						"OSU_SSID and "
5151 						"WLAN_TAG2 SSID differ");
5152 				return -2;
5153 			}
5154 			fprintf(f, "osu_ssid=\"%s\"\n", dut->ap_osu_ssid);
5155 		} else
5156 			fprintf(f, "osu_ssid=\"%s\"\n", osu_ssid);
5157 
5158 
5159 		if (osu_friendly_name)
5160 			fprintf(f, "osu_friendly_name=%s\n", osu_friendly_name);
5161 
5162 		if (osu_service_desc)
5163 			fprintf(f, "osu_service_desc=%s\n", osu_service_desc);
5164 
5165 		if (osu_nai)
5166 			fprintf(f, "osu_nai=%s\n", osu_nai);
5167 		if (osu_nai2)
5168 			fprintf(f, "osu_nai2=%s\n", osu_nai2);
5169 
5170 		fprintf(f, "hs20_icon=%s\n", hs20_icon);
5171 
5172 		if (osu_icon)
5173 			fprintf(f, "osu_icon=%s\n", osu_icon);
5174 
5175 		if (dut->ap_osu_provider_list > 100)
5176 			fprintf(f, "osu_method_list=0\n");
5177 		else
5178 			fprintf(f, "osu_method_list=%d\n", osu_method);
5179 	}
5180 
5181 	switch (dut->ap_venue_url) {
5182 	case 1:
5183 		fprintf(f,
5184 			"venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5185 			"venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/directory/index.html\n");
5186 		break;
5187 	case 2:
5188 		fprintf(f,
5189 			"venue_url=1:https://the-great-mall.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5190 			"venue_url=2:https://abercrombie.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5191 			"venue_url=3:https://adidas.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5192 			"venue_url=4:https://aeropostale.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5193 			"venue_url=5:https://agaci.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5194 			"venue_url=6:https://aldo-shoes.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5195 			"venue_url=7:https://american-eagle-outfitters.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5196 			"venue_url=8:https://anderson-bakery.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5197 			"venue_url=9:https://banana-republic-factory-store.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5198 			"venue_url=10:https://bed-bath-and-beyond.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5199 			);
5200 		break;
5201 	}
5202 
5203 	switch (dut->ap_advice_of_charge) {
5204 	case 1:
5205 		fprintf(f, "anqp_elem=278:" ADV_OF_CHARGE_1 "\n");
5206 		break;
5207 	}
5208 
5209 	switch (dut->ap_oper_icon_metadata) {
5210 	case 1:
5211 		fprintf(f,
5212 			"hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/icon_red_eng.png\n"
5213 			"operator_icon=icon_red_eng.png\n");
5214 		break;
5215 	}
5216 
5217 	switch (dut->ap_tnc_file_name) {
5218 	case 1:
5219 		fprintf(f, "hs20_t_c_filename=tandc-id1-content.txt\n");
5220 		break;
5221 	}
5222 
5223 	if (dut->ap_tnc_time_stamp)
5224 		fprintf(f, "hs20_t_c_timestamp=%u\n", dut->ap_tnc_time_stamp);
5225 
5226 	return 0;
5227 }
5228 
5229 
5230 static void write_ap_roaming_cons(FILE *f, const char *list)
5231 {
5232 	char *buf, *pos, *end;
5233 
5234 	if (list == NULL || list[0] == '\0')
5235 		return;
5236 
5237 	buf = strdup(list);
5238 	if (buf == NULL)
5239 		return;
5240 
5241 	pos = buf;
5242 	while (pos && *pos) {
5243 		end = strchr(pos, ';');
5244 		if (end)
5245 			*end++ = '\0';
5246 		fprintf(f, "roaming_consortium=%s\n", pos);
5247 		pos = end;
5248 	}
5249 
5250 	free(buf);
5251 }
5252 
5253 
5254 static int append_hostapd_conf_interworking(struct sigma_dut *dut, FILE *f)
5255 {
5256 	int i;
5257 	char buf[100], *temp;
5258 
5259 	if (dut->ap_gas_cb_delay > 0)
5260 		fprintf(f, "gas_comeback_delay=%d\n",
5261 			dut->ap_gas_cb_delay);
5262 
5263 	fprintf(f, "interworking=1\n"
5264 		"access_network_type=%d\n"
5265 		"internet=%d\n"
5266 		"asra=0\n"
5267 		"esr=0\n"
5268 		"uesa=0\n"
5269 		"venue_group=%d\n"
5270 		"venue_type=%d\n",
5271 		dut->ap_access_net_type,
5272 		dut->ap_internet,
5273 		dut->ap_venue_group,
5274 		dut->ap_venue_type);
5275 	if (dut->ap_hessid[0])
5276 		fprintf(f, "hessid=%s\n", dut->ap_hessid);
5277 
5278 	write_ap_roaming_cons(f, dut->ap_roaming_cons);
5279 
5280 	if (dut->ap_venue_name) {
5281 		fprintf(f, "venue_name=P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"\n");
5282 		fprintf(f, "venue_name=%s\n", ANQP_VENUE_NAME_1_CHI);
5283 	}
5284 
5285 	if (dut->ap_net_auth_type == 1)
5286 		fprintf(f, "network_auth_type=00https://tandc-server.wi-fi.org\n");
5287 	else if (dut->ap_net_auth_type == 2)
5288 		fprintf(f, "network_auth_type=01\n");
5289 
5290 	if (dut->ap_nai_realm_list == 1) {
5291 		fprintf(f, "nai_realm=0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]\n");
5292 		fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n");
5293 	} else if (dut->ap_nai_realm_list == 2) {
5294 		fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n");
5295 	} else if (dut->ap_nai_realm_list == 3) {
5296 		fprintf(f, "nai_realm=0,cisco.com;wi-fi.org,21[2:4][5:7]\n");
5297 		fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n");
5298 	} else if (dut->ap_nai_realm_list == 4) {
5299 		fprintf(f, "nai_realm=0,mail.example.com,21[2:4][5:7],13[5:6]\n");
5300 	} else if (dut->ap_nai_realm_list == 5) {
5301 		fprintf(f, "nai_realm=0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]\n");
5302 	} else if (dut->ap_nai_realm_list == 6) {
5303 		fprintf(f, "nai_realm=0,wi-fi.org;mail.example.com,21[2:4][5:7]\n");
5304 	} else if (dut->ap_nai_realm_list == 7) {
5305 		fprintf(f, "nai_realm=0,wi-fi.org,13[5:6]\n");
5306 		fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n");
5307 	}
5308 
5309 	if (dut->ap_domain_name_list[0]) {
5310 		fprintf(f, "domain_name=%s\n",
5311 			dut->ap_domain_name_list);
5312 	}
5313 
5314 	if (dut->ap_ip_addr_type_avail == 1) {
5315 		fprintf(f, "ipaddr_type_availability=0c\n");
5316 	}
5317 
5318 	temp = buf;
5319 	for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0];
5320 	     i++) {
5321 		if (i)
5322 			*temp++ = ';';
5323 
5324 		snprintf(temp,
5325 			 sizeof(dut->ap_plmn_mcc[i]) +
5326 			 sizeof(dut->ap_plmn_mnc[i]) + 1,
5327 			 "%s,%s",
5328 			 dut->ap_plmn_mcc[i],
5329 			 dut->ap_plmn_mnc[i]);
5330 
5331 		temp += strlen(dut->ap_plmn_mcc[i]) +
5332 			strlen(dut->ap_plmn_mnc[i]) + 1;
5333 	}
5334 	if (i)
5335 		fprintf(f, "anqp_3gpp_cell_net=%s\n", buf);
5336 
5337 	if (dut->ap_qos_map_set == 1)
5338 		fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_1);
5339 	else if (dut->ap_qos_map_set == 2)
5340 		fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_2);
5341 
5342 	return 0;
5343 }
5344 
5345 
5346 static int ath_ap_append_hostapd_conf(struct sigma_dut *dut)
5347 {
5348 	FILE *f;
5349 
5350 	if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
5351 	    system("killall hostapd") == 0) {
5352 		int i;
5353 
5354 		/* Wait some time to allow hostapd to complete cleanup before
5355 		 * starting a new process */
5356 		for (i = 0; i < 10; i++) {
5357 			usleep(500000);
5358 			if (system("pidof hostapd") != 0)
5359 				break;
5360 		}
5361 	}
5362 
5363 	f = fopen("/tmp/secath0", "a");
5364 	if (f == NULL)
5365 		return -2;
5366 
5367 	if (dut->ap_hs2 && append_hostapd_conf_hs2(dut, f)) {
5368 		fclose(f);
5369 		return -2;
5370 	}
5371 
5372 	if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) {
5373 		fclose(f);
5374 		return -2;
5375 	}
5376 
5377 	fflush(f);
5378 	fclose(f);
5379 	return ath_ap_start_hostapd(dut);
5380 }
5381 
5382 
5383 static int ath_ap_start_hostapd(struct sigma_dut *dut)
5384 {
5385 	if (dut->ap_tag_key_mgmt[0] == AP2_OSEN)
5386 		run_system(dut, "hostapd -B /tmp/secath0 /tmp/secath1 -e /etc/wpa2/entropy");
5387 	else
5388 		run_system(dut, "hostapd -B /tmp/secath0 -e /etc/wpa2/entropy");
5389 
5390 	return 0;
5391 }
5392 
5393 
5394 #define LE16(a) ((((a) & 0xff) << 8) | (((a) >> 8) & 0xff))
5395 
5396 static int cmd_ath_ap_anqpserver_start(struct sigma_dut *dut)
5397 {
5398 	FILE *f;
5399 	int nai_realm = 0, domain_name = 0, oper_name = 0, venue_name = 0,
5400 		wan_metrics = 0, conn_cap = 0, ipaddr_avail = 0, cell_net = 0;
5401 	char buf[100];
5402 	int i;
5403 
5404 	f = fopen("/root/anqpserver.conf", "w");
5405 	if (f == NULL)
5406 		return -1;
5407 
5408 	if (dut->ap_nai_realm_list == 1) {
5409 		nai_realm = 1;
5410 		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");
5411 	} else if (dut->ap_nai_realm_list == 2) {
5412 		nai_realm = 1;
5413 		fprintf(f, "dyn_nai_home_realm=encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
5414 	} else if (dut->ap_nai_realm_list == 3) {
5415 		nai_realm = 1;
5416 		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");
5417 	} else if (dut->ap_nai_realm_list == 4) {
5418 		nai_realm = 1;
5419 		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");
5420 	} else
5421 		sigma_dut_print(dut, DUT_MSG_INFO, "not setting nai_realm");
5422 
5423 	if (dut->ap_domain_name_list[0]) {
5424 		char *next, *start, *dnbuf, *dn1, *anqp_dn;
5425 		int len, dn_len_max;
5426 		dnbuf = strdup(dut->ap_domain_name_list);
5427 		if (dnbuf == NULL) {
5428 			fclose(f);
5429 			return 0;
5430 		}
5431 
5432 		len = strlen(dnbuf);
5433 		dn_len_max = 50 + len*2;
5434 		anqp_dn = malloc(dn_len_max);
5435 		if (anqp_dn == NULL) {
5436 			free(dnbuf);
5437 			fclose(f);
5438 			return -1;
5439 		}
5440 		start = dnbuf;
5441 		dn1 = anqp_dn;
5442 		while (start && *start) {
5443 			char *hexstr;
5444 
5445 			next = strchr(start, ',');
5446 			if (next)
5447 				*next++ = '\0';
5448 
5449 			len = strlen(start);
5450 			hexstr = malloc(len * 2 + 1);
5451 			if (hexstr == NULL) {
5452 				free(dnbuf);
5453 				free(anqp_dn);
5454 				fclose(f);
5455 				return -1;
5456 			}
5457 			ascii2hexstr(start, hexstr);
5458 			snprintf(dn1, dn_len_max, "%02x%s", len, hexstr);
5459 			free(hexstr);
5460 			dn1 += 2 + len * 2;
5461 			dn_len_max -= 2 + len * 2;
5462 			start = next;
5463 		}
5464 		free(dnbuf);
5465 		if (dut->ap_gas_cb_delay) {
5466 			fprintf(f, "dyn_domain_name=0c01%04x%s",
5467 				LE16((unsigned int) strlen(anqp_dn)), anqp_dn);
5468 			domain_name = 1;
5469 		} else
5470 			fprintf(f, "domain_name=0c01%04x%s",
5471 				LE16((unsigned int) strlen(anqp_dn)), anqp_dn);
5472 		free(anqp_dn);
5473 	} else
5474 		sigma_dut_print(dut, DUT_MSG_INFO, "not setting domain_name");
5475 
5476 	sigma_dut_print(dut, DUT_MSG_INFO, "not setting roaming_consortium");
5477 
5478 	if (dut->ap_oper_name) {
5479 		if (dut->ap_gas_cb_delay) {
5480 			fprintf(f, "dyn_oper_friendly_name="
5481 				ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n");
5482 			oper_name = 1;
5483 		} else
5484 			fprintf(f, "oper_friendly_name="
5485 				ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n");
5486 	} else
5487 		sigma_dut_print(dut, DUT_MSG_INFO, "not setting oper_name");
5488 
5489 	if (dut->ap_venue_name) {
5490 		if (dut->ap_gas_cb_delay) {
5491 			fprintf(f, "dyn_venue_name=" ANQP_VENUE_NAME_1 "\n");
5492 			venue_name = 1;
5493 		} else
5494 			fprintf(f, "venue_name=" ANQP_VENUE_NAME_1 "\n");
5495 	} else
5496 		sigma_dut_print(dut, DUT_MSG_ERROR, "not setting venue_name");
5497 
5498 	if (dut->ap_wan_metrics) {
5499 		if (dut->ap_gas_cb_delay) {
5500 			fprintf(f, "dyn_wan_metrics=" ANQP_HS20_WAN_METRICS_1 "\n");
5501 			wan_metrics = 1;
5502 		} else
5503 			fprintf(f, "wan_metrics=" ANQP_HS20_WAN_METRICS_1
5504 				"\n");
5505 	} else
5506 		sigma_dut_print(dut, DUT_MSG_ERROR, "not setting wan_metrics");
5507 
5508 	if (dut->ap_conn_capab) {
5509 		if (dut->ap_gas_cb_delay) {
5510 			fprintf(f, "dyn_conn_capability="
5511 				ANQP_HS20_CONNECTION_CAPABILITY_1 "\n");
5512 			conn_cap = 1;
5513 		} else
5514 			fprintf(f, "conn_capability="
5515 				ANQP_HS20_CONNECTION_CAPABILITY_1 "\n");
5516 	} else
5517 		sigma_dut_print(dut, DUT_MSG_ERROR,
5518 				"not setting conn_capability");
5519 
5520 	if (dut->ap_ip_addr_type_avail) {
5521 		if (dut->ap_gas_cb_delay) {
5522 			fprintf(f, "dyn_ipaddr_type=" ANQP_IP_ADDR_TYPE_1
5523 				"\n");
5524 			ipaddr_avail = 1;
5525 		} else
5526 			fprintf(f, "ipaddr_type=" ANQP_IP_ADDR_TYPE_1 "\n");
5527 	} else
5528 		sigma_dut_print(dut, DUT_MSG_ERROR,
5529 				"not setting ipaddr_type_avail");
5530 
5531 	for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) {
5532 		snprintf(buf + i * 6, sizeof(buf) - i * 6, "%c%c%c%c%c%c",
5533 			 dut->ap_plmn_mcc[i][1],
5534 			 dut->ap_plmn_mcc[i][0],
5535 			 dut->ap_plmn_mnc[i][2] == '\0' ?
5536 			 'f' : dut->ap_plmn_mnc[i][2],
5537 			 dut->ap_plmn_mcc[i][2],
5538 			 dut->ap_plmn_mnc[i][1],
5539 			 dut->ap_plmn_mnc[i][0]);
5540 	}
5541 	if (i) {
5542 		uint16_t ie_len = (i * 3) + 5;
5543 		if (dut->ap_gas_cb_delay) {
5544 			fprintf(f, "dyn_cell_net=0801");
5545 			cell_net = 1;
5546 		} else
5547 			fprintf(f, "cell_net=0801");
5548 		fprintf(f, "%04x", LE16(ie_len));
5549 		fprintf(f, "00");                /* version */
5550 		fprintf(f, "%02x", (i * 3) + 3); /* user data hdr length */
5551 		fprintf(f, "00");                /* plmn list */
5552 		fprintf(f, "%02x", (i * 3) + 1); /* length of plmn list */
5553 		fprintf(f, "%02x", i);           /* number of plmns */
5554 		fprintf(f, "%s\n", buf);           /* plmns */
5555 	} else
5556 		sigma_dut_print(dut, DUT_MSG_ERROR,
5557 				"not setting 3gpp_cellular_network");
5558 
5559 	if (nai_realm || domain_name || oper_name || venue_name ||
5560 		wan_metrics || conn_cap || ipaddr_avail || cell_net) {
5561 		fprintf(f, "anqp_attach=");
5562 		if (venue_name)
5563 			fprintf(f, "00000104%4.4x", dut->ap_gas_cb_delay);
5564 		if (nai_realm)
5565 			fprintf(f, "00000107%4.4x", dut->ap_gas_cb_delay);
5566 		if (cell_net)
5567 			fprintf(f, "00000108%4.4x", dut->ap_gas_cb_delay);
5568 		if (domain_name)
5569 			fprintf(f, "0000010c%4.4x", dut->ap_gas_cb_delay);
5570 		if (oper_name)
5571 			fprintf(f, "00010003%4.4x", dut->ap_gas_cb_delay);
5572 		if (wan_metrics)
5573 			fprintf(f, "00010004%4.4x", dut->ap_gas_cb_delay);
5574 		if (conn_cap)
5575 			fprintf(f, "00010005%4.4x", dut->ap_gas_cb_delay);
5576 		fprintf(f, "00010006%4.4x", dut->ap_gas_cb_delay);
5577 		fprintf(f, "\n");
5578 	}
5579 
5580 	fclose(f);
5581 
5582 	run_system(dut, "anqpserver -i ath0 &");
5583 	if (!dut->ap_anqpserver_on)
5584 		run_system(dut, "killall anqpserver");
5585 
5586 	return 1;
5587 }
5588 
5589 
5590 static void cmd_ath_ap_radio_config(struct sigma_dut *dut)
5591 {
5592 	char buf[100];
5593 
5594 	run_system(dut, "cfg -a AP_STARTMODE=standard");
5595 
5596 	if (sigma_radio_ifname[0] &&
5597 	    strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
5598 		run_system(dut, "cfg -a AP_RADIO_ID=1");
5599 		switch (dut->ap_mode) {
5600 		case AP_11g:
5601 			run_system(dut, "cfg -a AP_CHMODE_2=11G");
5602 			break;
5603 		case AP_11b:
5604 			run_system(dut, "cfg -a AP_CHMODE_2=11B");
5605 			break;
5606 		case AP_11ng:
5607 			run_system(dut, "cfg -a AP_CHMODE_2=11NGHT20");
5608 			break;
5609 		case AP_11a:
5610 			run_system(dut, "cfg -a AP_CHMODE_2=11A");
5611 			break;
5612 		case AP_11na:
5613 			run_system(dut, "cfg -a AP_CHMODE_2=11NAHT20");
5614 			break;
5615 		case AP_11ac:
5616 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5617 			break;
5618 		default:
5619 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5620 			break;
5621 		}
5622 
5623 		switch (dut->ap_rx_streams) {
5624 		case 1:
5625 			run_system(dut, "cfg -a RX_CHAINMASK_2=1");
5626 			break;
5627 		case 2:
5628 			run_system(dut, "cfg -a RX_CHAINMASK_2=3");
5629 			break;
5630 		case 3:
5631 			run_system(dut, "cfg -a RX_CHAINMASK_2=7");
5632 			break;
5633 		}
5634 
5635 		switch (dut->ap_tx_streams) {
5636 		case 1:
5637 			run_system(dut, "cfg -a TX_CHAINMASK_2=1");
5638 			break;
5639 		case 2:
5640 			run_system(dut, "cfg -a TX_CHAINMASK_2=3");
5641 			break;
5642 		case 3:
5643 			run_system(dut, "cfg -a TX_CHAINMASK_2=7");
5644 			break;
5645 		}
5646 
5647 		switch (dut->ap_chwidth) {
5648 		case AP_20:
5649 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT20");
5650 			break;
5651 		case AP_40:
5652 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT40");
5653 			break;
5654 		case AP_80:
5655 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5656 			break;
5657 		case AP_160:
5658 		case AP_AUTO:
5659 		default:
5660 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5661 			break;
5662 		}
5663 
5664 		if (dut->ap_tx_stbc) {
5665 			run_system(dut, "cfg -a TX_STBC_2=1");
5666 		}
5667 
5668 		snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH_2=%d",
5669 			 dut->ap_channel);
5670 
5671 		if (dut->ap_is_dual) {
5672 			switch (dut->ap_mode_1) {
5673 			case AP_11g:
5674 				run_system(dut, "cfg -a AP_CHMODE=11G");
5675 				break;
5676 			case AP_11b:
5677 				run_system(dut, "cfg -a AP_CHMODE=11B");
5678 				break;
5679 			case AP_11ng:
5680 				run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5681 				break;
5682 			case AP_11a:
5683 				run_system(dut, "cfg -a AP_CHMODE=11A");
5684 				break;
5685 			case AP_11na:
5686 				run_system(dut, "cfg -a AP_CHMODE=11NAHT20");
5687 				break;
5688 			case AP_11ac:
5689 				run_system(dut, "cfg -a AP_CHMODE=11ACVHT80");
5690 				break;
5691 			default:
5692 				run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5693 				break;
5694 			}
5695 			snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d",
5696 				 dut->ap_channel_1);
5697 		}
5698 		run_system(dut, buf);
5699 	} else {
5700 		run_system(dut, "cfg -a AP_RADIO_ID=0");
5701 		switch (dut->ap_mode) {
5702 		case AP_11g:
5703 			run_system(dut, "cfg -a AP_CHMODE=11G");
5704 			break;
5705 		case AP_11b:
5706 			run_system(dut, "cfg -a AP_CHMODE=11B");
5707 			break;
5708 		case AP_11ng:
5709 			run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5710 			break;
5711 		case AP_11a:
5712 			run_system(dut, "cfg -a AP_CHMODE=11A");
5713 			break;
5714 		case AP_11na:
5715 			run_system(dut, "cfg -a AP_CHMODE=11NAHT20");
5716 			break;
5717 		case AP_11ac:
5718 			run_system(dut, "cfg -a AP_CHMODE=11ACVHT80");
5719 			break;
5720 		default:
5721 			run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5722 			break;
5723 		}
5724 		snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d",
5725 			 dut->ap_channel);
5726 		run_system(dut, buf);
5727 	}
5728 
5729 	if (dut->ap_sgi80 == 1) {
5730 		run_system(dut, "cfg -a SHORTGI=1");
5731 		run_system(dut, "cfg -a SHORTGI_2=1");
5732 	} else if (dut->ap_sgi80 == 0) {
5733 		run_system(dut, "cfg -a SHORTGI=0");
5734 		run_system(dut, "cfg -a SHORTGI_2=0");
5735 	}
5736 
5737 	if (dut->ap_ldpc == VALUE_ENABLED)
5738 		run_system(dut, "cfg -a LDPC=1");
5739 	else if (dut->ap_ldpc == VALUE_DISABLED)
5740 		run_system(dut, "cfg -a LDPC=0");
5741 }
5742 
5743 
5744 void ath_disable_txbf(struct sigma_dut *dut, const char *intf)
5745 {
5746 	run_iwpriv(dut, intf, "vhtsubfee 0");
5747 	run_iwpriv(dut, intf, "vhtsubfer 0");
5748 	run_iwpriv(dut, intf, "vhtmubfee 0");
5749 	run_iwpriv(dut, intf, "vhtmubfer 0");
5750 }
5751 
5752 
5753 static void ath_set_assoc_disallow(struct sigma_dut *dut, const char *ifname,
5754 				   const char *val)
5755 {
5756 	if (strcasecmp(val, "enable") == 0) {
5757 		run_iwpriv(dut, ifname, "mbo_asoc_dis 1");
5758 	} else if (strcasecmp(val, "disable") == 0) {
5759 		run_iwpriv(dut, ifname, "mbo_asoc_dis 0");
5760 	} else {
5761 		sigma_dut_print(dut, DUT_MSG_ERROR,
5762 				"Unsupported assoc_disallow");
5763 	}
5764 }
5765 
5766 
5767 static void apply_mbo_pref_ap_list(struct sigma_dut *dut)
5768 {
5769 	int i;
5770 	int least_pref = 1 << 8;
5771 	char ifname[20];
5772 	uint8_t self_mac[ETH_ALEN];
5773 	char buf[200];
5774 	int ap_ne_class, ap_ne_pref, ap_ne_op_ch;
5775 
5776 	get_if_name(dut, ifname, sizeof(ifname), 1);
5777 	get_hwaddr(ifname, self_mac);
5778 
5779 	/* Clear off */
5780 	snprintf(buf, sizeof(buf),
5781 		 "wifitool %s setbssidpref 00:00:00:00:00:00 0 0 0",
5782 		 ifname);
5783 	run_system(dut, buf);
5784 
5785 	/* Find the least preference number */
5786 	for (i = 0; i < dut->mbo_pref_ap_cnt; i++) {
5787 		unsigned char *mac_addr = dut->mbo_pref_aps[i].mac_addr;
5788 
5789 		ap_ne_class = 1;
5790 		ap_ne_pref = 255;
5791 		ap_ne_op_ch = 1;
5792 		if (dut->mbo_pref_aps[i].ap_ne_pref != -1)
5793 			ap_ne_pref = dut->mbo_pref_aps[i].ap_ne_pref;
5794 		if (dut->mbo_pref_aps[i].ap_ne_class != -1)
5795 			ap_ne_class = dut->mbo_pref_aps[i].ap_ne_class;
5796 		if (dut->mbo_pref_aps[i].ap_ne_op_ch != -1)
5797 			ap_ne_op_ch = dut->mbo_pref_aps[i].ap_ne_op_ch;
5798 
5799 		if (ap_ne_pref < least_pref)
5800 			least_pref = ap_ne_pref;
5801 		snprintf(buf, sizeof(buf),
5802 			 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d",
5803 			 ifname, mac_addr[0], mac_addr[1], mac_addr[2],
5804 			 mac_addr[3], mac_addr[4], mac_addr[5],
5805 			 ap_ne_pref, ap_ne_class, ap_ne_op_ch);
5806 		run_system(dut, buf);
5807 	}
5808 
5809 	/* Now add the self AP Address */
5810 	if (dut->mbo_self_ap_tuple.ap_ne_class == -1) {
5811 		if (dut->ap_channel <= 11)
5812 			ap_ne_class = 81;
5813 		else
5814 			ap_ne_class = 115;
5815 	} else {
5816 		ap_ne_class = dut->mbo_self_ap_tuple.ap_ne_class;
5817 	}
5818 
5819 	if (dut->mbo_self_ap_tuple.ap_ne_op_ch == -1)
5820 		ap_ne_op_ch = dut->ap_channel;
5821 	else
5822 		ap_ne_op_ch = dut->mbo_self_ap_tuple.ap_ne_op_ch;
5823 
5824 	if (dut->mbo_self_ap_tuple.ap_ne_pref == -1)
5825 		ap_ne_pref = least_pref - 1;
5826 	else
5827 		ap_ne_pref = dut->mbo_self_ap_tuple.ap_ne_pref;
5828 
5829 	snprintf(buf, sizeof(buf),
5830 		 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d",
5831 		 ifname, self_mac[0], self_mac[1], self_mac[2],
5832 		 self_mac[3], self_mac[4], self_mac[5],
5833 		 ap_ne_pref,
5834 		 ap_ne_class,
5835 		 ap_ne_op_ch);
5836 	run_system(dut, buf);
5837 }
5838 
5839 
5840 static void mubrp_commands(struct sigma_dut *dut, const char *ifname)
5841 {
5842 	run_iwpriv(dut, ifname, "he_subfer 1");
5843 	run_iwpriv(dut, ifname, "he_mubfer 1");
5844 	/* To enable MU_AX with MU_BRP trigger */
5845 	run_iwpriv(dut, ifname, "he_sounding_mode 13");
5846 	/* Sets g_force_1x1_peer to 1 which should be reset to zero for non MU
5847 	 * test cases */
5848 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 118 1",
5849 			   ifname);
5850 	/* Disable DL OFDMA */
5851 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 11 0",
5852 			   ifname);
5853 }
5854 
5855 
5856 static void ath_ap_set_params(struct sigma_dut *dut)
5857 {
5858 	const char *basedev = "wifi0";
5859 	const char *basedev_radio = "wifi1";
5860 	const char *ifname = get_main_ifname(dut);
5861 	char *ifname_dual = NULL;
5862 	int i;
5863 	char buf[300];
5864 	unsigned int he_mcsnssmap = dut->he_mcsnssmap;
5865 
5866 	if (sigma_radio_ifname[0])
5867 		basedev = sigma_radio_ifname[0];
5868 
5869 	if (dut->ap_is_dual == 1) {
5870 		basedev = sigma_radio_ifname[0];
5871 		basedev_radio = sigma_radio_ifname[1];
5872 		if (sigma_radio_ifname[0] &&
5873 		    strcmp(sigma_radio_ifname[0], "wifi0") == 0) {
5874 			ifname = "ath0";
5875 			ifname_dual = "ath1";
5876 		} else {
5877 			ifname = "ath1";
5878 			ifname_dual = "ath0";
5879 		}
5880 	}
5881 
5882 	if (dut->ap_countrycode[0]) {
5883 		run_iwpriv(dut, basedev, "setCountry %s", dut->ap_countrycode);
5884 		sigma_dut_print(dut, DUT_MSG_INFO, "Set countrycode");
5885 	}
5886 
5887 	for (i = 0; i < NUM_AP_AC; i++) {
5888 		if (dut->ap_qos[i].ac) {
5889 			run_iwpriv(dut, ifname, "cwmin %d 0 %d", i,
5890 				   dut->ap_qos[i].cwmin);
5891 			run_iwpriv(dut, ifname, "cwmax %d 0 %d", i,
5892 				   dut->ap_qos[i].cwmax);
5893 			run_iwpriv(dut, ifname, "aifs %d 0 %d", i,
5894 				   dut->ap_qos[i].aifs);
5895 			run_iwpriv(dut, ifname, "txoplimit %d 0 %d", i,
5896 				   dut->ap_qos[i].txop);
5897 			run_iwpriv(dut, ifname, "acm %d 0 %d", i,
5898 				   dut->ap_qos[i].acm);
5899 		}
5900 	}
5901 
5902 	for (i = 0; i < NUM_AP_AC; i++) {
5903 		if (dut->ap_sta_qos[i].ac) {
5904 			run_iwpriv(dut, ifname, "cwmin %d 1 %d", i,
5905 				   dut->ap_sta_qos[i].cwmin);
5906 			run_iwpriv(dut, ifname, "cwmax %d 1 %d", i,
5907 				   dut->ap_sta_qos[i].cwmax);
5908 			run_iwpriv(dut, ifname, "aifs %d 1 %d", i,
5909 				   dut->ap_sta_qos[i].aifs);
5910 			run_iwpriv(dut, ifname, "txoplimit %d 1 %d", i,
5911 				   dut->ap_sta_qos[i].txop);
5912 			run_iwpriv(dut, ifname, "acm %d 1 %d", i,
5913 				   dut->ap_sta_qos[i].acm);
5914 		}
5915 	}
5916 
5917 	if (dut->ap_disable_protection == 1) {
5918 		run_iwpriv(dut, ifname, "enablertscts 0");
5919 		sigma_dut_print(dut, DUT_MSG_INFO, "Disabled rtscts");
5920 	}
5921 
5922 	if (dut->ap_ldpc == VALUE_ENABLED)
5923 		run_iwpriv(dut, ifname, "ldpc 3");
5924 	else if (dut->ap_ldpc == VALUE_DISABLED)
5925 		run_iwpriv(dut, ifname, "ldpc 0");
5926 
5927 	if (dut->ap_ampdu == VALUE_ENABLED) {
5928 		run_iwpriv(dut, ifname, "ampdu 1");
5929 	} else if (dut->ap_ampdu == VALUE_DISABLED) {
5930 		run_iwpriv(dut, ifname, "ampdu 0");
5931 		if (dut->program == PROGRAM_HE) {
5932 			run_iwpriv(dut, ifname, "setaddbaoper 1");
5933 			run_system_wrapper(dut, "wifitool %s refusealladdbas 1",
5934 					   ifname);
5935 			if (dut->ap_amsdu == VALUE_ENABLED) {
5936 				/* disable the limit for A-MSDU */
5937 				run_system_wrapper(dut,
5938 						   "wifitool %s setUnitTestCmd 0x48 2 46 1",
5939 						   ifname);
5940 			}
5941 		}
5942 	}
5943 
5944 	if (dut->ap_ampdu_exp) {
5945 		if (dut->program == PROGRAM_VHT) {
5946 			run_iwpriv(dut, ifname, "vhtmaxampdu %d",
5947 				   dut->ap_ampdu_exp);
5948 		} else {
5949 			/* 11N */
5950 			run_iwpriv(dut, ifname, "maxampdu %d",
5951 				   dut->ap_ampdu_exp);
5952 		}
5953 	}
5954 
5955 	if (dut->ap_noack == VALUE_ENABLED) {
5956 		run_iwpriv(dut, ifname, "noackpolicy 0 0 1");
5957 		run_iwpriv(dut, ifname, "noackpolicy 1 0 1");
5958 		run_iwpriv(dut, ifname, "noackpolicy 2 0 1");
5959 		run_iwpriv(dut, ifname, "noackpolicy 3 0 1");
5960 	} else if (dut->ap_noack == VALUE_DISABLED) {
5961 		run_iwpriv(dut, ifname, "noackpolicy 0 0 0");
5962 		run_iwpriv(dut, ifname, "noackpolicy 1 0 0");
5963 		run_iwpriv(dut, ifname, "noackpolicy 2 0 0");
5964 		run_iwpriv(dut, ifname, "noackpolicy 3 0 0");
5965 	}
5966 
5967 	if (dut->device_type == AP_testbed && dut->ap_vhtmcs_map)
5968 		run_iwpriv(dut, ifname, "vht_mcsmap 0x%04x",
5969 			   dut->ap_vhtmcs_map);
5970 
5971 	if (dut->ap_amsdu == VALUE_ENABLED)
5972 		run_iwpriv(dut, ifname, "amsdu 2");
5973 	else if (dut->ap_amsdu == VALUE_DISABLED)
5974 		run_iwpriv(dut, ifname, "amsdu 1");
5975 
5976 	if (dut->ap_rx_amsdu == VALUE_ENABLED)
5977 		run_iwpriv(dut, basedev_radio, "rx_amsdu 1");
5978 	else if (dut->ap_rx_amsdu == VALUE_DISABLED)
5979 		run_iwpriv(dut, basedev_radio, "rx_amsdu 0");
5980 
5981 	/* Command sequence to generate single VHT AMSDU and MPDU */
5982 	if (dut->ap_addba_reject != VALUE_NOT_SET &&
5983 	    dut->ap_ampdu == VALUE_DISABLED &&
5984 	    dut->ap_amsdu == VALUE_ENABLED) {
5985 		run_iwpriv(dut, ifname, "setaddbaoper 1");
5986 
5987 		snprintf(buf, sizeof(buf),
5988 			 "wifitool %s senddelba 1 0 1 4", ifname);
5989 		if (system(buf) != 0) {
5990 			sigma_dut_print(dut, DUT_MSG_ERROR,
5991 					"wifitool senddelba failed");
5992 		}
5993 
5994 		snprintf(buf, sizeof(buf), "wifitool %s sendsingleamsdu 1 0",
5995 			 ifname);
5996 		if (system(buf) != 0) {
5997 			sigma_dut_print(dut, DUT_MSG_ERROR,
5998 					"wifitool sendsingleamsdu failed");
5999 		}
6000 
6001 		run_iwpriv(dut, ifname, "amsdu 10");
6002 	}
6003 
6004 	if (dut->ap_mode == AP_11ac) {
6005 		int chwidth, nss;
6006 
6007 		switch (dut->ap_chwidth) {
6008 		case AP_20:
6009 			chwidth = 0;
6010 			break;
6011 		case AP_40:
6012 			chwidth = 1;
6013 			break;
6014 		case AP_80:
6015 			chwidth = 2;
6016 			break;
6017 		case AP_160:
6018 			chwidth = 3;
6019 			break;
6020 		case AP_80_80:
6021 			chwidth = 3;
6022 			break;
6023 		default:
6024 			chwidth = 0;
6025 			break;
6026 		}
6027 
6028 		switch (dut->ap_tx_streams) {
6029 		case 1:
6030 			nss = 1;
6031 			break;
6032 		case 2:
6033 			nss = 2;
6034 			break;
6035 		case 3:
6036 			nss = 3;
6037 			break;
6038 		case 4:
6039 			nss = 4;
6040 			break;
6041 		default:
6042 			nss = 3;
6043 			break;
6044 		}
6045 
6046 		if (dut->ap_fixed_rate) {
6047 			if (nss == 4)
6048 				ath_disable_txbf(dut, ifname);
6049 
6050 			/* Set the nss */
6051 			run_iwpriv(dut, ifname, "nss %d", nss);
6052 
6053 			/* Set the channel width */
6054 			run_iwpriv(dut, ifname, "chwidth %d", chwidth);
6055 
6056 			/* Set the VHT MCS */
6057 			run_iwpriv(dut, ifname, "vhtmcs %d", dut->ap_mcs);
6058 		}
6059 	}
6060 
6061 	if (dut->ap_dyn_bw_sig == VALUE_ENABLED)
6062 		run_iwpriv(dut, ifname, "cwmenable 1");
6063 	else if (dut->ap_dyn_bw_sig == VALUE_DISABLED)
6064 		run_iwpriv(dut, ifname, "cwmenable 0");
6065 
6066 	if (dut->ap_sig_rts == VALUE_ENABLED) {
6067 		snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname);
6068 		if (system(buf) != 0) {
6069 			sigma_dut_print(dut, DUT_MSG_ERROR,
6070 					"iwconfig rts 64 failed");
6071 		}
6072 	} else if (dut->ap_sig_rts == VALUE_DISABLED) {
6073 		snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname);
6074 		if (system(buf) != 0) {
6075 			sigma_dut_print(dut, DUT_MSG_ERROR,
6076 					"iwconfig rts 2347 failed");
6077 		}
6078 	}
6079 
6080 	if (dut->ap_hs2) {
6081 		run_iwpriv(dut, ifname, "qbssload 1");
6082 		sigma_dut_print(dut, DUT_MSG_INFO, "Enabled qbssload");
6083 	}
6084 
6085 	if (dut->ap_bss_load && dut->ap_bss_load != -1) {
6086 		unsigned int bssload = 0;
6087 
6088 		if (dut->ap_bss_load == 1) {
6089 			/* STA count: 1, CU: 50, AAC: 65535 */
6090 			bssload = 0x0132ffff;
6091 		} else if (dut->ap_bss_load == 2) {
6092 			/* STA count: 1, CU: 200, AAC: 65535 */
6093 			bssload = 0x01c8ffff;
6094 		} else if (dut->ap_bss_load == 3) {
6095 			/* STA count: 1, CU: 75, AAC: 65535 */
6096 			bssload = 0x014bffff;
6097 		}
6098 
6099 		run_iwpriv(dut, ifname, "hcbssload %u", bssload);
6100 	} else if (dut->ap_bss_load == 0) {
6101 		run_iwpriv(dut, ifname, "qbssload 0");
6102 		sigma_dut_print(dut, DUT_MSG_INFO, "Disabled qbssload");
6103 	}
6104 
6105 	if (dut->ap_dgaf_disable) {
6106 		run_iwpriv(dut, ifname, "dgaf_disable 1");
6107 		sigma_dut_print(dut, DUT_MSG_INFO, "Enabled dgaf_disable");
6108 	}
6109 
6110 	if (dut->ap_l2tif) {
6111 		run_iwpriv(dut, ifname, "l2tif 1");
6112 		snprintf(buf, sizeof(buf),
6113 			"echo 1 > /sys/class/net/br0/brif/ath0/hotspot_l2tif");
6114 		if (system(buf) != 0)
6115 			sigma_dut_print(dut, DUT_MSG_ERROR,
6116 				"l2tif br failed");
6117 
6118 		snprintf(buf, sizeof(buf),
6119 			"echo 1 > /sys/class/net/br0/brif/eth0/hotspot_wan");
6120 		if (system(buf) != 0)
6121 			sigma_dut_print(dut, DUT_MSG_ERROR,
6122 				"l2tif brif failed");
6123 		sigma_dut_print(dut, DUT_MSG_INFO, "Enabled l2tif");
6124 	}
6125 
6126 	if (dut->ap_ndpa_frame == 0) {
6127 		snprintf(buf, sizeof(buf),
6128 			 "wifitool %s beeliner_fw_test 117 192", ifname);
6129 		if (system(buf) != 0) {
6130 			sigma_dut_print(dut, DUT_MSG_ERROR,
6131 					"wifitool beeliner_fw_test 117 192 failed");
6132 		}
6133 		snprintf(buf, sizeof(buf),
6134 			 "wifitool %s beeliner_fw_test 118 192", ifname);
6135 		if (system(buf) != 0) {
6136 			sigma_dut_print(dut, DUT_MSG_ERROR,
6137 					"wifitool beeliner_fw_test 117 192 failed");
6138 		}
6139 	} else if (dut->ap_ndpa_frame == 1) {
6140 		/* Driver default - no changes needed */
6141 	} else if (dut->ap_ndpa_frame == 2) {
6142 		snprintf(buf, sizeof(buf),
6143 			 "wifitool %s beeliner_fw_test 115 1", ifname);
6144 		if (system(buf) != 0) {
6145 			sigma_dut_print(dut, DUT_MSG_ERROR,
6146 					"wifitool beeliner_fw_test 117 192 failed");
6147 		}
6148 		snprintf(buf, sizeof(buf),
6149 			 "wifitool %s beeliner_fw_test 116 1", ifname);
6150 		if (system(buf) != 0) {
6151 			sigma_dut_print(dut, DUT_MSG_ERROR,
6152 					"wifitool beeliner_fw_test 117 192 failed");
6153 		}
6154 	}
6155 
6156 	if (dut->ap_rtt == 1)
6157 		run_iwpriv(dut, ifname, "enable_rtt 1");
6158 
6159 	if (dut->ap_lci == 1)
6160 		run_iwpriv(dut, ifname, "enable_lci 1");
6161 
6162 	if (dut->ap_lcr == 1)
6163 		run_iwpriv(dut, ifname, "enable_lcr 1");
6164 
6165 	if (dut->ap_rrm == 1)
6166 		run_iwpriv(dut, ifname, "enable_rmm 1");
6167 
6168 	if (dut->ap_lci == 1 || dut->ap_lcr == 1) {
6169 		run_system(dut, "wpc -l /tmp/lci_cfg.txt");
6170 	}
6171 
6172 	if (dut->ap_neighap >= 1 && dut->ap_lci == 0) {
6173 		FILE *f;
6174 
6175 		f = fopen("/tmp/nbr_report.txt", "w");
6176 		if (!f) {
6177 			sigma_dut_print(dut, DUT_MSG_ERROR,
6178 					"Failed to open /tmp/nbr_report.txt");
6179 			return;
6180 		}
6181 
6182 		fprintf(f,
6183 			"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",
6184 			dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1],
6185 			dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3],
6186 			dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5],
6187 			dut->ap_val_opchannel[0]);
6188 		fclose(f);
6189 
6190 		f = fopen("/tmp/ftmrr.txt", "w");
6191 		if (!f) {
6192 			sigma_dut_print(dut, DUT_MSG_ERROR,
6193 					"Failed to open /tmp/ftmrr.txt");
6194 			return;
6195 		}
6196 
6197 		fprintf(f,
6198 			"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",
6199 			dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1],
6200 			dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3],
6201 			dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5],
6202 			dut->ap_val_opchannel[0]);
6203 		fclose(f);
6204 	}
6205 
6206 	if (dut->ap_neighap >= 2 && dut->ap_lci == 0) {
6207 		FILE *f;
6208 
6209 		f = fopen("/tmp/nbr_report.txt", "a");
6210 		if (!f) {
6211 			sigma_dut_print(dut, DUT_MSG_ERROR,
6212 					"Failed to open /tmp/nbr_report.txt");
6213 			return;
6214 		}
6215 		fprintf(f,
6216 			"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",
6217 			dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1],
6218 			dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3],
6219 			dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5],
6220 			dut->ap_val_opchannel[1]);
6221 		fclose(f);
6222 
6223 		f = fopen("/tmp/ftmrr.txt", "a");
6224 		if (!f) {
6225 			sigma_dut_print(dut, DUT_MSG_ERROR,
6226 					"Failed to open /tmp/ftmrr.txt");
6227 			return;
6228 		}
6229 		fprintf(f,
6230 			"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",
6231 			dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1],
6232 			dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3],
6233 			dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5],
6234 			dut->ap_val_opchannel[1]);
6235 		fclose(f);
6236 	}
6237 
6238 	if (dut->ap_neighap >= 3 && dut->ap_lci == 0) {
6239 		FILE *f;
6240 
6241 		f = fopen("/tmp/nbr_report.txt", "a");
6242 		if (!f) {
6243 			sigma_dut_print(dut, DUT_MSG_ERROR,
6244 					"Failed to open /tmp/nbr_report.txt");
6245 			return;
6246 		}
6247 
6248 		fprintf(f,
6249 			"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",
6250 			dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1],
6251 			dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3],
6252 			dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5],
6253 			dut->ap_val_opchannel[2]);
6254 		fclose(f);
6255 
6256 		f = fopen("/tmp/ftmrr.txt", "a");
6257 		if (!f) {
6258 			sigma_dut_print(dut, DUT_MSG_ERROR,
6259 					"Failed to open /tmp/ftmrr.txt");
6260 			return;
6261 		}
6262 
6263 		fprintf(f,
6264 			"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",
6265 			dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1],
6266 			dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3],
6267 			dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5],
6268 			dut->ap_val_opchannel[2]);
6269 		fclose(f);
6270 	}
6271 
6272 	if (dut->ap_neighap) {
6273 		run_iwpriv(dut, ifname, "enable_rtt 1");
6274 		run_iwpriv(dut, ifname, "enable_lci 1");
6275 		run_iwpriv(dut, ifname, "enable_lcr 1");
6276 		run_iwpriv(dut, ifname, "enable_rrm 1");
6277 	}
6278 
6279 	if (dut->ap_scan == 1) {
6280 		run_iwpriv(dut, ifname, "scanentryage 600");
6281 		snprintf(buf, sizeof(buf), "iwlist %s scan", ifname);
6282 		run_system(dut, buf);
6283 	}
6284 
6285 	if (dut->ap_set_bssidpref) {
6286 		snprintf(buf, sizeof(buf),
6287 			 "wifitool %s setbssidpref 00:00:00:00:00:00 0 00 00",
6288 			 ifname);
6289 		if (system(buf) != 0) {
6290 			sigma_dut_print(dut, DUT_MSG_ERROR,
6291 					"wifitool clear bssidpref failed");
6292 		}
6293 	}
6294 
6295 	if (dut->wnm_bss_max_feature != VALUE_NOT_SET) {
6296 		int feature_enable;
6297 
6298 		feature_enable = dut->wnm_bss_max_feature == VALUE_ENABLED;
6299 		run_iwpriv(dut, ifname, "wnm %d", feature_enable);
6300 		run_iwpriv(dut, ifname, "wnm_bss %d", feature_enable);
6301 		if (feature_enable) {
6302 			const char *extra = "";
6303 
6304 			if (dut->wnm_bss_max_protection != VALUE_NOT_SET) {
6305 				if (dut->wnm_bss_max_protection ==
6306 				    VALUE_ENABLED)
6307 					extra = " 1";
6308 				else
6309 					extra = " 0";
6310 			}
6311 			snprintf(buf, sizeof(buf),
6312 				 "wlanconfig %s wnm setbssmax %d%s",
6313 				 ifname, dut->wnm_bss_max_idle_time, extra);
6314 			run_system(dut, buf);
6315 		}
6316 	}
6317 
6318 	if (dut->program == PROGRAM_MBO) {
6319 		apply_mbo_pref_ap_list(dut);
6320 		run_iwpriv(dut, ifname, "mbo_cel_pref %d",
6321 			   dut->ap_cell_cap_pref);
6322 		run_iwpriv(dut, ifname, "mbocap 0x40");
6323 		ath_set_assoc_disallow(dut, ifname, "disable");
6324 	}
6325 
6326 	if (dut->ap_oce == VALUE_ENABLED)
6327 		run_iwpriv(dut, ifname, "set_bpr_enable 1");
6328 
6329 	if (dut->ap_oce == VALUE_ENABLED && dut->ap_channel <= 11) {
6330 		run_iwpriv(dut, ifname, "prb_rate 5500");
6331 		run_iwpriv(dut, ifname, "set_bcn_rate 5500");
6332 	}
6333 
6334 	if (dut->ap_oce == VALUE_DISABLED)
6335 		run_iwpriv(dut, ifname, "set_bpr_enable 0");
6336 
6337 	if (dut->ap_oce == VALUE_DISABLED && dut->ap_channel <= 11) {
6338 		run_iwpriv(dut, ifname, "mgmt_rate 1000");
6339 		run_iwpriv(dut, ifname, "set_bcn_rate 1000");
6340 	}
6341 
6342 	if (dut->ap_bcnint)
6343 		run_iwpriv(dut, ifname, "bintval %d", dut->ap_bcnint);
6344 
6345 	if (dut->ap_filsdscv == VALUE_DISABLED)
6346 		run_iwpriv(dut, ifname, "enable_fils 0 0");
6347 
6348 	if (dut->ap_filshlp == VALUE_ENABLED)
6349 		run_iwpriv(dut, ifname, "oce_hlp 1");
6350 	else if (dut->ap_filshlp == VALUE_DISABLED)
6351 		run_iwpriv(dut, ifname, "oce_hlp 0");
6352 
6353 	/*  When RNR is enabled, also enable apchannelreport, background scan */
6354 	if (dut->ap_rnr == VALUE_ENABLED) {
6355 		run_iwpriv(dut, ifname, "rnr 1");
6356 		run_iwpriv(dut, ifname, "rnr_tbtt 1");
6357 		run_iwpriv(dut, ifname, "apchanrpt 1");
6358 		run_iwpriv(dut, basedev, "acs_ctrlflags 0x4");
6359 		run_iwpriv(dut, basedev, "acs_scanintvl 60");
6360 		run_iwpriv(dut, basedev, "acs_bkscanen 1");
6361 		if (dut->ap_is_dual == 1) {
6362 			run_iwpriv(dut, ifname_dual, "rnr 1");
6363 			run_iwpriv(dut, ifname_dual, "rnr_tbtt 1");
6364 			run_iwpriv(dut, ifname_dual, "apchanrpt 1");
6365 			run_iwpriv(dut, basedev_radio, "acs_ctrlflags 0x4");
6366 			run_iwpriv(dut, basedev_radio, "acs_scanintvl 60");
6367 			run_iwpriv(dut, basedev_radio, "acs_bkscanen 1");
6368 		}
6369 	}
6370 
6371 	if (dut->ap_blechanutil || dut->ap_ble_admit_cap || dut->ap_blestacnt) {
6372 		run_iwpriv(dut, ifname, "qbssload 0");
6373 		snprintf(buf, sizeof(buf),
6374 			 "wlanconfig %s addie ftype 0 len 7 data 0b05%02x%02x%02x%02x%02x ",
6375 			 ifname, dut->ap_blestacnt & 0xFF,
6376 			 dut->ap_blestacnt >> 8, dut->ap_blechanutil,
6377 			 dut->ap_ble_admit_cap & 0xFF,
6378 			 dut->ap_ble_admit_cap >> 8);
6379 		run_system(dut, buf);
6380 		snprintf(buf, sizeof(buf),
6381 			 "wlanconfig %s addie ftype 2 len 7 data 0b05%02x%02x%02x%02x%02x ",
6382 			 ifname, dut->ap_blestacnt & 0xFF,
6383 			 dut->ap_blestacnt >> 8, dut->ap_blechanutil,
6384 			 dut->ap_ble_admit_cap & 0xFF,
6385 			 dut->ap_ble_admit_cap >> 8);
6386 		run_system(dut, buf);
6387 	}
6388 
6389 	if (dut->ap_esp == VALUE_ENABLED)
6390 		run_iwpriv(dut, basedev, "esp_period 5");
6391 	else if (dut->ap_esp == VALUE_DISABLED)
6392 		run_iwpriv(dut, basedev, "esp_period 0");
6393 
6394 	if (dut->ap_datappdudura)
6395 		run_iwpriv(dut, basedev, "esp_ppdu_dur %d",
6396 			   dut->ap_datappdudura);
6397 
6398 	if (dut->ap_airtimefract)
6399 		run_iwpriv(dut, basedev, "esp_airtime %d",
6400 			   dut->ap_airtimefract);
6401 
6402 	if (dut->ap_dhcp_stop) {
6403 		snprintf(buf, sizeof(buf), "/etc/init.d/dnsmasq stop");
6404 		run_system(dut, buf);
6405 	}
6406 
6407 	if (dut->ap_bawinsize)
6408 		run_iwpriv(dut, basedev, "esp_ba_window %d", dut->ap_bawinsize);
6409 
6410 	if (dut->program == PROGRAM_DPP) {
6411 		if (dut->ap_interface_2g == 1) {
6412 			run_iwpriv(dut, ifname, "set_bcn_rate 5500");
6413 			run_iwpriv(dut, ifname, "prb_rate 5500");
6414 			run_iwpriv(dut, ifname, "mgmt_rate 5500");
6415 		}
6416 
6417 		run_iwpriv(dut, basedev, "set_rxfilter 0xffffffff");
6418 		dut->hostapd_running = 1;
6419 	}
6420 
6421 	if (dut->program == PROGRAM_HE) {
6422 		/* disable sending basic triggers */
6423 		run_system_wrapper(dut,
6424 				   "wifitool %s setUnitTestCmd 0x47 2 42 0",
6425 				   ifname);
6426 		/* disable MU BAR */
6427 		run_system_wrapper(dut,
6428 				   "wifitool %s setUnitTestCmd 0x47 2 64 1",
6429 				   ifname);
6430 		/* disable PSD Boost */
6431 		run_system_wrapper(dut,
6432 				   "wifitool %s setUnitTestCmd 0x48 2 142 1",
6433 				   ifname);
6434 		/* Enable mix bw */
6435 		run_system_wrapper(dut,
6436 				   "wifitool %s setUnitTestCmd 0x47 2 141 1",
6437 				   ifname);
6438 		/* Disable preferred AC */
6439 		run_system_wrapper(dut,
6440 				   "wifitool %s setUnitTestCmd 0x48 2 186 0",
6441 				   ifname);
6442 		run_iwpriv(dut, basedev, "he_muedca_mode 0");
6443 		run_iwpriv(dut, ifname, "he_ul_ofdma 0");
6444 		run_iwpriv(dut, ifname, "he_dl_ofdma 0");
6445 		if (dut->he_set_sta_1x1 == VALUE_ENABLED) {
6446 			/* sets g_force_1x1_peer to 1 */
6447 			run_system_wrapper(dut,
6448 					   "wifitool %s setUnitTestCmd 0x48 2 118 1",
6449 					    ifname);
6450 		}
6451 		if (dut->ap_txBF) {
6452 			/* Enable SU_AX sounding */
6453 			run_iwpriv(dut, ifname, "he_sounding_mode 1");
6454 			/* Ignore TBTT for NDP */
6455 			run_system_wrapper(dut,
6456 					   "wifitool %s setUnitTestCmd 0x48 2 2 1",
6457 					   ifname);
6458 			/* g_cv_query_enable=1, i.e., cv query enable */
6459 			run_system_wrapper(dut,
6460 					   "wifitool %s setUnitTestCmd 0x47 2 7 1",
6461 					   ifname);
6462 			/* Override TPC calculations and set TxBF flag to True
6463  */
6464 			run_system_wrapper(dut,
6465 					   "wifitool %s setUnitTestCmd 0x47 2 47 1",
6466 					   ifname);
6467 		}
6468 		if (dut->device_type == AP_testbed) {
6469 			run_iwpriv(dut, ifname, "tx_stbc 0");
6470 			run_iwpriv(dut, ifname, "he_txmcsmap 0x0");
6471 			run_iwpriv(dut, ifname, "he_rxmcsmap 0x0");
6472 			run_iwpriv(dut, ifname, "he_amsdu_in_ampdu_supp 0");
6473 			run_iwpriv(dut, ifname, "he_bfee_sts_supp 0 0");
6474 			run_iwpriv(dut, ifname, "he_4xltf_800nsgi_rx 0");
6475 			run_iwpriv(dut, ifname, "he_1xltf_800nsgi_rx 0");
6476 			run_iwpriv(dut, ifname, "he_max_nc 0");
6477 			run_iwpriv(dut, ifname, "he_bsr_supp 0");
6478 			run_iwpriv(dut, ifname, "rx_stbc 0");
6479 			if (dut->ap_he_dlofdma == VALUE_DISABLED)
6480 				run_iwpriv(dut, ifname, "he_dlofdma 0");
6481 			if (dut->ap_channel <= 11) {
6482 				dut->ap_bcc = VALUE_ENABLED;
6483 				run_iwpriv(dut, ifname, "vht_11ng 0");
6484 			}
6485 			if (!dut->ap_txBF) {
6486 				run_iwpriv(dut, ifname, "he_subfer 0");
6487 				run_iwpriv(dut, ifname, "he_subfee 0");
6488 			}
6489 			if (!dut->ap_mu_txBF) {
6490 				run_iwpriv(dut, ifname, "he_mubfer 0");
6491 				run_iwpriv(dut, ifname, "he_mubfee 0");
6492 			}
6493 			if (dut->ap_cipher == AP_WEP ||
6494 			    dut->ap_cipher == AP_TKIP)
6495 				run_iwpriv(dut, ifname, "htweptkip 1");
6496 			if (dut->ap_rx_streams || dut->ap_tx_streams)
6497 				run_iwpriv(dut, ifname, "nss %d",
6498 					   dut->ap_rx_streams);
6499 		}
6500 	}
6501 
6502 	if (dut->ap_he_ulofdma == VALUE_ENABLED) {
6503 		run_iwpriv(dut, ifname, "he_ul_ofdma 1");
6504 		run_iwpriv(dut, ifname, "he_mu_edca 1");
6505 
6506 		/* Disable sounding for UL OFDMA */
6507 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0",
6508 				   ifname);
6509 
6510 		if ((dut->ap_rx_streams || dut->ap_tx_streams) &&
6511 		    dut->device_type == AP_testbed) {
6512 			unsigned int txchainmask = 0x00;
6513 
6514 			switch (dut->ap_rx_streams) {
6515 			case 1:
6516 				txchainmask = 0x01;
6517 				break;
6518 			case 2:
6519 				txchainmask = 0x03;
6520 				break;
6521 			case 3:
6522 				txchainmask = 0x07;
6523 				break;
6524 			case 4:
6525 				txchainmask = 0x0f;
6526 				break;
6527 			case 5:
6528 				txchainmask = 0x1f;
6529 				break;
6530 			case 6:
6531 				txchainmask = 0x3f;
6532 				break;
6533 			case 7:
6534 				txchainmask = 0x7f;
6535 				break;
6536 			case 8:
6537 				txchainmask = 0xff;
6538 				break;
6539 			}
6540 
6541 			run_iwpriv(dut, ifname, "he_ul_nss %d",
6542 				   dut->ap_rx_streams);
6543 			run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
6544 			run_iwpriv(dut, basedev, "rxchainmask %d", txchainmask);
6545 		}
6546 
6547 		if (dut->ap_channel == 100 && dut->device_type == AP_testbed)
6548 			run_system_wrapper(dut, "iwpriv %s inact 1000", ifname);
6549 
6550 		if (dut->he_ul_mcs)
6551 			run_iwpriv(dut, ifname, "he_ul_mcs %d", dut->he_ul_mcs);
6552 
6553 		run_iwpriv(dut, ifname, "he_ul_ltf 3");
6554 		run_iwpriv(dut, ifname, "he_ul_shortgi 3");
6555 		run_iwpriv(dut, basedev, "he_ul_trig_int 2");
6556 
6557 		/* Disable efficiency check for UL OFDMA. We do not send TBPPDU
6558 		 * for one user. With this command, we would send UL OFDMA even
6559 		 * for one user to allow testing to be done without requiring
6560 		 * more than one station. */
6561 		run_system_wrapper(dut,
6562 				   "wifitool %s setUnitTestCmd 0x47 2 131 0",
6563 				   ifname);
6564 		/* Set random RU allocation */
6565 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 9 1",
6566 				   ifname);
6567 		/* To set TBTT PPDU duration (us) */
6568 		run_system_wrapper(dut,
6569 				   "wifitool %s setUnitTestCmd 0x48 2 63 1908",
6570 				   ifname);
6571 	}
6572 
6573 	if (dut->ap_he_dlofdma == VALUE_ENABLED) {
6574 		run_iwpriv(dut, ifname, "he_dl_ofdma 1", ifname);
6575 
6576 		/* For fixed MCS */
6577 		novap_reset(dut, ifname, 0);
6578 		run_iwpriv(dut, ifname,
6579 			   "cfg80211tool %s setratemask 3 0x80f80f80 0x0f80f80f 0xf80f80f8");
6580 	}
6581 
6582 	if (dut->ap_he_ppdu == PPDU_MU && dut->ap_he_dlofdma == VALUE_ENABLED) {
6583 		/* Increase the min TX time limit for MU MIMO to disable MU MIMO
6584 		 * scheduling */
6585 		run_system_wrapper(dut,
6586 				   "wifitool %s setUnitTestCmd 0x47 2 11 1000000",
6587 				   ifname);
6588 		/* Increase the max TX time limit for DL OFDMA to enable OFDMA
6589 		 * scheduling */
6590 		run_system_wrapper(dut,
6591 				   "wifitool %s setUnitTestCmd 0x47 2 17 1000000",
6592 				   ifname);
6593 		/* Disable 'force SU schedule' to enable MU sch */
6594 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 8 0",
6595 				   ifname);
6596 		/* Enable MU 11ax support in sch algo */
6597 		run_system_wrapper(dut,
6598 				   "wifitool %s setUnitTestCmd 0x47 2 29 0",
6599 				   ifname);
6600 		/* Enable to sort RU allocation */
6601 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x4b 2 2 1",
6602 				   ifname);
6603 	}
6604 
6605 	if (dut->ap_numsounddim) {
6606 		unsigned int txchainmask = 0;
6607 
6608 		switch (dut->ap_numsounddim) {
6609 		case 1:
6610 			txchainmask = 0x01;
6611 			break;
6612 		case 2:
6613 			txchainmask = 0x03;
6614 			break;
6615 		case 3:
6616 			txchainmask = 0x07;
6617 			break;
6618 		case 4:
6619 			txchainmask = 0x0f;
6620 			break;
6621 		case 5:
6622 			txchainmask = 0x1f;
6623 			break;
6624 		case 6:
6625 			txchainmask = 0x3f;
6626 			break;
6627 		case 7:
6628 			txchainmask = 0x7f;
6629 			break;
6630 		case 8:
6631 			txchainmask = 0xff;
6632 			break;
6633 		}
6634 		run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
6635 	}
6636 
6637 	if (dut->ap_numsounddim && dut->device_type == AP_testbed) {
6638 		/* Sets g_force_1x1_peer to 1 which should be reset to zero
6639 		 * for non-MU test cases */
6640 		run_system_wrapper(dut,
6641 				   "wifitool %s setUnitTestCmd 0x48 2 118 1",
6642 				   ifname);
6643 		if (dut->ap_mu_txBF) {
6644 			/* Disable DL OFDMA */
6645 			run_system_wrapper(dut,
6646 					   "wifitool %s setUnitTestCmd 0x47 2 11 0",
6647 					   ifname);
6648 		}
6649 	}
6650 
6651 	if (dut->ap_bcc == VALUE_ENABLED) {
6652 		run_iwpriv(dut, ifname, "mode 11AHE20");
6653 		run_iwpriv(dut, ifname, "nss 2");
6654 		run_iwpriv(dut, ifname, "he_txmcsmap 0x0");
6655 		run_iwpriv(dut, ifname, "he_rxmcsmap 0x0");
6656 	}
6657 
6658 	if (dut->ap_he_frag == VALUE_ENABLED)
6659 		run_iwpriv(dut, ifname, "he_frag 1");
6660 	else if (dut->ap_he_frag == VALUE_DISABLED)
6661 		run_iwpriv(dut, ifname, "he_frag 0");
6662 
6663 	if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) {
6664 		if (dut->ap_ba_bufsize == BA_BUFSIZE_64)
6665 			run_iwpriv(dut, ifname, "ba_bufsize 0");
6666 		else
6667 			run_iwpriv(dut, ifname, "ba_bufsize 1");
6668 	}
6669 
6670 	if (dut->ap_mu_edca == VALUE_ENABLED)
6671 		run_iwpriv(dut, ifname, "he_mu_edca 1");
6672 
6673 	if (dut->ap_he_mimo == MIMO_DL) {
6674 		mubrp_commands(dut, ifname);
6675 		if (dut->device_type != AP_testbed)
6676 			run_system_wrapper(
6677 				dut, "wifitool %s setUnitTestCmd 0x48 2 100 2",
6678 				ifname);
6679 	}
6680 
6681 	if (dut->ap_he_mimo == MIMO_UL)
6682 		run_iwpriv(dut, ifname, "he_mubfee 1");
6683 
6684 	if (dut->ap_he_rtsthrshld == VALUE_ENABLED)
6685 		run_iwpriv(dut, ifname, "he_rtsthrshld 512");
6686 	else if (dut->ap_he_rtsthrshld == VALUE_DISABLED)
6687 		run_iwpriv(dut, ifname, "he_rtsthrshld 1024");
6688 
6689 	if (dut->ap_mbssid == VALUE_ENABLED &&
6690 	    (dut->ap_rx_streams || dut->ap_tx_streams) &&
6691 	    dut->device_type == AP_testbed) {
6692 		const char *ifname_1;
6693 
6694 		ifname_1= dut->ap_channel >= 36 ? "ath01" : "ath11";
6695 
6696 		/* NSS is not set in Secondary VAP for MBSSID case,
6697 		 * hence it is explicitly set here. For primary VAP
6698 		 * NSS is set during AP configuration */
6699 		run_iwpriv(dut, ifname_1, "nss %d", dut->ap_rx_streams);
6700 	}
6701 
6702 	if (dut->ap_twtresp == VALUE_ENABLED)
6703 		run_iwpriv(dut, ifname, "twt_responder 1");
6704 	else if (dut->ap_twtresp == VALUE_DISABLED)
6705 		run_iwpriv(dut, ifname, "twt_responder 0");
6706 
6707 	if (dut->program == PROGRAM_HE && dut->ap_fixed_rate) {
6708 		int nss = 0, mcs = 0;
6709 		uint16_t mcsnssmap = 0;
6710 
6711 		/* MCS 7 is used - set only nss and he_mcs.
6712 		 * Do not set mcsnssmap unless MCS is 9 or 11. */
6713 		if (dut->ap_mcs >= 9) {
6714 			if (dut->ap_mcs == 9) {
6715 				if (dut->ap_tx_streams == 1) {
6716 					nss = 1;
6717 					mcs = dut->ap_mcs;
6718 				} else if (dut->ap_tx_streams == 2) {
6719 					nss = 2;
6720 					mcs = dut->ap_mcs;
6721 				}
6722 			} else if (dut->ap_mcs == 11) {
6723 				if (dut->ap_tx_streams == 1) {
6724 					nss = 1;
6725 					mcs = dut->ap_mcs;
6726 				} else if (dut->ap_tx_streams == 2) {
6727 					nss = 2;
6728 					mcs = dut->ap_mcs;
6729 				}
6730 			}
6731 
6732 			get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs);
6733 			he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap;
6734 		}
6735 
6736 		run_iwpriv(dut, ifname, "nss %d", dut->ap_tx_streams);
6737 		run_iwpriv(dut, ifname, "he_mcs %d", dut->ap_mcs);
6738 	}
6739 
6740 	if (he_mcsnssmap) {
6741 		run_iwpriv(dut, ifname, "he_rxmcsmap %lu", he_mcsnssmap);
6742 		run_iwpriv(dut, ifname, "he_txmcsmap %lu", he_mcsnssmap);
6743 	}
6744 
6745 	if (dut->he_sounding == VALUE_ENABLED)
6746 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0",
6747 				   ifname);
6748 
6749 	if (dut->he_mmss)
6750 		run_iwpriv(dut, ifname, "ampduden_ovrd %d", dut->he_mmss);
6751 
6752 	if (dut->he_srctrl_allow == 0) {
6753 		/* This is a special testbed AP case to enable SR for protocol
6754 		 * testing when SRCtrl_SRValue15Allowed is specified.
6755 		 */
6756 		run_iwpriv(dut, ifname, "he_sr_enable 1");
6757 	}
6758 }
6759 
6760 
6761 static int cmd_ath_ap_config_commit(struct sigma_dut *dut,
6762 				    struct sigma_conn *conn,
6763 				    struct sigma_cmd *cmd)
6764 {
6765 	/* const char *name = get_param(cmd, "NAME"); */
6766 	char buf[100];
6767 	struct stat s;
6768 	const char *ifname = dut->ap_is_dual ? "ath1" : "ath0";
6769 	int res;
6770 
6771 	if (stat("/proc/athversion", &s) == 0) {
6772 		sigma_dut_print(dut, DUT_MSG_INFO, "Run apdown");
6773 		run_system(dut, "apdown");
6774 	}
6775 
6776 	cmd_ath_ap_radio_config(dut);
6777 
6778 	snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID=%s'", dut->ap_ssid);
6779 	run_system(dut, buf);
6780 
6781 	switch (dut->ap_key_mgmt) {
6782 	case AP_OPEN:
6783 		if (dut->ap_cipher == AP_WEP) {
6784 			run_system(dut, "cfg -a AP_SECMODE=WEP");
6785 			run_system(dut, "cfg -a AP_SECFILE=NONE");
6786 			/* shared auth mode not supported */
6787 			run_system(dut, "cfg -a AP_WEP_MODE_0=1");
6788 			run_system(dut, "cfg -a AP_WEP_MODE_1=1");
6789 			snprintf(buf, sizeof(buf),
6790 				 "cfg -a WEP_RADIO_NUM0_KEY_1=%s",
6791 				 dut->ap_wepkey);
6792 			run_system(dut, buf);
6793 			snprintf(buf, sizeof(buf),
6794 				 "cfg -a WEP_RADIO_NUM1_KEY_1=%s",
6795 				 dut->ap_wepkey);
6796 			run_system(dut, buf);
6797 		} else {
6798 			run_system(dut, "cfg -a AP_SECMODE=None");
6799 		}
6800 		break;
6801 	case AP_WPA2_PSK:
6802 	case AP_WPA2_PSK_MIXED:
6803 	case AP_WPA_PSK:
6804 		case AP_WPA2_SAE:
6805 		case AP_WPA2_PSK_SAE:
6806 		if (dut->ap_key_mgmt == AP_WPA2_PSK ||
6807 		    dut->ap_key_mgmt == AP_WPA2_SAE ||
6808 		    dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
6809 			run_system(dut, "cfg -a AP_WPA=2");
6810 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
6811 			run_system(dut, "cfg -a AP_WPA=3");
6812 		else
6813 			run_system(dut, "cfg -a AP_WPA=1");
6814 		/* TODO: SAE configuration */
6815 		run_system(dut, "cfg -a AP_SECMODE=WPA");
6816 		run_system(dut, "cfg -a AP_SECFILE=PSK");
6817 		res = snprintf(buf, sizeof(buf), "cfg -a 'PSK_KEY=%s'",
6818 			       dut->ap_passphrase);
6819 		if (res < 0 || res >= sizeof(buf))
6820 			return ERROR_SEND_STATUS;
6821 		run_system(dut, buf);
6822 		if (dut->ap_cipher == AP_CCMP_TKIP)
6823 			run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\"");
6824 		else if (dut->ap_cipher == AP_TKIP)
6825 			run_system(dut, "cfg -a AP_CYPHER=TKIP");
6826 		else
6827 			run_system(dut, "cfg -a AP_CYPHER=CCMP");
6828 		break;
6829 	case AP_WPA2_EAP:
6830 	case AP_WPA2_EAP_MIXED:
6831 	case AP_WPA_EAP:
6832 		if (dut->ap_key_mgmt == AP_WPA2_EAP)
6833 			run_system(dut, "cfg -a AP_WPA=2");
6834 		else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
6835 			run_system(dut, "cfg -a AP_WPA=3");
6836 		else
6837 			run_system(dut, "cfg -a AP_WPA=1");
6838 		run_system(dut, "cfg -a AP_SECMODE=WPA");
6839 		run_system(dut, "cfg -a AP_SECFILE=EAP");
6840 		if (dut->ap_cipher == AP_CCMP_TKIP)
6841 			run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\"");
6842 		else if (dut->ap_cipher == AP_TKIP)
6843 			run_system(dut, "cfg -a AP_CYPHER=TKIP");
6844 		else
6845 			run_system(dut, "cfg -a AP_CYPHER=CCMP");
6846 		snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER=%s",
6847 			 dut->ap_radius_ipaddr);
6848 		run_system(dut, buf);
6849 		snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT=%d",
6850 			 dut->ap_radius_port);
6851 		run_system(dut, buf);
6852 		res = snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SECRET=%s",
6853 			       dut->ap_radius_password);
6854 		if (res < 0 || res >= sizeof(buf))
6855 			return ERROR_SEND_STATUS;
6856 		run_system(dut, buf);
6857 		break;
6858 	case AP_WPA2_EAP_OSEN:
6859 		/* TODO */
6860 		sigma_dut_print(dut, DUT_MSG_ERROR, "EAP+OSEN not supported");
6861 		break;
6862 	case AP_SUITEB:
6863 		/* TODO */
6864 		sigma_dut_print(dut, DUT_MSG_ERROR, "SuiteB not supported");
6865 		break;
6866 	case AP_WPA2_OWE:
6867 		/* TODO */
6868 		sigma_dut_print(dut, DUT_MSG_ERROR, "OWE not supported");
6869 		break;
6870 	case AP_WPA2_FT_EAP:
6871 	case AP_WPA2_FT_PSK:
6872 	case AP_WPA2_EAP_SHA256:
6873 	case AP_WPA2_PSK_SHA256:
6874 	case AP_WPA2_ENT_FT_EAP:
6875 	case AP_OSEN:
6876 		/* TODO */
6877 		send_resp(dut, conn, SIGMA_ERROR,
6878 			  "errorCode,Unsupported KeyMgnt value");
6879 		return 0;
6880 	}
6881 
6882 	if (dut->ap_is_dual) {
6883 		/* ath1 settings in case of dual */
6884 		snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID_2=%s'",
6885 			 dut->ap_ssid);
6886 		run_system(dut, buf);
6887 
6888 		switch (dut->ap_key_mgmt) {
6889 		case AP_OPEN:
6890 			if (dut->ap_cipher == AP_WEP) {
6891 				run_system(dut, "cfg -a AP_SECMODE_2=WEP");
6892 				run_system(dut, "cfg -a AP_SECFILE_2=NONE");
6893 				/* shared auth mode not supported */
6894 				run_system(dut, "cfg -a AP_WEP_MODE_0=1");
6895 				run_system(dut, "cfg -a AP_WEP_MODE_1=1");
6896 				snprintf(buf, sizeof(buf),
6897 					 "cfg -a WEP_RADIO_NUM0_KEY_1=%s",
6898 					 dut->ap_wepkey);
6899 				run_system(dut, buf);
6900 				snprintf(buf, sizeof(buf),
6901 					 "cfg -a WEP_RADIO_NUM1_KEY_1=%s",
6902 					 dut->ap_wepkey);
6903 				run_system(dut, buf);
6904 			} else {
6905 				run_system(dut, "cfg -a AP_SECMODE_2=None");
6906 			}
6907 			break;
6908 		case AP_WPA2_PSK:
6909 		case AP_WPA2_PSK_MIXED:
6910 		case AP_WPA_PSK:
6911 		case AP_WPA2_SAE:
6912 		case AP_WPA2_PSK_SAE:
6913 			if (dut->ap_key_mgmt == AP_WPA2_PSK ||
6914 			    dut->ap_key_mgmt == AP_WPA2_SAE ||
6915 			    dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
6916 				run_system(dut, "cfg -a AP_WPA_2=2");
6917 			else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
6918 				run_system(dut, "cfg -a AP_WPA_2=3");
6919 			else
6920 				run_system(dut, "cfg -a AP_WPA_2=1");
6921 			// run_system(dut, "cfg -a AP_WPA_2=2");
6922 			/* TODO: SAE configuration */
6923 			run_system(dut, "cfg -a AP_SECMODE_2=WPA");
6924 			run_system(dut, "cfg -a AP_SECFILE_2=PSK");
6925 			res = snprintf(buf, sizeof(buf),
6926 				       "cfg -a 'PSK_KEY_2=%s'",
6927 				       dut->ap_passphrase);
6928 			if (res < 0 || res >= sizeof(buf))
6929 				return ERROR_SEND_STATUS;
6930 			run_system(dut, buf);
6931 			if (dut->ap_cipher == AP_CCMP_TKIP)
6932 				run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\"");
6933 			else if (dut->ap_cipher == AP_TKIP)
6934 				run_system(dut, "cfg -a AP_CYPHER_2=TKIP");
6935 			else
6936 				run_system(dut, "cfg -a AP_CYPHER_2=CCMP");
6937 			break;
6938 		case AP_WPA2_EAP:
6939 		case AP_WPA2_EAP_MIXED:
6940 		case AP_WPA_EAP:
6941 			if (dut->ap_key_mgmt == AP_WPA2_EAP)
6942 				run_system(dut, "cfg -a AP_WPA_2=2");
6943 			else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
6944 				run_system(dut, "cfg -a AP_WPA_2=3");
6945 			else
6946 				run_system(dut, "cfg -a AP_WPA_2=1");
6947 			run_system(dut, "cfg -a AP_SECMODE_2=WPA");
6948 			run_system(dut, "cfg -a AP_SECFILE_2=EAP");
6949 			if (dut->ap_cipher == AP_CCMP_TKIP)
6950 				run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\"");
6951 			else if (dut->ap_cipher == AP_TKIP)
6952 				run_system(dut, "cfg -a AP_CYPHER_2=TKIP");
6953 			else
6954 				run_system(dut, "cfg -a AP_CYPHER_2=CCMP");
6955 
6956 			snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER_2=%s",
6957 				 dut->ap_radius_ipaddr);
6958 			run_system(dut, buf);
6959 			snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT_2=%d",
6960 				 dut->ap_radius_port);
6961 			run_system(dut, buf);
6962 			res = snprintf(buf, sizeof(buf),
6963 				       "cfg -a AP_AUTH_SECRET_2=%s",
6964 				       dut->ap_radius_password);
6965 			if (res < 0 || res >= sizeof(buf))
6966 				return ERROR_SEND_STATUS;
6967 			run_system(dut, buf);
6968 			break;
6969 		case AP_WPA2_EAP_OSEN:
6970 			/* TODO */
6971 			sigma_dut_print(dut, DUT_MSG_ERROR,
6972 					"EAP+OSEN not supported");
6973 			break;
6974 		case AP_SUITEB:
6975 			/* TODO */
6976 			sigma_dut_print(dut, DUT_MSG_ERROR,
6977 					"SuiteB not supported");
6978 			break;
6979 		case AP_WPA2_OWE:
6980 			/* TODO */
6981 			sigma_dut_print(dut, DUT_MSG_ERROR,
6982 					"OWE not supported");
6983 			break;
6984 		case AP_WPA2_FT_EAP:
6985 		case AP_WPA2_FT_PSK:
6986 		case AP_WPA2_EAP_SHA256:
6987 		case AP_WPA2_PSK_SHA256:
6988 		case AP_WPA2_ENT_FT_EAP:
6989 		case AP_OSEN:
6990 			/* TODO */
6991 			send_resp(dut, conn, SIGMA_ERROR,
6992 				  "errorCode,Unsupported KeyMgnt value");
6993 			return 0;
6994 		}
6995 
6996 		/* wifi0 settings in case of dual */
6997 		run_system(dut, "cfg -a AP_RADIO_ID=0");
6998 		run_system(dut, "cfg -a AP_PRIMARY_CH=6");
6999 		run_system(dut, "cfg -a AP_STARTMODE=dual");
7000 		run_system(dut, "cfg -a AP_CHMODE=11NGHT40PLUS");
7001 		run_system(dut, "cfg -a TX_CHAINMASK=7");
7002 		run_system(dut, "cfg -a RX_CHAINMASK=7");
7003 	}
7004 
7005 	switch (dut->ap_pmf) {
7006 	case AP_PMF_DISABLED:
7007 		snprintf(buf, sizeof(buf), "cfg -a AP_PMF=0");
7008 		run_system(dut, buf);
7009 		break;
7010 	case AP_PMF_OPTIONAL:
7011 		snprintf(buf, sizeof(buf), "cfg -a AP_PMF=1");
7012 		run_system(dut, buf);
7013 		break;
7014 	case AP_PMF_REQUIRED:
7015 		snprintf(buf, sizeof(buf), "cfg -a AP_PMF=2");
7016 		run_system(dut, buf);
7017 		break;
7018 	}
7019 	if (dut->ap_add_sha256) {
7020 		snprintf(buf, sizeof(buf), "cfg -a AP_WPA_SHA256=1");
7021 		run_system(dut, buf);
7022 	} else {
7023 		snprintf(buf, sizeof(buf), "cfg -r AP_WPA_SHA256");
7024 		run_system(dut, buf);
7025 	}
7026 
7027 	if (dut->ap_hs2)
7028 		run_system(dut, "cfg -a AP_HOTSPOT=1");
7029 	else
7030 		run_system(dut, "cfg -r AP_HOTSPOT");
7031 
7032 	if (dut->ap_interworking) {
7033 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_ANT=%d",
7034 			 dut->ap_access_net_type);
7035 		run_system(dut, buf);
7036 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_INTERNET=%d",
7037 			 dut->ap_internet);
7038 		run_system(dut, buf);
7039 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUEGROUP=%d",
7040 			 dut->ap_venue_group);
7041 		run_system(dut, buf);
7042 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUETYPE=%d",
7043 			 dut->ap_venue_type);
7044 		run_system(dut, buf);
7045 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=%s",
7046 			 dut->ap_hessid);
7047 		run_system(dut, buf);
7048 
7049 		if (dut->ap_roaming_cons[0]) {
7050 			char *second, *rc;
7051 			rc = strdup(dut->ap_roaming_cons);
7052 			if (rc == NULL)
7053 				return 0;
7054 
7055 			second = strchr(rc, ';');
7056 			if (second)
7057 				*second++ = '\0';
7058 
7059 			snprintf(buf, sizeof(buf),
7060 				 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=%s", rc);
7061 			run_system(dut, buf);
7062 
7063 			if (second) {
7064 				snprintf(buf, sizeof(buf),
7065 					 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2"
7066 					 "=%s", second);
7067 				run_system(dut, buf);
7068 			}
7069 			free(rc);
7070 		} else {
7071 			run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM");
7072 			run_system(dut,
7073 				   "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2");
7074 		}
7075 	} else {
7076 		run_system(dut, "cfg -r AP_HOTSPOT_ANT");
7077 		run_system(dut, "cfg -r AP_HOTSPOT_INTERNET");
7078 		run_system(dut, "cfg -r AP_HOTSPOT_VENUEGROUP");
7079 		run_system(dut, "cfg -r AP_HOTSPOT_VENUETYPE");
7080 		run_system(dut, "cfg -r AP_HOTSPOT_HESSID");
7081 		run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM");
7082 		run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2");
7083 	}
7084 
7085 	if (dut->ap_proxy_arp)
7086 		run_system(dut, "cfg -a IEEE80211V_PROXYARP=1");
7087 	else
7088 		run_system(dut, "cfg -a IEEE80211V_PROXYARP=0");
7089 	if (dut->ap_dgaf_disable)
7090 		run_system(dut, "cfg -a AP_HOTSPOT_DISABLE_DGAF=1");
7091 	else
7092 		run_system(dut, "cfg -r AP_HOTSPOT_DISABLE_DGAF");
7093 
7094 	if (strlen(dut->ap_tag_ssid[0])) {
7095 		snprintf(buf, sizeof(buf),
7096 			 "cfg -a AP_SSID_2=%s", dut->ap_tag_ssid[0]);
7097 		run_system(dut, buf);
7098 
7099 		if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) {
7100 			run_system(dut, "cfg -a AP_SECMODE_2=WPA");
7101 			run_system(dut, "cfg -a AP_SECFILE_2=OSEN");
7102 
7103 			res = snprintf(buf, sizeof(buf),
7104 				       "cfg -a AP_AUTH_SERVER_2=%s",
7105 				       dut->ap2_radius_ipaddr);
7106 			if (res < 0 || res >= sizeof(buf))
7107 				return ERROR_SEND_STATUS;
7108 			run_system(dut, buf);
7109 
7110 			res = snprintf(buf, sizeof(buf),
7111 				       "cfg -a AP_AUTH_PORT_2=%d",
7112 				       dut->ap2_radius_port);
7113 			if (res < 0 || res >= sizeof(buf))
7114 				return ERROR_SEND_STATUS;
7115 			run_system(dut, buf);
7116 
7117 			res = snprintf(buf, sizeof(buf),
7118 				       "cfg -a AP_AUTH_SECRET_2=%s",
7119 				       dut->ap2_radius_password);
7120 			if (res < 0 || res >= sizeof(buf))
7121 				return ERROR_SEND_STATUS;
7122 			run_system(dut, buf);
7123 		} else {
7124 			run_system(dut, "cfg -a AP_SECMODE_2=None");
7125 			run_system(dut, "cfg -r AP_AUTH_SERVER_2");
7126 			run_system(dut, "cfg -r AP_AUTH_PORT_2");
7127 			run_system(dut, "cfg -r AP_AUTH_SECRET_2");
7128 		}
7129 
7130 		run_system(dut, "cfg -a AP_STARTMODE=multi");
7131 	}
7132 
7133 	run_system(dut, "cfg -c");
7134 
7135 	sigma_dut_print(dut, DUT_MSG_INFO, "Starting AP");
7136 	if (system("apup") != 0) {
7137 		/* to be debugged why apup returns error
7138 		send_resp(dut, conn, SIGMA_ERROR,
7139 			  "errorCode,apup failed");
7140 		return 0;
7141 		*/
7142 	}
7143 	sigma_dut_print(dut, DUT_MSG_INFO, "AP started");
7144 
7145 	if (dut->ap_key_mgmt != AP_OPEN) {
7146 		int res;
7147 		/* allow some time for hostapd to start before returning
7148 		 * success */
7149 		usleep(500000);
7150 		if (run_hostapd_cli(dut, "ping") != 0) {
7151 			send_resp(dut, conn, SIGMA_ERROR,
7152 				  "errorCode,Failed to talk to hostapd");
7153 			return 0;
7154 		}
7155 
7156 		if (dut->ap_hs2 && !dut->ap_anqpserver) {
7157 			/* the cfg app doesn't like ";" in the variables */
7158 			res = ath_ap_append_hostapd_conf(dut);
7159 			if (res < 0)
7160 				return res;
7161 
7162 			/* wait for hostapd to be ready */
7163 			usleep(500000);
7164 			if (run_hostapd_cli(dut, "ping") != 0) {
7165 				send_resp(dut, conn, SIGMA_ERROR,
7166 					  "errorCode,Failed to talk to "
7167 					  "hostapd");
7168 				return 0;
7169 			}
7170 		}
7171 	}
7172 
7173 	ath_ap_set_params(dut);
7174 
7175 	if (dut->ap_anqpserver)
7176 		return cmd_ath_ap_anqpserver_start(dut);
7177 
7178 	if (dut->ap2_proxy_arp)
7179 		run_iwpriv(dut, ifname, "proxy_arp 1");
7180 
7181 	if (dut->ap_allow_vht_wep || dut->ap_allow_vht_tkip)
7182 		run_iwpriv(dut, ifname, "htweptkip 1");
7183 
7184 	return 1;
7185 }
7186 
7187 
7188 static int set_ebtables_proxy_arp(struct sigma_dut *dut, const char *chain,
7189 				  const char *ifname)
7190 {
7191 	char buf[200];
7192 
7193 	if (!chain || !ifname)
7194 		return -2;
7195 
7196 	snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain);
7197 	if (system(buf) != 0) {
7198 		sigma_dut_print(dut, DUT_MSG_ERROR,
7199 				"Failed to set ebtables rules, RULE-1, %s",
7200 				chain);
7201 		return -2;
7202 	}
7203 
7204 	snprintf(buf, sizeof(buf),
7205 		 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP",
7206 		 chain, ifname);
7207 	if (system(buf) != 0) {
7208 		sigma_dut_print(dut, DUT_MSG_ERROR,
7209 				"Failed to set ebtables rules, RULE-2, %s",
7210 				chain);
7211 		return -2;
7212 	}
7213 
7214 	snprintf(buf, sizeof(buf),
7215 		 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-solicitation -o %s -j DROP",
7216 		 chain, ifname);
7217 	if (system(buf) != 0) {
7218 		sigma_dut_print(dut, DUT_MSG_ERROR,
7219 				"Failed to set ebtables rules, RULE-3, %s",
7220 				chain);
7221 		return -2;
7222 	}
7223 
7224 	snprintf(buf, sizeof(buf),
7225 		 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-advertisement -o %s -j DROP",
7226 		 chain, ifname);
7227 	if (system(buf) != 0) {
7228 		sigma_dut_print(dut, DUT_MSG_ERROR,
7229 				"Failed to set ebtables rules, RULE-4, %s",
7230 				chain);
7231 		return -2;
7232 	}
7233 
7234 	return 0;
7235 }
7236 
7237 
7238 static int set_ebtables_disable_dgaf(struct sigma_dut *dut,
7239 				     const char *chain,
7240 				     const char *ifname)
7241 {
7242 	char buf[200];
7243 
7244 	if (!chain || !ifname)
7245 		return -2;
7246 
7247 	snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain);
7248 	if (system(buf) != 0) {
7249 		sigma_dut_print(dut, DUT_MSG_ERROR,
7250 				"Failed to set ebtables rules, RULE-5, %s",
7251 				chain);
7252 		return -2;
7253 	}
7254 
7255 	snprintf(buf, sizeof(buf),
7256 		 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP",
7257 		 chain, ifname);
7258 	if (system(buf) != 0) {
7259 		sigma_dut_print(dut, DUT_MSG_ERROR,
7260 				"Failed to set ebtables rules, RULE-6, %s",
7261 				chain);
7262 		return -2;
7263 	}
7264 
7265 	snprintf(buf, sizeof(buf),
7266 		 "ebtables -A %s -p IPv4 -d Multicast -o %s -j DROP",
7267 		 chain, ifname);
7268 	if (system(buf) != 0) {
7269 		sigma_dut_print(dut, DUT_MSG_ERROR,
7270 				"Failed to set ebtables rules, RULE-7, %s",
7271 				chain);
7272 		return -2;
7273 	}
7274 
7275 	snprintf(buf, sizeof(buf),
7276 		 "ebtables -A %s -p IPv6 -d Multicast -o %s -j DROP",
7277 		 chain, ifname);
7278 	if (system(buf) != 0) {
7279 		sigma_dut_print(dut, DUT_MSG_ERROR,
7280 				"Failed to set ebtables rules, RULE-8, %s",
7281 				chain);
7282 		return -2;
7283 	}
7284 
7285 	return 0;
7286 }
7287 
7288 
7289 static void set_ebtables_forward_drop(struct sigma_dut *dut,
7290 				      const char *ifname, const char *ifname2)
7291 {
7292 	char buf[128];
7293 
7294 	snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP",
7295 		 ifname, ifname2);
7296 	if (system(buf) != 0)
7297 		sigma_dut_print(dut, DUT_MSG_ERROR,
7298 				"Failed to set ebtables rule");
7299 
7300 	snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP",
7301 		 ifname2, ifname);
7302 	if (system(buf) != 0)
7303 		sigma_dut_print(dut, DUT_MSG_ERROR,
7304 				"Failed to set ebtables rule");
7305 }
7306 
7307 
7308 static int check_channel(int channel)
7309 {
7310 	int channel_list[] = { 36, 40, 44, 48, 52, 60, 64, 100, 104, 108, 112,
7311 			       116, 120, 124, 128, 132, 140, 144, 149, 153, 157,
7312 			       161, 165 };
7313 	int num_chan = sizeof(channel_list) / sizeof(int);
7314 	int i;
7315 
7316 	for (i = 0; i < num_chan; i++) {
7317 		if (channel == channel_list[i])
7318 			return i;
7319 	}
7320 
7321 	return -1;
7322 }
7323 
7324 
7325 static int get_oper_centr_freq_seq_idx(int chwidth, int channel)
7326 {
7327 	int ch_base;
7328 	int period;
7329 
7330 	if (check_channel(channel) < 0)
7331 		return -1;
7332 
7333 	if (channel >= 36 && channel <= 64)
7334 		ch_base = 36;
7335 	else if (channel >= 100 && channel <= 144)
7336 		ch_base = 100;
7337 	else
7338 		ch_base = 149;
7339 
7340 	period = channel % ch_base * 5 / chwidth;
7341 	return ch_base + period * chwidth / 5 + (chwidth - 20) / 10;
7342 }
7343 
7344 
7345 static int is_ht40plus_chan(int chan)
7346 {
7347 	return chan == 36 || chan == 44 || chan == 52 || chan == 60 ||
7348 		chan == 100 || chan == 108 || chan == 116 || chan == 124 ||
7349 		chan == 132 || chan == 149 || chan == 157;
7350 }
7351 
7352 
7353 static int is_ht40minus_chan(int chan)
7354 {
7355 	return chan == 40 || chan == 48 || chan == 56 || chan == 64 ||
7356 		chan == 104 || chan == 112 || chan == 120 || chan == 128 ||
7357 		chan == 136 || chan == 144 || chan == 153 || chan == 161;
7358 }
7359 
7360 
7361 static int get_5g_channel_freq(int chan)
7362 {
7363 	return 5000 + chan * 5;
7364 }
7365 
7366 
7367 static const char * hostapd_cipher_name(enum ap_cipher cipher)
7368 {
7369 	switch (cipher) {
7370 	case AP_CCMP:
7371 		return "CCMP";
7372 	case AP_TKIP:
7373 		return "TKIP";
7374 	case AP_CCMP_TKIP:
7375 		return "CCMP TKIP";
7376 	case AP_GCMP_256:
7377 		return "GCMP-256";
7378 	case AP_GCMP_128:
7379 		return "GCMP";
7380 	case AP_CCMP_256:
7381 		return "CCMP-256";
7382 	case AP_CCMP_128_GCMP_256:
7383 		return "CCMP GCMP-256";
7384 	default:
7385 		return "UNKNOWN";
7386 	}
7387 }
7388 
7389 
7390 static const char *
7391 hostapd_group_mgmt_cipher_name(enum ap_group_mgmt_cipher cipher)
7392 {
7393 	switch (cipher) {
7394 	case AP_BIP_GMAC_256:
7395 		return "BIP-GMAC-256";
7396 	case AP_BIP_CMAC_256:
7397 		return "BIP-CMAC-256";
7398 	case AP_BIP_GMAC_128:
7399 		return "BIP-GMAC-128";
7400 	case AP_BIP_CMAC_128:
7401 		return "AES-128-CMAC";
7402 	default:
7403 		return "UNKNOWN";
7404 	}
7405 }
7406 
7407 
7408 static int ap_set_60g_ese(struct sigma_dut *dut, int count,
7409 			  struct sigma_ese_alloc *allocs)
7410 {
7411 	switch (get_driver_type(dut)) {
7412 #ifdef __linux__
7413 	case DRIVER_WIL6210:
7414 		return wil6210_set_ese(dut, count, allocs);
7415 #endif /* __linux__ */
7416 	default:
7417 		sigma_dut_print(dut, DUT_MSG_ERROR,
7418 				"Unsupported ap_set_60g_ese with the current driver");
7419 		return -1;
7420 	}
7421 }
7422 
7423 
7424 static int ap_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7425 {
7426 	switch (get_driver_type(dut)) {
7427 #ifdef __linux__
7428 	case DRIVER_WIL6210:
7429 		return wil6210_set_force_mcs(dut, force, mcs);
7430 #endif /* __linux__ */
7431 	default:
7432 		sigma_dut_print(dut, DUT_MSG_ERROR,
7433 				"Unsupported ap_set_force_mcs with the current driver");
7434 		return -1;
7435 	}
7436 }
7437 
7438 
7439 enum sigma_cmd_result cmd_ap_config_commit(struct sigma_dut *dut,
7440 					   struct sigma_conn *conn,
7441 					   struct sigma_cmd *cmd)
7442 {
7443 	/* const char *name = get_param(cmd, "NAME"); */
7444 	FILE *f;
7445 	const char *ifname;
7446 	char buf[500];
7447 	char path[100];
7448 	char ap_conf_path[100];
7449 	enum driver_type drv;
7450 	const char *key_mgmt;
7451 #ifdef ANDROID
7452 	struct group *gr;
7453 #endif /* ANDROID */
7454 
7455 	drv = get_driver_type(dut);
7456 
7457 	if (dut->mode == SIGMA_MODE_STATION) {
7458 		stop_sta_mode(dut);
7459 		sleep(1);
7460 	}
7461 
7462 	if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) {
7463 		snprintf(buf, sizeof(buf), "ifconfig %s down",
7464 			 dut->sniffer_ifname);
7465 		if (system(buf) != 0) {
7466 			sigma_dut_print(dut, DUT_MSG_INFO,
7467 					"Failed to run '%s'", buf);
7468 		}
7469 		snprintf(buf, sizeof(buf), "iw dev %s set type station",
7470 			 dut->sniffer_ifname);
7471 		if (system(buf) != 0) {
7472 			sigma_dut_print(dut, DUT_MSG_INFO,
7473 					"Failed to run '%s'", buf);
7474 		}
7475 	}
7476 
7477 	dut->mode = SIGMA_MODE_AP;
7478 
7479 	if (drv == DRIVER_ATHEROS)
7480 		return cmd_ath_ap_config_commit(dut, conn, cmd);
7481 	if (drv == DRIVER_WCN)
7482 		return cmd_wcn_ap_config_commit(dut, conn, cmd);
7483 	if (drv == DRIVER_OPENWRT)
7484 		return cmd_owrt_ap_config_commit(dut, conn, cmd);
7485 
7486 	concat_sigma_tmpdir(dut, "/sigma_dut-ap.conf", ap_conf_path,
7487 			    sizeof(ap_conf_path));
7488 	f = fopen(ap_conf_path, "w");
7489 	if (f == NULL) {
7490 		sigma_dut_print(dut, DUT_MSG_ERROR,
7491 				"%s: Failed to open sigma_dut-ap.conf",
7492 				__func__);
7493 		return -2;
7494 	}
7495 
7496 	ifname = get_hostapd_ifname(dut);
7497 
7498 	switch (dut->ap_mode) {
7499 	case AP_11g:
7500 	case AP_11b:
7501 	case AP_11ng:
7502 		fprintf(f, "hw_mode=g\n");
7503 		break;
7504 	case AP_11a:
7505 	case AP_11na:
7506 	case AP_11ac:
7507 		fprintf(f, "hw_mode=a\n");
7508 		break;
7509 	case AP_11ad:
7510 		fprintf(f, "hw_mode=ad\n");
7511 		break;
7512 	case AP_11ax:
7513 		if (dut->use_5g)
7514 			fprintf(f, "hw_mode=a\n");
7515 		else
7516 			fprintf(f, "hw_mode=g\n");
7517 		break;
7518 	default:
7519 		fclose(f);
7520 		return -1;
7521 	}
7522 
7523 	if (drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN)
7524 		fprintf(f, "driver=nl80211\n");
7525 
7526 	if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7527 	     drv == DRIVER_LINUX_WCN) &&
7528 	    (dut->ap_mode == AP_11ng || dut->ap_mode == AP_11na ||
7529 	     (dut->ap_mode == AP_11ax && !dut->use_5g))) {
7530 		int ht40plus = 0, ht40minus = 0, tx_stbc = 0;
7531 
7532 		fprintf(f, "ieee80211n=1\n");
7533 		if (dut->ap_mode == AP_11ax)
7534 			fprintf(f, "ieee80211ax=1\n");
7535 		if (dut->ap_mode == AP_11ng &&
7536 		    (dut->ap_chwidth == AP_40 ||
7537 		     (dut->ap_chwidth == AP_AUTO &&
7538 		      dut->default_11ng_ap_chwidth == AP_40))) {
7539 			if (dut->ap_channel >= 1 && dut->ap_channel <= 7)
7540 				ht40plus = 1;
7541 			else if (dut->ap_channel >= 8 && dut->ap_channel <= 11)
7542 				ht40minus = 1;
7543 			fprintf(f, "obss_interval=300\n");
7544 		}
7545 
7546 		/* configure ht_capab based on channel width */
7547 		if (dut->ap_mode == AP_11na &&
7548 		    (dut->ap_chwidth == AP_40 ||
7549 		     (dut->ap_chwidth == AP_AUTO &&
7550 		      dut->default_11na_ap_chwidth == AP_40))) {
7551 			if (is_ht40plus_chan(dut->ap_channel))
7552 				ht40plus = 1;
7553 			else if (is_ht40minus_chan(dut->ap_channel))
7554 				ht40minus = 1;
7555 		}
7556 
7557 		if (dut->ap_tx_stbc)
7558 			tx_stbc = 1;
7559 
7560 		/* Overwrite the ht_capab with offset value if configured */
7561 		if (dut->ap_chwidth == AP_40 &&
7562 		    dut->ap_chwidth_offset == SEC_CH_40ABOVE) {
7563 			ht40plus = 1;
7564 			ht40minus = 0;
7565 		} else if (dut->ap_chwidth == AP_40 &&
7566 			   dut->ap_chwidth_offset == SEC_CH_40BELOW) {
7567 			ht40minus = 1;
7568 			ht40plus = 0;
7569 		}
7570 
7571 		fprintf(f, "ht_capab=%s%s%s\n",
7572 			ht40plus ? "[HT40+]" : "",
7573 			ht40minus ? "[HT40-]" : "",
7574 			tx_stbc ? "[TX-STBC]" : "");
7575 	}
7576 
7577 	if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7578 	     drv == DRIVER_LINUX_WCN) &&
7579 	    (dut->ap_mode == AP_11ac ||
7580 	    (dut->ap_mode == AP_11ax && dut->use_5g))) {
7581 		int ht40plus = 0, ht40minus = 0;
7582 
7583 		fprintf(f, "ieee80211ac=1\n"
7584 			"ieee80211n=1\n");
7585 		if (dut->ap_mode == AP_11ax)
7586 			fprintf(f, "ieee80211ax=1\n");
7587 
7588 		/* configure ht_capab based on channel width */
7589 		if (dut->ap_chwidth != AP_20) {
7590 			if (is_ht40plus_chan(dut->ap_channel))
7591 				ht40plus = 1;
7592 			else if (is_ht40minus_chan(dut->ap_channel))
7593 				ht40minus = 1;
7594 
7595 			fprintf(f, "ht_capab=%s%s\n",
7596 				ht40plus ? "[HT40+]" : "",
7597 				ht40minus ? "[HT40-]" : "");
7598 		}
7599 	}
7600 
7601 	if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7602 	     drv == DRIVER_LINUX_WCN) &&
7603 	    (dut->ap_mode == AP_11ac || dut->ap_mode == AP_11na)) {
7604 		if (dut->ap_countrycode[0]) {
7605 			fprintf(f, "country_code=%s\n", dut->ap_countrycode);
7606 			fprintf(f, "ieee80211d=1\n");
7607 			fprintf(f, "ieee80211h=1\n");
7608 		}
7609 	}
7610 
7611 	if (drv == DRIVER_LINUX_WCN && dut->ap_mode == AP_11ax) {
7612 		if (dut->ap_txBF) {
7613 			fprintf(f, "he_su_beamformer=1\n");
7614 			fprintf(f, "he_su_beamformee=1\n");
7615 			if (dut->ap_mu_txBF)
7616 				fprintf(f, "he_mu_beamformer=1\n");
7617 		} else {
7618 			fprintf(f, "he_su_beamformer=0\n");
7619 			fprintf(f, "he_su_beamformee=0\n");
7620 			fprintf(f, "he_mu_beamformer=0\n");
7621 		}
7622 	}
7623 
7624 	fprintf(f, "interface=%s\n", ifname);
7625 	if (dut->bridge)
7626 		fprintf(f, "bridge=%s\n", dut->bridge);
7627 	fprintf(f, "channel=%d\n", dut->ap_channel);
7628 
7629 	if (sigma_hapd_ctrl)
7630 		fprintf(f, "ctrl_interface=%s\n", sigma_hapd_ctrl);
7631 	else
7632 		fprintf(f, "ctrl_interface=/var/run/hostapd\n");
7633 
7634 	if (dut->ap_ssid[0])
7635 		fprintf(f, "ssid=%s\n", dut->ap_ssid);
7636 	else
7637 		fprintf(f, "ssid=QCA AP OOB\n");
7638 	if (dut->ap_bcnint)
7639 		fprintf(f, "beacon_int=%d\n", dut->ap_bcnint);
7640 	if (dut->ap_start_disabled)
7641 		fprintf(f, "start_disabled=1\n");
7642 
7643 	if (dut->ap_akm_values) {
7644 		struct {
7645 			int akm;
7646 			const char *str;
7647 		} akms[] = {
7648 			{ AKM_WPA_EAP, "WPA-EAP" },
7649 			{ AKM_WPA_PSK, "WPA-PSK" },
7650 			{ AKM_FT_EAP, "FT-EAP" },
7651 			{ AKM_FT_PSK, "FT-PSK" },
7652 			{ AKM_EAP_SHA256, "WPA-EAP-SHA256" },
7653 			{ AKM_PSK_SHA256, "WPA-PSK-SHA256" },
7654 			{ AKM_SAE, "SAE" },
7655 			{ AKM_FT_SAE, "FT-SAE" },
7656 			{ AKM_SUITE_B, "WPA-EAP-SUITE-B-192" },
7657 			{ AKM_FT_SUITE_B, "FT-EAP-SHA384" },
7658 			{ AKM_FILS_SHA256, "FILS-SHA256" },
7659 			{ AKM_FILS_SHA384, "FILS-SHA384" },
7660 			{ AKM_FT_FILS_SHA256, "FT-FILS-SHA256" },
7661 			{ AKM_FT_FILS_SHA384, "FT-FILS-SHA384" },
7662 		};
7663 		int first = 1;
7664 		unsigned int i;
7665 
7666 		fprintf(f, "wpa_key_mgmt=");
7667 		for (i = 0; i < ARRAY_SIZE(akms); i++) {
7668 			if (dut->ap_akm_values & (1 << akms[i].akm)) {
7669 				fprintf(f, "%s%s", first ? "" : " ",
7670 					akms[i].str);
7671 				first = 0;
7672 			}
7673 		}
7674 		fprintf(f, "\n");
7675 		/* TODO: mixed mode and WPAv1 only */
7676 		fprintf(f, "wpa=2\n");
7677 		fprintf(f, "wpa_pairwise=%s\n",
7678 			hostapd_cipher_name(dut->ap_cipher));
7679 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7680 			fprintf(f, "group_cipher=%s\n",
7681 				hostapd_cipher_name(dut->ap_group_cipher));
7682 		if ((dut->ap_akm_values &
7683 		     ((1 << AKM_SAE) | (1 << AKM_FT_SAE))) &&
7684 		    !(dut->ap_akm_values &
7685 		      ((1 << AKM_WPA_PSK) | (1 << AKM_FT_PSK))) &&
7686 		    dut->ap_passphrase[0])
7687 			fprintf(f, "sae_password=%s\n", dut->ap_passphrase);
7688 		else if (!dut->ap_passphrase[0] && dut->ap_psk[0])
7689 			fprintf(f, "wpa_psk=%s", dut->ap_psk);
7690 		else if (dut->ap_passphrase[0])
7691 			fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase);
7692 		if (dut->ap_akm_values & ((1 << AKM_WPA_EAP) |
7693 					  (1 << AKM_FT_EAP) |
7694 					  (1 << AKM_EAP_SHA256) |
7695 					  (1 << AKM_SUITE_B) |
7696 					  (1 << AKM_FT_SUITE_B) |
7697 					  (1 << AKM_FILS_SHA256) |
7698 					  (1 << AKM_FILS_SHA384) |
7699 					  (1 << AKM_FT_FILS_SHA256) |
7700 					  (1 << AKM_FT_FILS_SHA384))) {
7701 			fprintf(f, "ieee8021x=1\n");
7702 			fprintf(f, "auth_server_addr=%s\n",
7703 				dut->ap_radius_ipaddr);
7704 			if (dut->ap_radius_port)
7705 				fprintf(f, "auth_server_port=%d\n",
7706 					dut->ap_radius_port);
7707 			fprintf(f, "auth_server_shared_secret=%s\n",
7708 				dut->ap_radius_password);
7709 		}
7710 		goto skip_key_mgmt;
7711 	}
7712 
7713 	switch (dut->ap_key_mgmt) {
7714 	case AP_OPEN:
7715 		if (dut->ap_cipher == AP_WEP)
7716 			fprintf(f, "wep_key0=%s\n", dut->ap_wepkey);
7717 		break;
7718 	case AP_WPA2_PSK:
7719 	case AP_WPA2_PSK_MIXED:
7720 	case AP_WPA_PSK:
7721 	case AP_WPA2_SAE:
7722 	case AP_WPA2_PSK_SAE:
7723 	case AP_WPA2_PSK_SHA256:
7724 	case AP_WPA2_FT_PSK:
7725 		if (dut->ap_key_mgmt == AP_WPA2_PSK ||
7726 		    dut->ap_key_mgmt == AP_WPA2_SAE ||
7727 		    dut->ap_key_mgmt == AP_WPA2_PSK_SAE ||
7728 		    dut->ap_key_mgmt == AP_WPA2_PSK_SHA256 ||
7729 		    dut->ap_key_mgmt == AP_WPA2_FT_PSK)
7730 			fprintf(f, "wpa=2\n");
7731 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
7732 			fprintf(f, "wpa=3\n");
7733 		else
7734 			fprintf(f, "wpa=1\n");
7735 		if (dut->ap_key_mgmt == AP_WPA2_SAE)
7736 			key_mgmt = "SAE";
7737 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
7738 			key_mgmt = "WPA-PSK SAE";
7739 		else
7740 			key_mgmt = "WPA-PSK";
7741 		switch (dut->ap_pmf) {
7742 		case AP_PMF_DISABLED:
7743 			fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt,
7744 				dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
7745 			break;
7746 		case AP_PMF_OPTIONAL:
7747 			fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt,
7748 				dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
7749 			break;
7750 		case AP_PMF_REQUIRED:
7751 			if (dut->ap_key_mgmt == AP_WPA2_SAE)
7752 				key_mgmt = "SAE";
7753 			else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
7754 				key_mgmt = "WPA-PSK-SHA256 SAE";
7755 			else
7756 				key_mgmt = "WPA-PSK-SHA256";
7757 			fprintf(f, "wpa_key_mgmt=%s\n", key_mgmt);
7758 			break;
7759 		}
7760 		if (dut->ap_key_mgmt == AP_WPA2_PSK_SHA256)
7761 			fprintf(f, "wpa_key_mgmt=WPA-PSK-SHA256\n");
7762 		else if (dut->ap_key_mgmt == AP_WPA2_FT_PSK)
7763 			fprintf(f, "wpa_key_mgmt=FT-PSK\n");
7764 		fprintf(f, "wpa_pairwise=%s\n",
7765 			hostapd_cipher_name(dut->ap_cipher));
7766 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7767 			fprintf(f, "group_cipher=%s\n",
7768 				hostapd_cipher_name(dut->ap_group_cipher));
7769 		if (dut->ap_key_mgmt == AP_WPA2_SAE)
7770 			fprintf(f, "sae_password=%s\n", dut->ap_passphrase);
7771 		else if (!dut->ap_passphrase[0] && dut->ap_psk[0])
7772 			fprintf(f, "wpa_psk=%s", dut->ap_psk);
7773 		else
7774 			fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase);
7775 		break;
7776 	case AP_WPA2_EAP:
7777 	case AP_WPA2_EAP_MIXED:
7778 	case AP_WPA_EAP:
7779 	case AP_WPA2_EAP_OSEN:
7780 	case AP_WPA2_EAP_SHA256:
7781 	case AP_WPA2_FT_EAP:
7782 	case AP_WPA2_ENT_FT_EAP:
7783 		fprintf(f, "ieee8021x=1\n");
7784 		if (dut->ap_key_mgmt == AP_WPA2_EAP ||
7785 		    dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ||
7786 		    dut->ap_key_mgmt == AP_WPA2_EAP_SHA256 ||
7787 		    dut->ap_key_mgmt == AP_WPA2_FT_EAP ||
7788 		    dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP)
7789 			fprintf(f, "wpa=2\n");
7790 		else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
7791 			fprintf(f, "wpa=3\n");
7792 		else
7793 			fprintf(f, "wpa=1\n");
7794 		switch (dut->ap_pmf) {
7795 		case AP_PMF_DISABLED:
7796 			fprintf(f, "wpa_key_mgmt=WPA-EAP%s\n",
7797 				dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "");
7798 			break;
7799 		case AP_PMF_OPTIONAL:
7800 			fprintf(f, "wpa_key_mgmt=WPA-EAP%s%s\n",
7801 				dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "",
7802 				dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" :
7803 				"");
7804 			break;
7805 		case AP_PMF_REQUIRED:
7806 			fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256%s\n",
7807 				dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" :
7808 				"");
7809 			break;
7810 		}
7811 		if (dut->ap_key_mgmt == AP_WPA2_EAP_SHA256)
7812 			fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256\n");
7813 		else if (dut->ap_key_mgmt == AP_WPA2_FT_EAP)
7814 			fprintf(f, "wpa_key_mgmt=FT-EAP\n");
7815 		else if (dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP)
7816 			fprintf(f, "wpa_key_mgmt=FT-EAP WPA-EAP\n");
7817 		fprintf(f, "wpa_pairwise=%s\n",
7818 			hostapd_cipher_name(dut->ap_cipher));
7819 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7820 			fprintf(f, "group_cipher=%s\n",
7821 				hostapd_cipher_name(dut->ap_group_cipher));
7822 		fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
7823 		if (dut->ap_radius_port)
7824 			fprintf(f, "auth_server_port=%d\n",
7825 				dut->ap_radius_port);
7826 		fprintf(f, "auth_server_shared_secret=%s\n",
7827 			dut->ap_radius_password);
7828 		if (dut->program == PROGRAM_HS2_R3) {
7829 			fprintf(f, "radius_das_port=3799\n");
7830 			fprintf(f, "radius_das_client=0.0.0.0 %s\n",
7831 				dut->ap_radius_password);
7832 			fprintf(f, "radius_das_require_event_timestamp=1\n");
7833 		}
7834 		break;
7835 	case AP_SUITEB:
7836 		fprintf(f, "ieee8021x=1\n");
7837 		fprintf(f, "wpa=2\n");
7838 		fprintf(f, "wpa_key_mgmt=WPA-EAP-SUITE-B-192\n");
7839 		fprintf(f, "wpa_pairwise=%s\n",
7840 			hostapd_cipher_name(dut->ap_cipher));
7841 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7842 			fprintf(f, "group_cipher=%s\n",
7843 				hostapd_cipher_name(dut->ap_group_cipher));
7844 		if (dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET)
7845 			fprintf(f, "group_mgmt_cipher=%s\n",
7846 				hostapd_group_mgmt_cipher_name(
7847 					dut->ap_group_mgmt_cipher));
7848 		fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
7849 		if (dut->ap_radius_port)
7850 			fprintf(f, "auth_server_port=%d\n",
7851 				dut->ap_radius_port);
7852 		fprintf(f, "auth_server_shared_secret=%s\n",
7853 			dut->ap_radius_password);
7854 		break;
7855 	case AP_WPA2_OWE:
7856 		fprintf(f, "wpa=2\n");
7857 		fprintf(f, "wpa_key_mgmt=OWE\n");
7858 		fprintf(f, "rsn_pairwise=%s\n",
7859 			hostapd_cipher_name(dut->ap_cipher));
7860 		if (dut->ap_sae_groups) {
7861 			fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups);
7862 			if (dut->owe_ptk_workaround)
7863 				fprintf(f, "owe_ptk_workaround=1\n");
7864 		}
7865 		break;
7866 	case AP_OSEN:
7867 		fprintf(f, "osen=1\n");
7868 		fprintf(f, "disable_dgaf=1\n");
7869 		fprintf(f, "wpa_pairwise=%s\n",
7870 			hostapd_cipher_name(dut->ap_cipher));
7871 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7872 			fprintf(f, "group_cipher=%s\n",
7873 				hostapd_cipher_name(dut->ap_group_cipher));
7874 		fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
7875 		if (dut->ap_radius_port)
7876 			fprintf(f, "auth_server_port=%d\n",
7877 				dut->ap_radius_port);
7878 		fprintf(f, "auth_server_shared_secret=%s\n",
7879 			dut->ap_radius_password);
7880 		break;
7881 	}
7882 skip_key_mgmt:
7883 
7884 	if (dut->ap_sae_passwords) {
7885 		char *tmp, *pos, *end, *id;
7886 
7887 		tmp = strdup(dut->ap_sae_passwords);
7888 		if (!tmp) {
7889 			fclose(f);
7890 			return ERROR_SEND_STATUS;
7891 		}
7892 
7893 		pos = tmp;
7894 		while (*pos) {
7895 			end = strchr(pos, ';');
7896 			if (end)
7897 				*end = '\0';
7898 			id = strchr(pos, ':');
7899 			if (id)
7900 				*id++ = '\0';
7901 
7902 			fprintf(f, "sae_password=%s%s%s\n",
7903 				pos, id ? "|id=" : "", id ? id : "");
7904 			if (!end)
7905 				break;
7906 			pos = end + 1;
7907 		}
7908 
7909 		free(tmp);
7910 	}
7911 
7912 	if (dut->ap_rsn_preauth)
7913 		fprintf(f, "rsn_preauth=1\n");
7914 
7915 	if (dut->ap_pmksa && dut->ap_pmksa_caching)
7916 		fprintf(f, "disable_pmksa_caching=1\n");
7917 
7918 	if (dut->ap_beacon_prot)
7919 		fprintf(f, "beacon_prot=1\n");
7920 
7921 	if (dut->ap_transition_disable)
7922 		fprintf(f, "transition_disable=0x%02x\n",
7923 			dut->ap_transition_disable);
7924 
7925 	if (dut->ap_ocvc == 1 || dut->ap_ocvc == 0)
7926 		fprintf(f, "ocv=%d\n", dut->ap_ocvc);
7927 
7928 	switch (dut->ap_pmf) {
7929 	case AP_PMF_DISABLED:
7930 		break;
7931 	case AP_PMF_OPTIONAL:
7932 		fprintf(f, "ieee80211w=1\n");
7933 		if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE ||
7934 		    (dut->ap_akm_values & (AKM_SAE | AKM_WPA_PSK)) ==
7935 		    (AKM_SAE | AKM_WPA_PSK))
7936 			fprintf(f, "sae_require_mfp=1\n");
7937 		break;
7938 	case AP_PMF_REQUIRED:
7939 		fprintf(f, "ieee80211w=2\n");
7940 		break;
7941 	}
7942 
7943 	if (dut->ap_pmf != AP_PMF_DISABLED &&
7944 	    dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET)
7945 		fprintf(f, "group_mgmt_cipher=%s\n",
7946 			hostapd_group_mgmt_cipher_name(
7947 				dut->ap_group_mgmt_cipher));
7948 
7949 	if (ap_ft_enabled(dut)) {
7950 		unsigned char own_addr[ETH_ALEN];
7951 
7952 		fprintf(f, "mobility_domain=%s\n", dut->ap_mobility_domain);
7953 		fprintf(f, "ft_over_ds=%d\n", dut->ap_ft_ds == VALUE_ENABLED);
7954 		if (get_hwaddr(ifname, own_addr) < 0) {
7955 			memset(own_addr, 0, ETH_ALEN);
7956 			own_addr[0] = 0x02;
7957 		}
7958 		fprintf(f,
7959 			"nas_identifier=%02x%02x%02x%02x%02x%02x.nas.example.com\n",
7960 			own_addr[0], own_addr[1], own_addr[2],
7961 			own_addr[3], own_addr[4], own_addr[5]);
7962 		fprintf(f, "r1_key_holder=%02x%02x%02x%02x%02x%02x\n",
7963 			own_addr[0], own_addr[1], own_addr[2],
7964 			own_addr[3], own_addr[4], own_addr[5]);
7965 		fprintf(f, "ft_psk_generate_local=1\n");
7966 		fprintf(f, "pmk_r1_push=0\n");
7967 		fprintf(f,
7968 			"r0kh=ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n");
7969 		fprintf(f,
7970 			"r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n");
7971 	}
7972 
7973 	if (dut->rsne_override)
7974 		fprintf(f, "own_ie_override=%s\n", dut->rsne_override);
7975 	if (dut->rsnxe_override_eapol)
7976 		fprintf(f, "rsnxe_override_eapol=%s\n",
7977 			dut->rsnxe_override_eapol);
7978 
7979 	if (dut->sae_commit_override)
7980 		fprintf(f, "sae_commit_override=%s\n",
7981 			dut->sae_commit_override);
7982 
7983 	if (dut->ap_sae_groups)
7984 		fprintf(f, "sae_groups=%s\n", dut->ap_sae_groups);
7985 
7986 	if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) {
7987 		const char *sae_pwe = NULL;
7988 
7989 		if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut))
7990 			sae_pwe = "3";
7991 		else if (dut->sae_pwe == SAE_PWE_LOOP)
7992 			sae_pwe = "0";
7993 		else if (dut->sae_pwe == SAE_PWE_H2E)
7994 			sae_pwe = "1";
7995 		else if (dut->sae_h2e_default)
7996 			sae_pwe = "2";
7997 		if (sae_pwe)
7998 			fprintf(f, "sae_pwe=%s\n", sae_pwe);
7999 	}
8000 
8001 	if (dut->sae_anti_clogging_threshold >= 0)
8002 		fprintf(f, "sae_anti_clogging_threshold=%d\n",
8003 			dut->sae_anti_clogging_threshold);
8004 	if (dut->sae_reflection)
8005 		fprintf(f, "sae_reflection_attack=1\n");
8006 	if (dut->sae_confirm_immediate)
8007 		fprintf(f, "sae_confirm_immediate=2\n");
8008 
8009 	if (dut->ap_p2p_mgmt)
8010 		fprintf(f, "manage_p2p=1\n");
8011 
8012 	if (dut->ap_tdls_prohibit || dut->ap_l2tif)
8013 		fprintf(f, "tdls_prohibit=1\n");
8014 	if (dut->ap_tdls_prohibit_chswitch || dut->ap_l2tif)
8015 		fprintf(f, "tdls_prohibit_chan_switch=1\n");
8016 	if (dut->ap_p2p_cross_connect >= 0) {
8017 		fprintf(f, "manage_p2p=1\n"
8018 			"allow_cross_connection=%d\n",
8019 			dut->ap_p2p_cross_connect);
8020 	}
8021 
8022 	if (dut->ap_l2tif || dut->ap_proxy_arp ||
8023 	    dut->ap_key_mgmt == AP_WPA2_EAP_OSEN) {
8024 		if (!dut->bridge) {
8025 			sigma_dut_print(dut, DUT_MSG_ERROR,
8026 					"Bridge must be configured. Run with -b <brname>.");
8027 			fclose(f);
8028 			return -2;
8029 		}
8030 		fprintf(f, "ap_isolate=1\n");
8031 	}
8032 
8033 	if (dut->ap_proxy_arp)
8034 		fprintf(f, "proxy_arp=1\n");
8035 
8036 	if (dut->ap_wme)
8037 		fprintf(f, "wmm_enabled=1\n");
8038 
8039 	if (dut->ap_wmmps == AP_WMMPS_ON)
8040 		fprintf(f, "uapsd_advertisement_enabled=1\n");
8041 
8042 	if (dut->ap_hs2) {
8043 		if (dut->ap_bss_load) {
8044 			char *bss_load;
8045 
8046 			switch (dut->ap_bss_load) {
8047 			case -1:
8048 				bss_load = "bss_load_update_period=10";
8049 				break;
8050 			case 1:
8051 				/* STA count: 1, CU: 50, AAC: 65535 */
8052 				bss_load = "bss_load_test=1:50:65535";
8053 				break;
8054 			case 2:
8055 				/* STA count: 1, CU: 200, AAC: 65535 */
8056 				bss_load = "bss_load_test=1:200:65535";
8057 				break;
8058 			case 3:
8059 				/* STA count: 1, CU: 75, AAC: 65535 */
8060 				bss_load = "bss_load_test=1:75:65535";
8061 				break;
8062 			default:
8063 				bss_load = NULL;
8064 				break;
8065 			}
8066 
8067 			if (!bss_load) {
8068 				fclose(f);
8069 				return -2;
8070 			}
8071 			fprintf(f, "%s\n", bss_load);
8072 		}
8073 
8074 		if (append_hostapd_conf_hs2(dut, f)) {
8075 			fclose(f);
8076 			return -2;
8077 		}
8078 	}
8079 
8080 	if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) {
8081 		fclose(f);
8082 		return -2;
8083 	}
8084 
8085 	if (dut->ap_hs2 && strlen(dut->ap_tag_ssid[0])) {
8086 		unsigned char bssid[6];
8087 		char ifname2[50];
8088 
8089 		if (get_hwaddr(ifname, bssid)) {
8090 			fclose(f);
8091 			return -2;
8092 		}
8093 		if (bssid[0] & 0x02)
8094 			bssid[5] ^= 0x01;
8095 		else
8096 			bssid[0] |= 0x02;
8097 
8098 		snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8099 		fprintf(f, "bss=%s\n", ifname2);
8100 		fprintf(f, "ssid=%s\n", dut->ap_tag_ssid[0]);
8101 		if (dut->bridge)
8102 			fprintf(f, "bridge=%s\n", dut->bridge);
8103 
8104 		if (drv == DRIVER_LINUX_WCN)
8105 			fprintf(f, "use_driver_iface_addr=1\n");
8106 		else
8107 			fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8108 				bssid[0], bssid[1], bssid[2], bssid[3],
8109 				bssid[4], bssid[5]);
8110 
8111 		if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) {
8112 			fprintf(f, "osen=1\n");
8113 			/* Disable DGAF for OSEN BSS */
8114 			fprintf(f, "disable_dgaf=1\n");
8115 			fprintf(f, "ap_isolate=1\n");
8116 			if (strlen(dut->ap2_radius_ipaddr))
8117 				fprintf(f, "auth_server_addr=%s\n",
8118 					dut->ap2_radius_ipaddr);
8119 			if (dut->ap2_radius_port)
8120 				fprintf(f, "auth_server_port=%d\n",
8121 					dut->ap2_radius_port);
8122 			if (strlen(dut->ap2_radius_password))
8123 				fprintf(f, "auth_server_shared_secret=%s\n",
8124 					dut->ap2_radius_password);
8125 
8126 			set_ebtables_forward_drop(dut, ifname, ifname2);
8127 		} else if (dut->ap2_osu) {
8128 			fprintf(f, "ap_isolate=1\n");
8129 			set_ebtables_forward_drop(dut, ifname, ifname2);
8130 		}
8131 
8132 		if (dut->ap2_proxy_arp) {
8133 			if (!dut->bridge) {
8134 				sigma_dut_print(dut, DUT_MSG_ERROR,
8135 						"Bridge must be configured. Run with -b <brname>.");
8136 				fclose(f);
8137 				return -2;
8138 			}
8139 			fprintf(f, "ap_isolate=1\n");
8140 			fprintf(f, "proxy_arp=1\n");
8141 
8142 			if (set_ebtables_proxy_arp(dut, "FORWARD", ifname2) ||
8143 			    set_ebtables_proxy_arp(dut, "OUTPUT", ifname2)) {
8144 				fclose(f);
8145 				return -2;
8146 			}
8147 
8148 		}
8149 	}
8150 
8151 	if (dut->program == PROGRAM_WPS) {
8152 		/* 60G WPS tests requires wps_state of 2 (configured) */
8153 		int wps_state = is_60g_sigma_dut(dut) ? 2 : 1;
8154 
8155 		fprintf(f, "eap_server=1\n"
8156 			"wps_state=%d\n"
8157 			"device_name=QCA AP\n"
8158 			"manufacturer=QCA\n"
8159 			"device_type=6-0050F204-1\n"
8160 			"config_methods=label virtual_display %s"
8161 			"virtual_push_button keypad%s\n"
8162 			"ap_pin=12345670\n"
8163 			"friendly_name=QCA Access Point\n"
8164 			"upnp_iface=%s\n",
8165 			wps_state,
8166 			is_60g_sigma_dut(dut) ? "physical_display " : "",
8167 			dut->ap_wpsnfc ? " nfc_interface ext_nfc_token" : "",
8168 			dut->bridge ? dut->bridge : ifname);
8169 		if (dut->wsc_fragment) {
8170 			fprintf(f, "device_name=%s\n"
8171 				"manufacturer=%s\n"
8172 				"model_name=%s\n"
8173 				"model_number=%s\n"
8174 				"serial_number=%s\n",
8175 				WPS_LONG_DEVICE_NAME,
8176 				WPS_LONG_MANUFACTURER,
8177 				WPS_LONG_MODEL_NAME,
8178 				WPS_LONG_MODEL_NUMBER,
8179 				WPS_LONG_SERIAL_NUMBER);
8180 		} else {
8181 			fprintf(f, "device_name=QCA AP\n"
8182 				"manufacturer=QCA\n");
8183 		}
8184 		if (dut->eap_fragment)
8185 			fprintf(f, "fragment_size=128\n");
8186 	}
8187 
8188 	if (dut->ap_dpp_conf_addr && dut->ap_dpp_conf_pkhash)
8189 		fprintf(f, "dpp_controller=ipaddr=%s pkhash=%s\n",
8190 			dut->ap_dpp_conf_addr, dut->ap_dpp_conf_pkhash);
8191 
8192 	if (dut->ap_he_rtsthrshld == VALUE_ENABLED)
8193 		fprintf(f, "he_rts_threshold=512\n");
8194 	else if (dut->ap_he_rtsthrshld == VALUE_DISABLED)
8195 		fprintf(f, "he_rts_threshold=1024\n");
8196 
8197 	if ((dut->program == PROGRAM_VHT) ||
8198 	    (dut->program == PROGRAM_HE && dut->use_5g)) {
8199 		int vht_oper_centr_freq_idx;
8200 
8201 		if (check_channel(dut->ap_channel) < 0) {
8202 			send_resp(dut, conn, SIGMA_INVALID,
8203 				  "errorCode,Invalid channel");
8204 			fclose(f);
8205 			return 0;
8206 		}
8207 
8208 		switch (dut->ap_chwidth) {
8209 		case AP_20:
8210 			dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH;
8211 			vht_oper_centr_freq_idx =
8212 				get_oper_centr_freq_seq_idx(20,
8213 							    dut->ap_channel);
8214 			break;
8215 		case AP_40:
8216 			dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH;
8217 			vht_oper_centr_freq_idx =
8218 				get_oper_centr_freq_seq_idx(40,
8219 							    dut->ap_channel);
8220 			break;
8221 		case AP_80:
8222 			dut->ap_vht_chwidth = AP_80_VHT_OPER_CHWIDTH;
8223 			vht_oper_centr_freq_idx =
8224 				get_oper_centr_freq_seq_idx(80,
8225 							    dut->ap_channel);
8226 			break;
8227 		case AP_160:
8228 			dut->ap_vht_chwidth = AP_160_VHT_OPER_CHWIDTH;
8229 			vht_oper_centr_freq_idx =
8230 				get_oper_centr_freq_seq_idx(160,
8231 							    dut->ap_channel);
8232 			break;
8233 		default:
8234 			dut->ap_vht_chwidth = VHT_DEFAULT_OPER_CHWIDTH;
8235 			vht_oper_centr_freq_idx =
8236 				get_oper_centr_freq_seq_idx(80,
8237 							    dut->ap_channel);
8238 			break;
8239 		}
8240 		fprintf(f, "vht_oper_centr_freq_seg0_idx=%d\n",
8241 			vht_oper_centr_freq_idx);
8242 		fprintf(f, "vht_oper_chwidth=%d\n", dut->ap_vht_chwidth);
8243 		if (dut->ap_mode == AP_11ax) {
8244 			fprintf(f, "he_oper_chwidth=%d\n", dut->ap_vht_chwidth);
8245 			fprintf(f, "he_oper_centr_freq_seg0_idx=%d\n",
8246 				vht_oper_centr_freq_idx);
8247 		}
8248 
8249 		if (dut->ap_sgi80 || dut->ap_txBF ||
8250 		    dut->ap_ldpc != VALUE_NOT_SET ||
8251 		    dut->ap_tx_stbc || dut->ap_mu_txBF) {
8252 			fprintf(f, "vht_capab=%s%s%s%s%s\n",
8253 				dut->ap_sgi80 ? "[SHORT-GI-80]" : "",
8254 				dut->ap_txBF ?
8255 				"[SU-BEAMFORMER][SU-BEAMFORMEE][BF-ANTENNA-2][SOUNDING-DIMENSION-2]" : "",
8256 				(dut->ap_ldpc == VALUE_ENABLED) ?
8257 				"[RXLDPC]" : "",
8258 				dut->ap_tx_stbc ? "[TX-STBC-2BY1]" : "",
8259 				dut->ap_mu_txBF ? "[MU-BEAMFORMER]" : "");
8260 		}
8261 	}
8262 
8263 	if (dut->ap_key_mgmt == AP_WPA2_OWE && dut->ap_tag_ssid[0][0] &&
8264 	    dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
8265 		/* OWE transition mode */
8266 		unsigned char bssid[6];
8267 		char ifname2[50];
8268 		unsigned long val;
8269 		FILE *f2;
8270 
8271 		snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8272 
8273 		fprintf(f, "owe_transition_ifname=%s\n", ifname2);
8274 		val = 0x12345678; /* default to something */
8275 		f2 = fopen("/dev/urandom", "r");
8276 		if (f2) {
8277 			if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) {
8278 				sigma_dut_print(dut, DUT_MSG_ERROR,
8279 						"Could not read /dev/urandom");
8280 			}
8281 			fclose(f2);
8282 		}
8283 		fprintf(f, "ssid=owe-%lx\n", val);
8284 		fprintf(f, "ignore_broadcast_ssid=1\n");
8285 
8286 		if (get_hwaddr(ifname, bssid)) {
8287 			fclose(f);
8288 			return -2;
8289 		}
8290 		if (bssid[0] & 0x02)
8291 			bssid[5] ^= 0x01;
8292 		else
8293 			bssid[0] |= 0x02;
8294 
8295 		fprintf(f, "bss=%s\n", ifname2);
8296 		fprintf(f, "ssid=%s\n", dut->ap_ssid);
8297 		if (dut->bridge)
8298 			fprintf(f, "bridge=%s\n", dut->bridge);
8299 		if (drv == DRIVER_LINUX_WCN)
8300 			fprintf(f, "use_driver_iface_addr=1\n");
8301 		else
8302 			fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8303 				bssid[0], bssid[1], bssid[2], bssid[3],
8304 				bssid[4], bssid[5]);
8305 		fprintf(f, "owe_transition_ifname=%s\n", ifname);
8306 	}
8307 
8308 	if (dut->ap_key_mgmt == AP_OPEN &&
8309 	    dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
8310 		/* OWE transition mode */
8311 		unsigned char bssid[6];
8312 		char ifname2[50];
8313 		unsigned long val;
8314 		FILE *f2;
8315 
8316 		snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8317 
8318 		fprintf(f, "owe_transition_ifname=%s\n", ifname2);
8319 		fprintf(f, "ssid=%s\n", dut->ap_ssid);
8320 
8321 		if (get_hwaddr(ifname, bssid)) {
8322 			fclose(f);
8323 			return -2;
8324 		}
8325 		if (bssid[0] & 0x02)
8326 			bssid[5] ^= 0x01;
8327 		else
8328 			bssid[0] |= 0x02;
8329 
8330 		fprintf(f, "bss=%s\n", ifname2);
8331 		val = 0x12345678; /* default to something */
8332 		f2 = fopen("/dev/urandom", "r");
8333 		if (f2) {
8334 			if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) {
8335 				sigma_dut_print(dut, DUT_MSG_ERROR,
8336 						"Could not read /dev/urandom");
8337 			}
8338 			fclose(f2);
8339 		}
8340 		fprintf(f, "ssid=owe-%lx\n", val);
8341 		if (dut->bridge)
8342 			fprintf(f, "bridge=%s\n", dut->bridge);
8343 		if (drv == DRIVER_LINUX_WCN)
8344 			fprintf(f, "use_driver_iface_addr=1\n");
8345 		else
8346 			fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8347 				bssid[0], bssid[1], bssid[2], bssid[3],
8348 				bssid[4], bssid[5]);
8349 		fprintf(f, "owe_transition_ifname=%s\n", ifname);
8350 		fprintf(f, "wpa=2\n");
8351 		fprintf(f, "wpa_key_mgmt=OWE\n");
8352 		fprintf(f, "rsn_pairwise=CCMP\n");
8353 		fprintf(f, "ieee80211w=2\n");
8354 		fprintf(f, "ignore_broadcast_ssid=1\n");
8355 		if (dut->ap_sae_groups) {
8356 			fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups);
8357 			if (dut->owe_ptk_workaround)
8358 				fprintf(f, "owe_ptk_workaround=1\n");
8359 		}
8360 	}
8361 
8362 	if (dut->program == PROGRAM_OCE) {
8363 		fprintf(f, "oce=%d\n",
8364 			dut->dev_role == DEVROLE_STA_CFON ? 2 : 1);
8365 	}
8366 	fclose(f);
8367 	if (dut->use_hostapd_pid_file)
8368 		kill_hostapd_process_pid(dut);
8369 #ifdef __QNXNTO__
8370 	if (system("slay hostapd") == 0)
8371 #else /* __QNXNTO__ */
8372 	if (!dut->use_hostapd_pid_file &&
8373 	    (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
8374 	     system("killall hostapd") == 0))
8375 #endif /* __QNXNTO__ */
8376 	{
8377 		int i;
8378 		/* Wait some time to allow hostapd to complete cleanup before
8379 		 * starting a new process */
8380 		for (i = 0; i < 10; i++) {
8381 			usleep(500000);
8382 #ifdef __QNXNTO__
8383 			if (system("pidin | grep hostapd") != 0)
8384 				break;
8385 #else /* __QNXNTO__ */
8386 			if (system("pidof hostapd") != 0)
8387 				break;
8388 #endif /* __QNXNTO__ */
8389 		}
8390 	}
8391 	dut->hostapd_running = 0;
8392 
8393 #ifdef ANDROID
8394 	/* Set proper conf file permissions so that hostapd process
8395 	 * can access it.
8396 	 */
8397 	if (chmod(ap_conf_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0)
8398 		sigma_dut_print(dut, DUT_MSG_ERROR,
8399 				"Error changing permissions");
8400 
8401 	gr = getgrnam("wifi");
8402 	if (!gr || chown(ap_conf_path, -1, gr->gr_gid) < 0)
8403 		sigma_dut_print(dut, DUT_MSG_ERROR, "Error changing groupid");
8404 #endif /* ANDROID */
8405 
8406 	f = fopen(ap_conf_path, "r");
8407 	if (f) {
8408 		size_t len;
8409 
8410 		len = fread(buf, 1, sizeof(buf), f);
8411 		fclose(f);
8412 		if (len >= sizeof(buf))
8413 			len = sizeof(buf) - 1;
8414 		buf[len] = '\0';
8415 		sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd debug log:\n%s",
8416 				buf);
8417 	}
8418 
8419 	if (drv == DRIVER_QNXNTO) {
8420 		snprintf(buf, sizeof(buf),
8421 			 "hostapd -B %s%s%s %s%s %s/sigma_dut-ap.conf",
8422 			 dut->hostapd_debug_log ? "-dddKt " : "",
8423 			 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ?
8424 			 "-f " : "",
8425 			 dut->hostapd_debug_log ? dut->hostapd_debug_log : "",
8426 			 dut->hostapd_entropy_log ? " -e" : "",
8427 			 dut->hostapd_entropy_log ? dut->hostapd_entropy_log :
8428 			 "",
8429 			 dut->sigma_tmpdir);
8430 	} else {
8431 		/*
8432 		 * It looks like a monitor interface can cause some issues for
8433 		 * beaconing, so remove it (if injection was used) before
8434 		 * starting hostapd.
8435 		 */
8436 		if (if_nametoindex("sigmadut") > 0 &&
8437 		    system("iw dev sigmadut del") != 0)
8438 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove "
8439 					"monitor interface");
8440 
8441 		snprintf(path, sizeof(path), "%shostapd",
8442 			 file_exists("hostapd") ? "./" : "");
8443 		snprintf(buf, sizeof(buf),
8444 			 "%s -B%s%s%s%s%s%s %s/sigma_dut-ap.conf",
8445 			 dut->hostapd_bin ? dut->hostapd_bin : path,
8446 			 dut->hostapd_debug_log ? " -dddKt" : "",
8447 			 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ?
8448 			 " -f " : "",
8449 			 dut->hostapd_debug_log ? dut->hostapd_debug_log : "",
8450 			 dut->hostapd_entropy_log ? " -e" : "",
8451 			 dut->hostapd_entropy_log ? dut->hostapd_entropy_log :
8452 			 "",
8453 			 dut->use_hostapd_pid_file ?
8454 			 " -P " SIGMA_DUT_HOSTAPD_PID_FILE : "",
8455 			 dut->sigma_tmpdir);
8456 	}
8457 
8458 	sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd command: %s", buf);
8459 	if (system(buf) != 0) {
8460 		send_resp(dut, conn, SIGMA_ERROR,
8461 			  "errorCode,Failed to start hostapd");
8462 		return 0;
8463 	}
8464 
8465 	/* allow some time for hostapd to start before returning success */
8466 	usleep(500000);
8467 	if (run_hostapd_cli(dut, "ping") != 0) {
8468 		send_resp(dut, conn, SIGMA_ERROR,
8469 			  "errorCode,Failed to talk to hostapd");
8470 		return 0;
8471 	}
8472 
8473 	if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) {
8474 		int buf_size;
8475 
8476 		if (dut->ap_ba_bufsize == BA_BUFSIZE_256)
8477 			buf_size = 256;
8478 		else
8479 			buf_size = 64;
8480 
8481 		if ((drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) &&
8482 		    sta_set_addba_buf_size(dut, ifname, buf_size)) {
8483 			send_resp(dut, conn, SIGMA_ERROR,
8484 				  "ErrorCode,set_addba_buf_size failed");
8485 			return STATUS_SENT_ERROR;
8486 		}
8487 
8488 		sigma_dut_print(dut, DUT_MSG_INFO,
8489 				"setting addba buf_size=%d", buf_size);
8490 	}
8491 
8492 	if (drv == DRIVER_LINUX_WCN) {
8493 		const char *ifname_ptr = ifname;
8494 
8495 		if ((dut->ap_key_mgmt == AP_OPEN &&
8496 		     dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) ||
8497 		    (dut->ap_key_mgmt == AP_WPA2_OWE &&
8498 		     dut->ap_tag_ssid[0][0] &&
8499 		     dut->ap_tag_key_mgmt[0] == AP2_OPEN)) {
8500 			/* OWE transition mode */
8501 			if (dut->bridge)
8502 				ifname_ptr = dut->bridge;
8503 		}
8504 
8505 		sigma_dut_print(dut, DUT_MSG_INFO,
8506 				"setting ip addr %s mask %s ifname %s",
8507 				ap_inet_addr, ap_inet_mask, ifname_ptr);
8508 		snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up",
8509 			 ifname_ptr, ap_inet_addr, ap_inet_mask);
8510 		if (system(buf) != 0) {
8511 			sigma_dut_print(dut, DUT_MSG_ERROR,
8512 					"Failed to initialize the interface");
8513 			return -1;
8514 		}
8515 	}
8516 
8517 	/* Configure the driver with LDPC setting for AP mode as a new vdev is
8518 	 * created when hostapd is started.
8519 	 */
8520 	if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN)
8521 		wcn_config_ap_ldpc(dut, ifname);
8522 
8523 	if (dut->ap_l2tif) {
8524 		snprintf(path, sizeof(path),
8525 			 "/sys/class/net/%s/brport/hairpin_mode",
8526 			 ifname);
8527 		if (!file_exists(path)) {
8528 			sigma_dut_print(dut, DUT_MSG_ERROR,
8529 					"%s must be binded to the bridge for L2TIF",
8530 					ifname);
8531 			return -2;
8532 		}
8533 
8534 		snprintf(buf, sizeof(buf), "echo 1 > %s", path);
8535 		if (system(buf) != 0) {
8536 			sigma_dut_print(dut, DUT_MSG_ERROR,
8537 				"Failed to enable hairpin_mode for L2TIF");
8538 			return -2;
8539 		}
8540 
8541 		snprintf(buf, sizeof(buf), "ebtables -P FORWARD ACCEPT");
8542 		if (system(buf) != 0) {
8543 			sigma_dut_print(dut, DUT_MSG_ERROR,
8544 					"Failed to set ebtables rules, RULE-9");
8545 			return -2;
8546 		}
8547 
8548 		snprintf(buf, sizeof(buf),
8549 			 "ebtables -A FORWARD -p IPv4 --ip-proto icmp -i %s -j DROP",
8550 			 ifname);
8551 		if (system(buf) != 0) {
8552 			sigma_dut_print(dut, DUT_MSG_ERROR,
8553 					"Failed to set ebtables rules, RULE-11");
8554 			return -2;
8555 		}
8556 	}
8557 
8558 	if (dut->ap_proxy_arp) {
8559 		if (dut->ap_dgaf_disable) {
8560 			if (set_ebtables_disable_dgaf(dut, "FORWARD", ifname) ||
8561 			    set_ebtables_disable_dgaf(dut, "OUTPUT", ifname))
8562 				return -2;
8563 		} else {
8564 			if (set_ebtables_proxy_arp(dut, "FORWARD", ifname) ||
8565 			    set_ebtables_proxy_arp(dut, "OUTPUT", ifname))
8566 				return -2;
8567 		}
8568 
8569 		/* For 4.5-(c) */
8570 		snprintf(buf, sizeof(buf),
8571 			 "ebtables -A FORWARD -p ARP --arp-opcode 2 -i %s -j DROP",
8572 			 ifname);
8573 		if (system(buf) != 0) {
8574 			sigma_dut_print(dut, DUT_MSG_ERROR,
8575 					"Failed to set ebtables rules, RULE-10");
8576 			return -2;
8577 		}
8578 	}
8579 
8580 	if (dut->ap_tdls_prohibit || dut->ap_l2tif) {
8581 		/* Drop TDLS frames */
8582 		snprintf(buf, sizeof(buf),
8583 			 "ebtables -A FORWARD -p 0x890d -i %s -j DROP", ifname);
8584 		if (system(buf) != 0) {
8585 			sigma_dut_print(dut, DUT_MSG_ERROR,
8586 					"Failed to set ebtables rules, RULE-13");
8587 			return -2;
8588 		}
8589 	}
8590 
8591 	if (dut->ap_fake_pkhash &&
8592 	    run_hostapd_cli(dut, "set wps_corrupt_pkhash 1") != 0) {
8593 		send_resp(dut, conn, SIGMA_ERROR,
8594 			  "errorCode,Could not enable FakePubKey");
8595 		return 0;
8596 	}
8597 
8598 	if (dut->program == PROGRAM_60GHZ) {
8599 		if (dut->ap_num_ese_allocs > 0) {
8600 			/* wait extra time for AP to start */
8601 			sleep(2);
8602 			if (ap_set_60g_ese(dut, dut->ap_num_ese_allocs,
8603 					   dut->ap_ese_allocs)) {
8604 				send_resp(dut, conn, SIGMA_ERROR,
8605 					  "errorCode,Could not set ExtSch");
8606 				return 0;
8607 			}
8608 		}
8609 		if (dut->ap_fixed_rate) {
8610 			sigma_dut_print(dut, DUT_MSG_DEBUG,
8611 					"forcing TX MCS index %d",
8612 					dut->ap_mcs);
8613 			if (ap_set_force_mcs(dut, 1, dut->ap_mcs)) {
8614 				send_resp(dut, conn, SIGMA_ERROR,
8615 					  "errorCode,Could not force MCS");
8616 				return -2;
8617 			}
8618 		}
8619 	}
8620 
8621 	if (dut->wps_forced_version) {
8622 		snprintf(buf, sizeof(buf), "SET wps_version_number %d",
8623 			 dut->wps_forced_version);
8624 		if (hapd_command(ifname, buf) < 0) {
8625 			send_resp(dut, conn, SIGMA_ERROR,
8626 				  "errorCode,Fail to set wps_version_number");
8627 			return STATUS_SENT;
8628 		}
8629 	}
8630 
8631 	dut->hostapd_running = 1;
8632 	return 1;
8633 }
8634 
8635 
8636 static int parse_qos_params(struct sigma_dut *dut, struct sigma_conn *conn,
8637 			    struct qos_params *qos, const char *cwmin,
8638 			    const char *cwmax, const char *aifs,
8639 			    const char *txop, const char *acm)
8640 {
8641 	int val;
8642 
8643 	if (cwmin) {
8644 		qos->ac = 1;
8645 		val = atoi(cwmin);
8646 		if (val < 0 || val > 15) {
8647 			send_resp(dut, conn, SIGMA_INVALID,
8648 				  "errorCode,Invalid cwMin");
8649 			return 0;
8650 		}
8651 		qos->cwmin = val;
8652 	}
8653 
8654 	if (cwmax) {
8655 		qos->ac = 1;
8656 		val = atoi(cwmax);
8657 		if (val < 0 || val > 15) {
8658 			send_resp(dut, conn, SIGMA_INVALID,
8659 				  "errorCode,Invalid cwMax");
8660 			return 0;
8661 		}
8662 		qos->cwmax = val;
8663 	}
8664 
8665 	if (aifs) {
8666 		qos->ac = 1;
8667 		val = atoi(aifs);
8668 		if (val < 1 || val > 255) {
8669 			send_resp(dut, conn, SIGMA_INVALID,
8670 				  "errorCode,Invalid AIFS");
8671 			return 0;
8672 		}
8673 		qos->aifs = val;
8674 	}
8675 
8676 	if (txop) {
8677 		qos->ac = 1;
8678 		val = atoi(txop);
8679 		if (val < 0 || val > 0xffff) {
8680 			send_resp(dut, conn, SIGMA_INVALID,
8681 				  "errorCode,Invalid txop");
8682 			return 0;
8683 		}
8684 		qos->txop = val * 32;
8685 	}
8686 
8687 	if (acm) {
8688 		qos->ac = 1;
8689 		qos->acm = strcasecmp(acm, "on") == 0;
8690 	}
8691 
8692 	return 1;
8693 }
8694 
8695 
8696 static enum sigma_cmd_result cmd_ap_set_apqos(struct sigma_dut *dut,
8697 					      struct sigma_conn *conn,
8698 					      struct sigma_cmd *cmd)
8699 {
8700 	/* TXOP: The values provided here for VHT5G only */
8701 	if (!parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VO],
8702 			      get_param(cmd, "cwmin_VO"),
8703 			      get_param(cmd, "cwmax_VO"),
8704 			      get_param(cmd, "AIFS_VO"),
8705 			      get_param(cmd, "TXOP_VO"),
8706 			      get_param(cmd, "ACM_VO")) ||
8707 	    !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VI],
8708 			      get_param(cmd, "cwmin_VI"),
8709 			      get_param(cmd, "cwmax_VI"),
8710 			      get_param(cmd, "AIFS_VI"),
8711 			      get_param(cmd, "TXOP_VI"),
8712 			      get_param(cmd, "ACM_VI")) ||
8713 	    !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BE],
8714 			      get_param(cmd, "cwmin_BE"),
8715 			      get_param(cmd, "cwmax_BE"),
8716 			      get_param(cmd, "AIFS_BE"),
8717 			      get_param(cmd, "TXOP_BE"),
8718 			      get_param(cmd, "ACM_BE")) ||
8719 	    !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BK],
8720 			      get_param(cmd, "cwmin_BK"),
8721 			      get_param(cmd, "cwmax_BK"),
8722 			      get_param(cmd, "AIFS_BK"),
8723 			      get_param(cmd, "TXOP_BK"),
8724 			      get_param(cmd, "ACM_BK")))
8725 		return 0;
8726 
8727 	return 1;
8728 }
8729 
8730 
8731 static enum sigma_cmd_result cmd_ap_set_staqos(struct sigma_dut *dut,
8732 					       struct sigma_conn *conn,
8733 					       struct sigma_cmd *cmd)
8734 {
8735 	if (!parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VO],
8736 			      get_param(cmd, "cwmin_VO"),
8737 			      get_param(cmd, "cwmax_VO"),
8738 			      get_param(cmd, "AIFS_VO"),
8739 			      get_param(cmd, "TXOP_VO"),
8740 			      get_param(cmd, "ACM_VO")) ||
8741 	    !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VI],
8742 			      get_param(cmd, "cwmin_VI"),
8743 			      get_param(cmd, "cwmax_VI"),
8744 			      get_param(cmd, "AIFS_VI"),
8745 			      get_param(cmd, "TXOP_VI"),
8746 			      get_param(cmd, "ACM_VI")) ||
8747 	    !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BE],
8748 			      get_param(cmd, "cwmin_BE"),
8749 			      get_param(cmd, "cwmax_BE"),
8750 			      get_param(cmd, "AIFS_BE"),
8751 			      get_param(cmd, "TXOP_BE"),
8752 			      get_param(cmd, "ACM_BE")) ||
8753 	    !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BK],
8754 			      get_param(cmd, "cwmin_BK"),
8755 			      get_param(cmd, "cwmax_BK"),
8756 			      get_param(cmd, "AIFS_BK"),
8757 			      get_param(cmd, "TXOP_BK"),
8758 			      get_param(cmd, "ACM_BK")))
8759 		return 0;
8760 
8761 	return 1;
8762 }
8763 
8764 
8765 static void cmd_ath_ap_hs2_reset(struct sigma_dut *dut)
8766 {
8767 	unsigned char bssid[6];
8768 	char buf[100];
8769 	run_system(dut, "cfg -a AP_SSID=\"Hotspot 2.0\"");
8770 	run_system(dut, "cfg -a AP_PRIMARY_CH=1");
8771 	run_system(dut, "cfg -a AP_SECMODE=WPA");
8772 	run_system(dut, "cfg -a AP_SECFILE=EAP");
8773 	run_system(dut, "cfg -a AP_WPA=2");
8774 	run_system(dut, "cfg -a AP_CYPHER=CCMP");
8775 	run_system(dut, "cfg -a AP_HOTSPOT=1");
8776 	run_system(dut, "cfg -a AP_HOTSPOT_ANT=2");
8777 	run_system(dut, "cfg -a AP_HOTSPOT_INTERNET=0");
8778 	run_system(dut, "cfg -a AP_HOTSPOT_VENUEGROUP=2");
8779 	run_system(dut, "cfg -a AP_HOTSPOT_VENUETYPE=8");
8780 	run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=506f9a");
8781 	run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2=001bc504bd");
8782 	if (!get_hwaddr("ath0", bssid)) {
8783 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID="
8784 			"%02x:%02x:%02x:%02x:%02x:%02x",
8785 			bssid[0], bssid[1], bssid[2], bssid[3],
8786 			bssid[4], bssid[5]);
8787 		run_system(dut, buf);
8788 		snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
8789 			"%02x:%02x:%02x:%02x:%02x:%02x",
8790 			bssid[0], bssid[1], bssid[2], bssid[3],
8791 			bssid[4], bssid[5]);
8792 	} else {
8793 		if (!get_hwaddr("wifi0", bssid)) {
8794 			snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID="
8795 				"%02x:%02x:%02x:%02x:%02x:%02x",
8796 				bssid[0], bssid[1], bssid[2], bssid[3],
8797 				bssid[4], bssid[5]);
8798 			run_system(dut, buf);
8799 			snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
8800 				"%02x:%02x:%02x:%02x:%02x:%02x",
8801 				bssid[0], bssid[1], bssid[2], bssid[3],
8802 				bssid[4], bssid[5]);
8803 		} else {
8804 			/* load the driver and try again */
8805 			run_system(dut, "/etc/rc.d/rc.wlan up");
8806 
8807 			if (!get_hwaddr("wifi0", bssid)) {
8808 				snprintf(buf, sizeof(buf),
8809 					 "cfg -a AP_HOTSPOT_HESSID="
8810 					 "%02x:%02x:%02x:%02x:%02x:%02x",
8811 					 bssid[0], bssid[1], bssid[2],
8812 					 bssid[3], bssid[4], bssid[5]);
8813 				run_system(dut, buf);
8814 				snprintf(dut->ap_hessid,
8815 					 sizeof(dut->ap_hessid),
8816 					 "%02x:%02x:%02x:%02x:%02x:%02x",
8817 					 bssid[0], bssid[1], bssid[2],
8818 					 bssid[3], bssid[4], bssid[5]);
8819 			}
8820 		}
8821 	}
8822 
8823 	run_system(dut, "cfg -r AP_SSID_2");
8824 	run_system(dut, "cfg -c");
8825 	/* run_system(dut, "cfg -s"); */
8826 }
8827 
8828 
8829 static void ath_reset_vht_defaults(struct sigma_dut *dut)
8830 {
8831 	run_system(dut, "cfg -x");
8832 	run_system(dut, "cfg -a AP_RADIO_ID=1");
8833 	run_system(dut, "cfg -a AP_PRIMARY_CH_2=36");
8834 	run_system(dut, "cfg -a AP_STARTMODE=standard");
8835 	run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
8836 	run_system(dut, "cfg -a TX_CHAINMASK_2=7");
8837 	run_system(dut, "cfg -a RX_CHAINMASK_2=7");
8838 	run_system(dut, "cfg -a ATH_countrycode=0x348");
8839 	/* NOTE: For Beeliner we have to turn off MU-MIMO */
8840 	if (system("rm /tmp/secath*") != 0) {
8841 		sigma_dut_print(dut, DUT_MSG_ERROR,
8842 				"Failed to remove secath file");
8843 	}
8844 }
8845 
8846 
8847 static enum sigma_cmd_result cmd_ap_reset_default(struct sigma_dut *dut,
8848 						  struct sigma_conn *conn,
8849 						  struct sigma_cmd *cmd)
8850 {
8851 	const char *type, *program;
8852 	enum driver_type drv;
8853 	char buf[128];
8854 	int i;
8855 
8856 	for (i = 0; i < MAX_WLAN_TAGS - 1; i++) {
8857 		/*
8858 		 * Reset all tagged SSIDs to NULL-string and all key management
8859 		 * to open.
8860 		 */
8861 		dut->ap_tag_ssid[i][0] = '\0';
8862 		dut->ap_tag_key_mgmt[i] = AP2_OPEN;
8863 	}
8864 
8865 	drv = get_driver_type(dut);
8866 
8867 	program = get_param(cmd, "program");
8868 	if (!program)
8869 		program = get_param(cmd, "prog");
8870 	dut->program = sigma_program_to_enum(program);
8871 	dut->device_type = AP_unknown;
8872 	type = get_param(cmd, "type");
8873 	if (type && strcasecmp(type, "Testbed") == 0)
8874 		dut->device_type = AP_testbed;
8875 	if (type && strcasecmp(type, "DUT") == 0)
8876 		dut->device_type = AP_dut;
8877 
8878 	dut->ap_rts = 0;
8879 	dut->ap_frgmnt = 0;
8880 	dut->ap_bcnint = 0;
8881 	dut->ap_key_mgmt = AP_OPEN;
8882 	dut->ap_ssid[0] = '\0';
8883 	dut->ap_fake_pkhash = 0;
8884 	memset(dut->ap_qos, 0, sizeof(dut->ap_qos));
8885 	memset(dut->ap_sta_qos, 0, sizeof(dut->ap_sta_qos));
8886 	dut->ap_addba_reject = VALUE_NOT_SET;
8887 	dut->ap_noack = VALUE_NOT_SET;
8888 	dut->ap_is_dual = 0;
8889 	dut->ap_mode = AP_inval;
8890 	dut->ap_mode_1 = AP_inval;
8891 
8892 	dut->ap_allow_vht_wep = 0;
8893 	dut->ap_allow_vht_tkip = 0;
8894 	dut->ap_disable_protection = 0;
8895 	memset(dut->ap_countrycode, 0, sizeof(dut->ap_countrycode));
8896 	dut->ap_dyn_bw_sig = VALUE_NOT_SET;
8897 	dut->ap_ldpc = VALUE_NOT_SET;
8898 	dut->ap_sig_rts = VALUE_NOT_SET;
8899 	dut->ap_rx_amsdu = VALUE_NOT_SET;
8900 	dut->ap_txBF = 0;
8901 	dut->ap_mu_txBF = 0;
8902 	dut->ap_chwidth = AP_AUTO;
8903 
8904 	dut->ap_rsn_preauth = 0;
8905 	dut->ap_wpsnfc = 0;
8906 	dut->ap_bss_load = -1;
8907 	dut->ap_p2p_cross_connect = -1;
8908 
8909 	dut->ap_regulatory_mode = AP_80211D_MODE_DISABLED;
8910 	dut->ap_dfs_mode = AP_DFS_MODE_DISABLED;
8911 	dut->ap_chwidth_offset = SEC_CH_NO;
8912 
8913 	dut->mbo_pref_ap_cnt = 0;
8914 	dut->ft_bss_mac_cnt = 0;
8915 	dut->ap_interface_5g = 0;
8916 	dut->ap_interface_2g = 0;
8917 	dut->ap_pmf = AP_PMF_DISABLED;
8918 
8919 	dut->wsc_fragment = 0;
8920 	dut->eap_fragment = 0;
8921 	dut->wps_forced_version = 0;
8922 
8923 	if (dut->program == PROGRAM_HT || dut->program == PROGRAM_VHT) {
8924 		dut->ap_wme = AP_WME_ON;
8925 		dut->ap_wmmps = AP_WMMPS_ON;
8926 	} else {
8927 		dut->ap_wme = AP_WME_OFF;
8928 		dut->ap_wmmps = AP_WMMPS_OFF;
8929 	}
8930 
8931 	dut->ap_venue_url = 0;
8932 	dut->ap_advice_of_charge = 0;
8933 	dut->ap_oper_icon_metadata = 0;
8934 	dut->ap_tnc_file_name = 0;
8935 	dut->ap_tnc_time_stamp = 0;
8936 
8937 	dut->ap_akm_values = 0;
8938 	free(dut->ap_sae_passwords);
8939 	dut->ap_sae_passwords = NULL;
8940 
8941 	dut->ap_ocvc = -1;
8942 
8943 	if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
8944 	    dut->program == PROGRAM_HS2_R3 ||
8945 	    dut->program == PROGRAM_IOTLP) {
8946 		int i;
8947 
8948 		if (drv == DRIVER_ATHEROS)
8949 			cmd_ath_ap_hs2_reset(dut);
8950 		else if (drv == DRIVER_OPENWRT)
8951 			cmd_owrt_ap_hs2_reset(dut);
8952 
8953 		dut->ap_interworking = 1;
8954 		dut->ap_access_net_type = 2;
8955 		dut->ap_internet = 0;
8956 		dut->ap_venue_group = 2;
8957 		dut->ap_venue_type = 8;
8958 		dut->ap_domain_name_list[0] = '\0';
8959 		dut->ap_hs2 = 1;
8960 		snprintf(dut->ap_roaming_cons, sizeof(dut->ap_roaming_cons),
8961 			 "506f9a;001bc504bd");
8962 		dut->ap_l2tif = 0;
8963 		dut->ap_proxy_arp = 0;
8964 		if (dut->bridge) {
8965 			char buf[50];
8966 
8967 			snprintf(buf, sizeof(buf), "ip neigh flush dev %s",
8968 				 dut->bridge);
8969 			if (system(buf) != 0) {
8970 				sigma_dut_print(dut, DUT_MSG_DEBUG,
8971 						"%s ip neigh table flushing failed",
8972 						dut->bridge);
8973 			}
8974 
8975 			snprintf(buf, sizeof(buf), "ebtables -F");
8976 			if (system(buf) != 0) {
8977 				sigma_dut_print(dut, DUT_MSG_DEBUG,
8978 						"%s ebtables flushing failed",
8979 						dut->bridge);
8980 			}
8981 		}
8982 		dut->ap_dgaf_disable = 0;
8983 		dut->ap_p2p_cross_connect = 0;
8984 		dut->ap_gas_cb_delay = 0;
8985 		dut->ap_nai_realm_list = 0;
8986 		dut->ap_oper_name = 0;
8987 		dut->ap_venue_name = 0;
8988 		for (i = 0; i < 10; i++) {
8989 			dut->ap_plmn_mcc[i][0] = '\0';
8990 			dut->ap_plmn_mnc[i][0] = '\0';
8991 		}
8992 		dut->ap_wan_metrics = 0;
8993 		dut->ap_conn_capab = 0;
8994 		dut->ap_ip_addr_type_avail = 0;
8995 		dut->ap_net_auth_type = 0;
8996 		dut->ap_oper_class = 0;
8997 		dut->ap_pmf = 0;
8998 		dut->ap_add_sha256 = 0;
8999 	}
9000 
9001 	if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
9002 	    dut->program == PROGRAM_IOTLP) {
9003 		int i;
9004 		const char hessid[] = "50:6f:9a:00:11:22";
9005 
9006 		memcpy(dut->ap_hessid, hessid, strlen(hessid) + 1);
9007 		dut->ap_osu_ssid[0] = '\0';
9008 		dut->ap_pmf = 1;
9009 		dut->ap_osu_provider_list = 0;
9010 		dut->ap_osu_provider_nai_list = 0;
9011 		for (i = 0; i < 10; i++) {
9012 			dut->ap_osu_server_uri[i][0] = '\0';
9013 			dut->ap_osu_method[i] = 0xFF;
9014 		}
9015 		dut->ap_qos_map_set = 0;
9016 		dut->ap_tag_key_mgmt[0] = AP2_OPEN;
9017 		dut->ap2_proxy_arp = 0;
9018 		dut->ap2_osu = 0;
9019 		dut->ap_osu_icon_tag = 0;
9020 	}
9021 
9022 	if (dut->program == PROGRAM_VHT) {
9023 		/* Set up the defaults */
9024 		dut->use_5g = 1;
9025 		dut->ap_mode = AP_11ac;
9026 		dut->ap_channel = 36;
9027 		dut->ap_ampdu = VALUE_NOT_SET;
9028 		dut->ap_ndpa_frame = 1;
9029 		if (dut->device_type == AP_testbed) {
9030 			dut->ap_amsdu = VALUE_DISABLED;
9031 			dut->ap_ldpc = VALUE_DISABLED;
9032 			dut->ap_rx_amsdu = VALUE_DISABLED;
9033 			dut->ap_sgi80 = 0;
9034 		} else {
9035 			dut->ap_amsdu = VALUE_ENABLED;
9036 			/*
9037 			 * As LDPC is optional, don't enable this by default
9038 			 * for LINUX-WCN driver. The ap_set_wireless command
9039 			 * can be used to enable LDPC, when needed.
9040 			 */
9041 			if (drv != DRIVER_LINUX_WCN)
9042 				dut->ap_ldpc = VALUE_ENABLED;
9043 			dut->ap_rx_amsdu = VALUE_ENABLED;
9044 			dut->ap_sgi80 = 1;
9045 		}
9046 		dut->ap_fixed_rate = 0;
9047 		dut->ap_rx_streams = 3;
9048 		dut->ap_tx_streams = 3;
9049 		dut->ap_vhtmcs_map = 0;
9050 		dut->ap_chwidth = AP_80;
9051 		dut->ap_tx_stbc = 1;
9052 		dut->ap_dyn_bw_sig = VALUE_ENABLED;
9053 		if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9054 			dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
9055 		if (get_driver_type(dut) == DRIVER_ATHEROS)
9056 			ath_reset_vht_defaults(dut);
9057 	}
9058 
9059 	if (dut->program == PROGRAM_IOTLP) {
9060 		dut->wnm_bss_max_feature = VALUE_DISABLED;
9061 		dut->wnm_bss_max_idle_time = 0;
9062 		dut->wnm_bss_max_protection = VALUE_NOT_SET;
9063 		dut->ap_proxy_arp = 1;
9064 	} else {
9065 		/*
9066 		 * Do not touch the BSS-MAX Idle time feature
9067 		 * if the program is not IOTLP.
9068 		 */
9069 		dut->wnm_bss_max_feature = VALUE_NOT_SET;
9070 		dut->wnm_bss_max_idle_time = 0;
9071 		dut->wnm_bss_max_protection = VALUE_NOT_SET;
9072 	}
9073 
9074 	if (dut->program == PROGRAM_LOC) {
9075 		dut->ap_rrm = 1;
9076 		dut->ap_rtt = 1;
9077 		dut->ap_lci = 0;
9078 		dut->ap_val_lci[0] = '\0';
9079 		dut->ap_infoz[0] = '\0';
9080 		dut->ap_lcr = 0;
9081 		dut->ap_val_lcr[0] = '\0';
9082 		dut->ap_neighap = 0;
9083 		dut->ap_opchannel = 0;
9084 		dut->ap_scan = 0;
9085 		dut->ap_fqdn_held = 0;
9086 		dut->ap_fqdn_supl = 0;
9087 		dut->ap_interworking = 0;
9088 		dut->ap_gas_cb_delay = 0;
9089 		dut->ap_msnt_type = 0;
9090 	}
9091 	dut->ap_ft_oa = 0;
9092 	dut->ap_ft_ds = VALUE_NOT_SET;
9093 	dut->ap_reg_domain = REG_DOMAIN_NOT_SET;
9094 	dut->ap_mobility_domain[0] = '\0';
9095 
9096 	if (dut->program == PROGRAM_MBO) {
9097 		dut->ap_mbo = 1;
9098 		dut->ap_interworking = 1;
9099 		dut->ap_ne_class = 0;
9100 		dut->ap_ne_op_ch = 0;
9101 		dut->ap_set_bssidpref = 1;
9102 		dut->ap_btmreq_disassoc_imnt = 0;
9103 		dut->ap_btmreq_term_bit = 0;
9104 		dut->ap_disassoc_timer = 0;
9105 		dut->ap_btmreq_bss_term_dur = 0;
9106 		dut->ap_channel = 36;
9107 		dut->ap_chwidth = AP_20;
9108 		dut->ap_cell_cap_pref = 0;
9109 		dut->ap_gas_cb_delay = 0;
9110 		dut->mbo_self_ap_tuple.ap_ne_class = -1;
9111 		dut->mbo_self_ap_tuple.ap_ne_pref = -1; /* Not set */
9112 		dut->mbo_self_ap_tuple.ap_ne_op_ch = -1;
9113 		dut->ap_btmreq_bss_term_tsf = 0;
9114 		dut->ap_assoc_delay = 0;
9115 	}
9116 
9117 	if (dut->program == PROGRAM_OCE) {
9118 		if (dut->ap_dhcp_stop)
9119 			run_system(dut, "/etc/init.d/dnsmasq start");
9120 
9121 		dut->ap_dhcp_stop = 0;
9122 		dut->ap_oce = VALUE_ENABLED;
9123 		dut->ap_broadcast_ssid = VALUE_ENABLED;
9124 		dut->ap_fils_dscv_int = 20;
9125 		dut->ap_filsdscv = VALUE_ENABLED;
9126 		dut->ap_filshlp = VALUE_DISABLED;
9127 		dut->ap_rnr = VALUE_DISABLED;
9128 		dut->ap_nairealm[0] = '\0';
9129 		dut->ap_nairealm_int = 0;
9130 		dut->ap_blechanutil = 0;
9131 		dut->ap_ble_admit_cap = 0;
9132 		dut->ap_esp = VALUE_ENABLED;
9133 		dut->ap_datappdudura = 0;
9134 		dut->ap_airtimefract = 0;
9135 		dut->ap_blestacnt = 0;
9136 		dut->ap_ul_availcap = 0;
9137 		dut->ap_dl_availcap = 0;
9138 		dut->ap_akm = 0;
9139 		dut->ap_add_sha256 = 0;
9140 		dut->ap_add_sha384 = 0;
9141 		dut->ap_80plus80 = 0;
9142 	}
9143 
9144 	dut->ap_he_ppdu = PPDU_NOT_SET;
9145 	dut->ap_he_ulofdma = VALUE_NOT_SET;
9146 	dut->ap_numsounddim = 0;
9147 	dut->ap_bcc = VALUE_DISABLED;
9148 	dut->ap_mu_edca = VALUE_DISABLED;
9149 	dut->ap_he_mimo = MIMO_NOT_SET;
9150 	dut->ap_he_rtsthrshld = VALUE_NOT_SET;
9151 	dut->ap_mbssid = VALUE_DISABLED;
9152 	dut->ap_ampdu = VALUE_NOT_SET;
9153 	dut->he_mcsnssmap = 0;
9154 	dut->ap_fixed_rate = 0;
9155 	dut->he_mmss = 0;
9156 	dut->he_set_sta_1x1 = VALUE_DISABLED;
9157 	dut->he_srctrl_allow = -1;
9158 	if (dut->device_type == AP_testbed) {
9159 		dut->ap_he_dlofdma = VALUE_DISABLED;
9160 		dut->ap_he_frag = VALUE_DISABLED;
9161 		dut->ap_twtresp = VALUE_DISABLED;
9162 		dut->he_ul_mcs = 7;
9163 	} else {
9164 		dut->ap_he_dlofdma = VALUE_NOT_SET;
9165 		dut->ap_he_frag = VALUE_NOT_SET;
9166 		dut->ap_ba_bufsize = BA_BUFSIZE_NOT_SET;
9167 		dut->ap_twtresp = VALUE_NOT_SET;
9168 		dut->he_ul_mcs = 0;
9169 	}
9170 
9171 	if (dut->program == PROGRAM_HE) {
9172 		if (dut->device_type == AP_testbed) {
9173 			dut->ap_ldpc = VALUE_DISABLED;
9174 			dut->ap_ba_bufsize = BA_BUFSIZE_64;
9175 			dut->ap_amsdu = VALUE_DISABLED;
9176 			dut->ap_txBF = 0;
9177 			dut->ap_mu_txBF = 0;
9178 			dut->he_sounding = VALUE_DISABLED;
9179 		} else {
9180 			if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) {
9181 				dut->ap_txBF = 0;
9182 				dut->ap_mu_txBF = 0;
9183 			} else {
9184 				dut->ap_txBF = 1;
9185 				dut->ap_mu_txBF = 1;
9186 			}
9187 			dut->he_sounding = VALUE_ENABLED;
9188 			if (drv == DRIVER_LINUX_WCN) {
9189 				dut->ap_ldpc = VALUE_ENABLED;
9190 				wcn_config_ap_ldpc(dut, get_main_ifname(dut));
9191 #ifdef NL80211_SUPPORT
9192 				if (wcn_set_he_ltf(dut, get_main_ifname(dut),
9193 						   QCA_WLAN_HE_LTF_AUTO)) {
9194 					sigma_dut_print(dut, DUT_MSG_ERROR,
9195 							"Failed to set LTF in ap_reset_default");
9196 				}
9197 #endif /* NL80211_SUPPORT */
9198 			}
9199 		}
9200 		if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9201 			dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
9202 	}
9203 
9204 	dut->ap_oper_chn = 0;
9205 
9206 	dut->ap_pmksa = 0;
9207 	dut->ap_pmksa_caching = 0;
9208 
9209 	free(dut->rsne_override);
9210 	dut->rsne_override = NULL;
9211 	free(dut->rsnxe_override_eapol);
9212 	dut->rsnxe_override_eapol = NULL;
9213 
9214 	free(dut->sae_commit_override);
9215 	dut->sae_commit_override = NULL;
9216 
9217 	free(dut->ap_sae_groups);
9218 	dut->ap_sae_groups = NULL;
9219 
9220 	dut->sae_anti_clogging_threshold = -1;
9221 	dut->sae_reflection = 0;
9222 	dut->sae_confirm_immediate = 0;
9223 	dut->sae_pwe = SAE_PWE_DEFAULT;
9224 
9225 	dut->ap_cipher = AP_CCMP;
9226 	dut->ap_group_cipher = AP_NO_GROUP_CIPHER_SET;
9227 	dut->ap_group_mgmt_cipher = AP_NO_GROUP_MGMT_CIPHER_SET;
9228 	dut->ap_passphrase[0] = '\0';
9229 	dut->ap_psk[0] = '\0';
9230 	dut->ap_beacon_prot = 0;
9231 	dut->ap_transition_disable = 0;
9232 
9233 	dut->dpp_conf_id = -1;
9234 	free(dut->ap_dpp_conf_addr);
9235 	dut->ap_dpp_conf_addr = NULL;
9236 	free(dut->ap_dpp_conf_pkhash);
9237 	dut->ap_dpp_conf_pkhash = NULL;
9238 	dut->ap_start_disabled = 0;
9239 
9240 	if (is_60g_sigma_dut(dut)) {
9241 		dut->ap_mode = AP_11ad;
9242 		dut->ap_channel = 2;
9243 		dut->wps_disable = 0; /* WPS is enabled */
9244 		dut->ap_pmf = 0;
9245 		dut->ap_num_ese_allocs = 0;
9246 		dut->ap_fixed_rate = 0;
9247 
9248 		dut->dev_role = DEVROLE_AP;
9249 
9250 		sigma_dut_print(dut, DUT_MSG_DEBUG,
9251 				"Setting msdu_size to MAX: 7912");
9252 		snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
9253 			 get_main_ifname(dut));
9254 
9255 		if (system(buf) != 0) {
9256 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9257 					buf);
9258 			return ERROR_SEND_STATUS;
9259 		}
9260 
9261 		if (ap_set_force_mcs(dut, 0, 1)) {
9262 			sigma_dut_print(dut, DUT_MSG_ERROR,
9263 					"Failed to reset force MCS");
9264 			return ERROR_SEND_STATUS;
9265 		}
9266 
9267 		if (set_ps(get_main_ifname(dut), dut, 1)) {
9268 			sigma_dut_print(dut, DUT_MSG_ERROR,
9269 					"Failed to enable power save");
9270 			return ERROR_SEND_STATUS;
9271 		}
9272 	}
9273 
9274 	if (dut->program == PROGRAM_WPS &&
9275 	    get_driver_type(dut) == DRIVER_WIL6210) {
9276 		/*
9277 		 * In 60 GHz WPS tests, we configure the AP OOB to
9278 		 * secure connection with a random passphrase.
9279 		 */
9280 		char r[16], passphrase[65];
9281 
9282 		if (random_get_bytes(r, sizeof(r))) {
9283 			sigma_dut_print(dut, DUT_MSG_ERROR,
9284 					"Failed to get random bytes");
9285 			return ERROR_SEND_STATUS;
9286 		}
9287 		if (base64_encode(r, sizeof(r),
9288 				  passphrase, sizeof(passphrase))) {
9289 			sigma_dut_print(dut, DUT_MSG_ERROR,
9290 					"Failed to generate random passphrase");
9291 			return ERROR_SEND_STATUS;
9292 		}
9293 
9294 		dut->ap_key_mgmt = AP_WPA2_PSK;
9295 		dut->ap_cipher = AP_GCMP_128;
9296 		strlcpy(dut->ap_passphrase, passphrase,
9297 			sizeof(dut->ap_passphrase));
9298 		sigma_dut_print(dut, DUT_MSG_DEBUG,
9299 				"60G WPS: configure secure AP with random passphrase");
9300 	}
9301 
9302 	dut->hostapd_running = 0;
9303 
9304 	if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9305 		return 1;
9306 
9307 	if (dut->use_hostapd_pid_file) {
9308 		kill_hostapd_process_pid(dut);
9309 	} else if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
9310 		   system("killall hostapd") == 0) {
9311 		int i;
9312 		/* Wait some time to allow hostapd to complete cleanup before
9313 		 * starting a new process */
9314 		for (i = 0; i < 10; i++) {
9315 			usleep(500000);
9316 			if (system("pidof hostapd") != 0)
9317 				break;
9318 		}
9319 	}
9320 
9321 	if (if_nametoindex("sigmadut") > 0 &&
9322 	    system("iw dev sigmadut del") != 0)
9323 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove "
9324 				"monitor interface");
9325 
9326 	return 1;
9327 }
9328 
9329 
9330 int sta_cfon_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
9331 			   struct sigma_cmd *cmd)
9332 {
9333 	return cmd_ap_reset_default(dut, conn, cmd);
9334 }
9335 
9336 
9337 static enum sigma_cmd_result cmd_ap_get_info(struct sigma_dut *dut,
9338 					     struct sigma_conn *conn,
9339 					     struct sigma_cmd *cmd)
9340 {
9341 	/* const char *name = get_param(cmd, "NAME"); */
9342 	struct stat s;
9343 	char resp[200];
9344 	FILE *f;
9345 	enum driver_type drv = get_driver_type(dut);
9346 	int res;
9347 
9348 	switch (drv) {
9349 	case DRIVER_ATHEROS: {
9350 		/* Atheros AP */
9351 		struct utsname uts;
9352 		char *version, athver[100];
9353 
9354 		if (stat("/proc/athversion", &s) != 0) {
9355 			if (system("/etc/rc.d/rc.wlan up") != 0) {
9356 			}
9357 		}
9358 
9359 		athver[0] = '\0';
9360 		f = fopen("/proc/athversion", "r");
9361 		if (f) {
9362 			if (fgets(athver, sizeof(athver), f)) {
9363 				char *pos = strchr(athver, '\n');
9364 				if (pos)
9365 					*pos = '\0';
9366 			}
9367 			fclose(f);
9368 		}
9369 
9370 		if (uname(&uts) == 0)
9371 			version = uts.release;
9372 		else
9373 			version = "Unknown";
9374 
9375 		if (if_nametoindex("ath1") > 0)
9376 			res = snprintf(resp, sizeof(resp),
9377 				       "interface,ath0_24G ath1_5G,agent,1.0,version,%s/drv:%s",
9378 				       version, athver);
9379 		else
9380 			res = snprintf(resp, sizeof(resp),
9381 				       "interface,ath0_24G,agent,1.0,version,%s/drv:%s",
9382 				       version, athver);
9383 		if (res < 0 || res >= sizeof(resp))
9384 			send_resp(dut, conn, SIGMA_ERROR, NULL);
9385 		else
9386 			send_resp(dut, conn, SIGMA_COMPLETE, resp);
9387 		return 0;
9388 	}
9389 	case DRIVER_LINUX_WCN:
9390 	case DRIVER_MAC80211: {
9391 		struct utsname uts;
9392 		char *version;
9393 
9394 		if (uname(&uts) == 0)
9395 			version = uts.release;
9396 		else
9397 			version = "Unknown";
9398 
9399 		if (if_nametoindex("wlan1") > 0)
9400 			snprintf(resp, sizeof(resp), "interface,wlan0_24G "
9401 				 "wlan1_5G,agent,1.0,version,%s", version);
9402 		else
9403 			snprintf(resp, sizeof(resp), "interface,wlan0_any,"
9404 				 "agent,1.0,version,%s", version);
9405 
9406 		send_resp(dut, conn, SIGMA_COMPLETE, resp);
9407 		return 0;
9408 	}
9409 	case DRIVER_QNXNTO: {
9410 		struct utsname uts;
9411 		char *version;
9412 
9413 		if (uname(&uts) == 0)
9414 			version = uts.release;
9415 		else
9416 			version = "Unknown";
9417 		snprintf(resp, sizeof(resp),
9418 			 "interface,%s_any,agent,1.0,version,%s",
9419 			 dut->main_ifname ? get_main_ifname(dut) : "NA",
9420 			 version);
9421 		send_resp(dut, conn, SIGMA_COMPLETE, resp);
9422 		return 0;
9423 	}
9424 	case DRIVER_OPENWRT: {
9425 		switch (get_openwrt_driver_type()) {
9426 		case OPENWRT_DRIVER_ATHEROS: {
9427 			struct utsname uts;
9428 			char *version;
9429 
9430 			if (uname(&uts) == 0)
9431 				version = uts.release;
9432 			else
9433 				version = "Unknown";
9434 
9435 			if (if_nametoindex("ath1") > 0)
9436 				snprintf(resp, sizeof(resp),
9437 					 "interface,ath0_5G ath1_24G,agent,1.0,version,%s",
9438 					 version);
9439 			else
9440 				snprintf(resp, sizeof(resp),
9441 					 "interface,ath0_any,agent,1.0,version,%s",
9442 					 version);
9443 
9444 			send_resp(dut, conn, SIGMA_COMPLETE, resp);
9445 			return 0;
9446 		}
9447 		default:
9448 			send_resp(dut, conn, SIGMA_ERROR,
9449 				  "errorCode,Unsupported openwrt driver");
9450 			return 0;
9451 		}
9452 	}
9453 	default:
9454 		send_resp(dut, conn, SIGMA_ERROR,
9455 			  "errorCode,Unsupported driver");
9456 		return 0;
9457 	}
9458 }
9459 
9460 
9461 static enum sigma_cmd_result cmd_ap_deauth_sta(struct sigma_dut *dut,
9462 					       struct sigma_conn *conn,
9463 					       struct sigma_cmd *cmd)
9464 {
9465 	/* const char *name = get_param(cmd, "NAME"); */
9466 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
9467 	const char *val, *disconnect;
9468 	char buf[100];
9469 
9470 	val = get_param(cmd, "MinorCode");
9471 	if (val) {
9472 		/* TODO: add support for P2P minor code */
9473 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,MinorCode not "
9474 			  "yet supported");
9475 		return 0;
9476 	}
9477 
9478 	val = get_param(cmd, "STA_MAC_ADDRESS");
9479 	if (val == NULL)
9480 		return -1;
9481 	disconnect = get_param(cmd, "disconnect");
9482 	if (disconnect && strcasecmp(disconnect, "silent") == 0)
9483 		snprintf(buf, sizeof(buf), "deauth %s tx=0", val);
9484 	else
9485 		snprintf(buf, sizeof(buf), "deauth %s", val);
9486 	if (run_hostapd_cli(dut, buf) != 0)
9487 		return -2;
9488 
9489 	return 1;
9490 }
9491 
9492 
9493 #ifdef __linux__
9494 int inject_frame(int s, const void *data, size_t len, int encrypt);
9495 int open_monitor(const char *ifname);
9496 #endif /* __linux__ */
9497 
9498 enum send_frame_type {
9499 		DISASSOC, DEAUTH, SAQUERY
9500 };
9501 enum send_frame_protection {
9502 	CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9503 };
9504 
9505 
9506 static int ap_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9507 			   enum send_frame_type frame,
9508 			   enum send_frame_protection protected,
9509 			   const char *sta_addr)
9510 {
9511 #ifdef __linux__
9512 	unsigned char buf[1000], *pos;
9513 	int s, res;
9514 	unsigned char addr_sta[6], addr_own[6];
9515 	char *ifname;
9516 	char cbuf[100];
9517 	struct ifreq ifr;
9518 
9519 	if ((dut->ap_mode == AP_11a || dut->ap_mode == AP_11na ||
9520 	     dut->ap_mode == AP_11ac) &&
9521 	    if_nametoindex("wlan1") > 0)
9522 		ifname = "wlan1";
9523 	else
9524 		ifname = "wlan0";
9525 
9526 	if (hwaddr_aton(sta_addr, addr_sta) < 0)
9527 		return -1;
9528 
9529 	s = socket(AF_INET, SOCK_DGRAM, 0);
9530 	if (s < 0)
9531 		return -1;
9532 	memset(&ifr, 0, sizeof(ifr));
9533 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9534 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
9535 		perror("ioctl");
9536 		close(s);
9537 		return -1;
9538 	}
9539 	close(s);
9540 	memcpy(addr_own, ifr.ifr_hwaddr.sa_data, 6);
9541 
9542 	if (if_nametoindex("sigmadut") == 0) {
9543 		snprintf(cbuf, sizeof(cbuf),
9544 			 "iw dev %s interface add sigmadut type monitor",
9545 			 ifname);
9546 		if (system(cbuf) != 0 ||
9547 		    if_nametoindex("sigmadut") == 0) {
9548 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9549 					"monitor interface with '%s'", cbuf);
9550 			return -2;
9551 		}
9552 	}
9553 
9554 	if (system("ifconfig sigmadut up") != 0) {
9555 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9556 				"monitor interface up");
9557 		return -2;
9558 	}
9559 
9560 	pos = buf;
9561 
9562 	/* Frame Control */
9563 	switch (frame) {
9564 	case DISASSOC:
9565 		*pos++ = 0xa0;
9566 		break;
9567 	case DEAUTH:
9568 		*pos++ = 0xc0;
9569 		break;
9570 	case SAQUERY:
9571 		*pos++ = 0xd0;
9572 		break;
9573 	}
9574 
9575 	if (protected == INCORRECT_KEY)
9576 		*pos++ = 0x40; /* Set Protected field to 1 */
9577 	else
9578 		*pos++ = 0x00;
9579 
9580 	/* Duration */
9581 	*pos++ = 0x00;
9582 	*pos++ = 0x00;
9583 
9584 	/* addr1 = DA (station) */
9585 	memcpy(pos, addr_sta, 6);
9586 	pos += 6;
9587 	/* addr2 = SA (own address) */
9588 	memcpy(pos, addr_own, 6);
9589 	pos += 6;
9590 	/* addr3 = BSSID (own address) */
9591 	memcpy(pos, addr_own, 6);
9592 	pos += 6;
9593 
9594 	/* Seq# (to be filled by driver/mac80211) */
9595 	*pos++ = 0x00;
9596 	*pos++ = 0x00;
9597 
9598 	if (protected == INCORRECT_KEY) {
9599 		/* CCMP parameters */
9600 		memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9601 		pos += 8;
9602 	}
9603 
9604 	if (protected == INCORRECT_KEY) {
9605 		switch (frame) {
9606 		case DEAUTH:
9607 			/* Reason code (encrypted) */
9608 			memcpy(pos, "\xa7\x39", 2);
9609 			pos += 2;
9610 			break;
9611 		case DISASSOC:
9612 			/* Reason code (encrypted) */
9613 			memcpy(pos, "\xa7\x39", 2);
9614 			pos += 2;
9615 			break;
9616 		case SAQUERY:
9617 			/* Category|Action|TransID (encrypted) */
9618 			memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9619 			pos += 4;
9620 			break;
9621 		default:
9622 			return -1;
9623 		}
9624 
9625 		/* CCMP MIC */
9626 		memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9627 		pos += 8;
9628 	} else {
9629 		switch (frame) {
9630 		case DEAUTH:
9631 			/* reason code = 8 */
9632 			*pos++ = 0x08;
9633 			*pos++ = 0x00;
9634 			break;
9635 		case DISASSOC:
9636 			/* reason code = 8 */
9637 			*pos++ = 0x08;
9638 			*pos++ = 0x00;
9639 			break;
9640 		case SAQUERY:
9641 			/* Category - SA Query */
9642 			*pos++ = 0x08;
9643 			/* SA query Action - Request */
9644 			*pos++ = 0x00;
9645 			/* Transaction ID */
9646 			*pos++ = 0x12;
9647 			*pos++ = 0x34;
9648 			break;
9649 		}
9650 	}
9651 
9652 	s = open_monitor("sigmadut");
9653 	if (s < 0) {
9654 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9655 			  "monitor socket");
9656 		return 0;
9657 	}
9658 
9659 	res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9660 	if (res < 0) {
9661 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9662 			  "inject frame");
9663 		close(s);
9664 		return 0;
9665 	}
9666 	if (res < pos - buf) {
9667 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9668 			  "frame sent");
9669 		close(s);
9670 		return 0;
9671 	}
9672 
9673 	close(s);
9674 
9675 	return 1;
9676 #else /* __linux__ */
9677 	send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_send_frame not "
9678 		  "yet supported");
9679 	return 0;
9680 #endif /* __linux__ */
9681 }
9682 
9683 
9684 int ap_send_frame_hs2(struct sigma_dut *dut, struct sigma_conn *conn,
9685 		      struct sigma_cmd *cmd)
9686 {
9687 	const char *val, *dest;
9688 	char buf[100];
9689 
9690 	val = get_param(cmd, "FrameName");
9691 	if (val == NULL)
9692 		return -1;
9693 
9694 	if (strcasecmp(val, "QoSMapConfigure") == 0) {
9695 		dest = get_param(cmd, "Dest");
9696 		if (!dest)
9697 			return -1;
9698 
9699 		val = get_param(cmd, "QoS_MAP_SET");
9700 		if (val) {
9701 			dut->ap_qos_map_set = atoi(val);
9702 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
9703 					dut->ap_qos_map_set);
9704 		}
9705 
9706 		if (dut->ap_qos_map_set == 1)
9707 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1);
9708 		else if (dut->ap_qos_map_set == 2)
9709 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2);
9710 
9711 		snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest);
9712 		if (run_hostapd_cli(dut, buf) != 0)
9713 			return -1;
9714 	}
9715 
9716 	return 1;
9717 }
9718 
9719 
9720 static int ath_ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn,
9721 				 struct sigma_cmd *cmd)
9722 {
9723 	const char *val;
9724 	const char *ifname;
9725 	int chwidth, nss;
9726 
9727 	val = get_param(cmd, "FrameName");
9728 	if (!val || strcasecmp(val, "op_md_notif_frm") != 0) {
9729 		send_resp(dut, conn, SIGMA_ERROR,
9730 			  "errorCode,Unsupported FrameName");
9731 		return 0;
9732 	}
9733 
9734 	/*
9735 	 * Sequence of commands for Opmode notification on
9736 	 * Peregrine based products
9737 	 */
9738 	ifname = get_main_ifname(dut);
9739 
9740 	/* Disable STBC */
9741 	run_iwpriv(dut, ifname, "tx_stbc 0");
9742 
9743 	/* Check whether optional arg channel width was passed */
9744 	val = get_param(cmd, "Channel_width");
9745 	if (val) {
9746 		switch (atoi(val)) {
9747 		case 20:
9748 			chwidth = 0;
9749 			break;
9750 		case 40:
9751 			chwidth = 1;
9752 			break;
9753 		case 80:
9754 			chwidth = 2;
9755 			break;
9756 		case 160:
9757 			chwidth = 3;
9758 			break;
9759 		default:
9760 			chwidth = 2;
9761 			break;
9762 		}
9763 		run_iwpriv(dut, ifname, "chwidth %d", chwidth);
9764 	}
9765 
9766 	/* Check whether optional arg NSS was passed */
9767 	val = get_param(cmd, "NSS");
9768 	if (val) {
9769 		/* Convert nss to chainmask */
9770 		switch (atoi(val)) {
9771 		case 1:
9772 			nss = 1;
9773 			break;
9774 		case 2:
9775 			nss = 3;
9776 			break;
9777 		case 3:
9778 			nss = 7;
9779 			break;
9780 		default:
9781 			/* We do not support NSS > 3 */
9782 			nss = 3;
9783 			break;
9784 		}
9785 		run_iwpriv(dut, ifname, "rxchainmask %d", nss);
9786 	}
9787 
9788 	/* Send the opmode notification */
9789 	run_iwpriv(dut, ifname, "opmode_notify 1");
9790 
9791 	return 1;
9792 }
9793 
9794 
9795 static int ath_ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn,
9796 				 struct sigma_cmd *cmd)
9797 {
9798 	const char *val;
9799 	FILE *f;
9800 	int rand_int = 0;
9801 
9802 	val = get_param(cmd, "MsntType");
9803 	if (val) {
9804 		if (dut->ap_msnt_type == 0)
9805 			dut->ap_msnt_type = atoi(val);
9806 
9807 		if (dut->ap_msnt_type != 5 && dut->ap_msnt_type != 2) {
9808 			dut->ap_msnt_type = atoi(val);
9809 			if (dut->ap_msnt_type == 1) {
9810 				val = get_param(cmd, "RandInterval");
9811 				if (val)
9812 					rand_int = atoi(val);
9813 				f = fopen("/tmp/ftmrr.txt", "a");
9814 				if (!f) {
9815 					sigma_dut_print(dut, DUT_MSG_ERROR,
9816 							"Failed to open /tmp/ftmrr.txt");
9817 					return -1;
9818 				}
9819 
9820 				fprintf(f, "sta_mac = %s\n", cmd->values[3]);
9821 				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",
9822 					rand_int, cmd->values[7]);
9823 				fclose(f);
9824 				dut->ap_msnt_type = 5;
9825 				run_system(dut, "wpc -f /tmp/ftmrr.txt");
9826 			}
9827 		} else if (dut->ap_msnt_type == 5) {
9828 			run_system(dut, "wpc -f /tmp/ftmrr.txt");
9829 		} else if (dut->ap_msnt_type == 2) {
9830 			f = fopen("/tmp/wru.txt", "w");
9831 			if (!f) {
9832 				sigma_dut_print(dut, DUT_MSG_ERROR,
9833 						"Failed to open /tmp/wru.txt");
9834 				return -1;
9835 			}
9836 
9837 			fprintf(f, "sta_mac = %s\n", cmd->values[3]);
9838 			fprintf(f, "meas_type = 0x08\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0x1\nmeas_req_mode = 0x00\nloc_subject = 0x01\n");
9839 			fclose(f);
9840 			run_system(dut, "wpc -w /tmp/wru.txt");
9841 		}
9842 	}
9843 	return 1;
9844 }
9845 
9846 
9847 /*
9848  * The following functions parse_send_frame_params_int(),
9849  * parse_send_frame_params_str(), and parse_send_frame_params_mac()
9850  * are used by ath_ap_send_frame_bcn_rpt_req().
9851  * Beacon Report Request is a frame used as part of the MBO program.
9852  * The command for sending beacon report has a lot of
9853  * arguments and having these functions reduces code size.
9854  *
9855  */
9856 static int parse_send_frame_params_int(char *param, struct sigma_cmd *cmd,
9857 				       struct sigma_dut *dut,
9858 				       char *buf, size_t buf_size)
9859 {
9860 	const char *str_val;
9861 	int int_val;
9862 	char temp[100];
9863 
9864 	str_val = get_param(cmd, param);
9865 	if (!str_val) {
9866 		sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
9867 		return -1;
9868 	}
9869 	int_val = atoi(str_val);
9870 	snprintf(temp, sizeof(temp), " %d", int_val);
9871 	strlcat(buf, temp, buf_size);
9872 	return 0;
9873 }
9874 
9875 
9876 static int parse_send_frame_params_str(char *param, struct sigma_cmd *cmd,
9877 				       struct sigma_dut *dut,
9878 				       char *buf, size_t buf_size)
9879 {
9880 	const char *str_val;
9881 	char temp[100];
9882 
9883 	str_val = get_param(cmd, param);
9884 	if (!str_val) {
9885 		sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
9886 		return -1;
9887 	}
9888 	snprintf(temp, sizeof(temp), " %s", str_val);
9889 	temp[sizeof(temp) - 1] = '\0';
9890 	strlcat(buf, temp, buf_size);
9891 	return 0;
9892 }
9893 
9894 
9895 static int parse_send_frame_params_mac(char *param, struct sigma_cmd *cmd,
9896 				       struct sigma_dut *dut,
9897 				       char *buf, size_t buf_size)
9898 {
9899 	const char *str_val;
9900 	unsigned char mac[6];
9901 	char temp[100];
9902 
9903 	str_val = get_param(cmd, param);
9904 	if (!str_val) {
9905 		sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
9906 		return -1;
9907 	}
9908 
9909 	if (parse_mac_address(dut, str_val, mac) < 0) {
9910 		sigma_dut_print(dut, DUT_MSG_ERROR,
9911 				"MAC Address not in proper format");
9912 		return -1;
9913 	}
9914 	snprintf(temp, sizeof(temp), " %02x:%02x:%02x:%02x:%02x:%02x",
9915 		 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
9916 	strlcat(buf, temp, buf_size);
9917 	return 0;
9918 }
9919 
9920 
9921 static void fill_1_or_0_based_on_presence(struct sigma_cmd *cmd, char *param,
9922 					  char *buf, size_t buf_size)
9923 {
9924 	const char *str_val;
9925 	char *value = " 1";
9926 
9927 	str_val = get_param(cmd, param);
9928 	if (!str_val || str_val[0] == '\0')
9929 		value = " 0";
9930 	strlcat(buf, value, buf_size);
9931 
9932 }
9933 
9934 
9935 /*
9936  * wifitool athN sendbcnrpt
9937  * <STA MAC        - Plugs in from Dest_MAC>
9938  * <regclass       - Plugs in from RegClass - int>
9939  * <channum        - Plugs in from Channel PARAM of dev_send_frame - int>
9940  * <rand_ivl       - Plugs in from RandInt - string>
9941  * <duration       - Plugs in from MeaDur - integer>
9942  * <mode           - Plugs in from MeaMode - string>
9943  * <req_ssid       - Plugs in from SSID PARAM of dev_send_frame - string>
9944  * <rep_cond       - Plugs in from RptCond - integer>
9945  * <rpt_detail     - Plugs in from RptDet - integer>
9946  * <req_ie         - Plugs in from ReqInfo PARAM of dev_send_frame - string>
9947  * <chanrpt_mode   - Plugs in from APChanRpt - integer>
9948  * <specific_bssid - Plugs in from BSSID PARAM of dev_send_frame>
9949  * [AP channel numbers]
9950  */
9951 static int ath_ap_send_frame_bcn_rpt_req(struct sigma_dut *dut,
9952 					 struct sigma_cmd *cmd,
9953 					 const char *ifname)
9954 {
9955 	char buf[100];
9956 	int rpt_det;
9957 	const char *str_val;
9958 	const char *mea_mode;
9959 
9960 	snprintf(buf, sizeof(buf), "wifitool %s sendbcnrpt", ifname);
9961 
9962 	if (parse_send_frame_params_mac("Dest_MAC", cmd, dut, buf, sizeof(buf)))
9963 		return -1;
9964 	if (parse_send_frame_params_int("RegClass", cmd, dut, buf, sizeof(buf)))
9965 		return -1;
9966 	if (parse_send_frame_params_int("Channel", cmd, dut, buf, sizeof(buf)))
9967 		return -1;
9968 	if (parse_send_frame_params_str("RandInt", cmd, dut, buf, sizeof(buf)))
9969 		return -1;
9970 	if (parse_send_frame_params_int("MeaDur", cmd, dut, buf, sizeof(buf)))
9971 		return -1;
9972 
9973 	str_val = get_param(cmd, "MeaMode");
9974 	if (!str_val) {
9975 		sigma_dut_print(dut, DUT_MSG_ERROR,
9976 				"MeaMode parameter not present in send bcn-rpt-req");
9977 		return -1;
9978 	}
9979 	if (strcasecmp(str_val, "passive") == 0) {
9980 		mea_mode = " 0";
9981 	} else if (strcasecmp(str_val, "active") == 0) {
9982 		mea_mode = " 1";
9983 	} else if (strcasecmp(str_val, "table") == 0) {
9984 		mea_mode = " 2";
9985 	} else {
9986 		sigma_dut_print(dut, DUT_MSG_ERROR,
9987 				"MEA-MODE Value not correctly given");
9988 		return -1;
9989 	}
9990 	strlcat(buf, mea_mode, sizeof(buf));
9991 
9992 	fill_1_or_0_based_on_presence(cmd, "SSID", buf, sizeof(buf));
9993 
9994 	if (parse_send_frame_params_int("RptCond", cmd, dut, buf, sizeof(buf)))
9995 		return -1;
9996 
9997 	if (parse_send_frame_params_int("RptDet", cmd, dut, buf, sizeof(buf)))
9998 		return -1;
9999 	str_val = get_param(cmd, "RptDet");
10000 	rpt_det = str_val ? atoi(str_val) : 0;
10001 
10002 	if (rpt_det)
10003 		fill_1_or_0_based_on_presence(cmd, "ReqInfo", buf, sizeof(buf));
10004 	else
10005 		strlcat(buf, " 0", sizeof(buf));
10006 
10007 	if (rpt_det)
10008 		fill_1_or_0_based_on_presence(cmd, "APChanRpt", buf,
10009 					      sizeof(buf));
10010 	else
10011 		strlcat(buf, " 0", sizeof(buf));
10012 
10013 	if (parse_send_frame_params_mac("BSSID", cmd, dut, buf, sizeof(buf)))
10014 		return -1;
10015 
10016 	str_val = get_param(cmd, "APChanRpt");
10017 	if (str_val) {
10018 		const char *pos;
10019 		int ap_chanrpt;
10020 		int ap_chanrpt_2 = 0;
10021 		char chanrpt[100];
10022 
10023 		ap_chanrpt = atoi(str_val);
10024 		pos = strchr(str_val, '_');
10025 		if (pos) {
10026 			pos++;
10027 			ap_chanrpt_2 = atoi(pos);
10028 		}
10029 		if (ap_chanrpt) {
10030 			snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt);
10031 			strlcat(buf, chanrpt, sizeof(buf));
10032 		}
10033 		if (ap_chanrpt_2) {
10034 			snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt_2);
10035 			strlcat(buf, chanrpt, sizeof(buf));
10036 		}
10037 	}
10038 
10039 	run_system(dut, buf);
10040 	return 0;
10041 }
10042 
10043 
10044 static void inform_and_sleep(struct sigma_dut *dut, int seconds)
10045 {
10046 	sigma_dut_print(dut, DUT_MSG_DEBUG, "sleeping for %d seconds", seconds);
10047 	sleep(seconds);
10048 	sigma_dut_print(dut, DUT_MSG_DEBUG, "woke up after %d seconds",
10049 			seconds);
10050 }
10051 
10052 
10053 static int ath_ap_send_frame_btm_req(struct sigma_dut *dut,
10054 				     struct sigma_cmd *cmd, const char *ifname)
10055 {
10056 	unsigned char mac_addr[ETH_ALEN];
10057 	int disassoc_timer;
10058 	char buf[100];
10059 	const char *val;
10060 	int cand_list = 1;
10061 
10062 	val = get_param(cmd, "Dest_MAC");
10063 	if (!val || parse_mac_address(dut, val, mac_addr) < 0) {
10064 		sigma_dut_print(dut, DUT_MSG_ERROR,
10065 				"MAC Address not in proper format");
10066 		return -1;
10067 	}
10068 
10069 	val = get_param(cmd, "Disassoc_Timer");
10070 	if (val)
10071 		disassoc_timer = atoi(val);
10072 	else
10073 		disassoc_timer = dut->ap_disassoc_timer;
10074 	if (disassoc_timer < 0) {
10075 		sigma_dut_print(dut, DUT_MSG_ERROR,
10076 				"Invalid Disassoc_Timer value %d",
10077 				disassoc_timer);
10078 		return -1;
10079 	}
10080 
10081 	val = get_param(cmd, "Cand_List");
10082 	if (val && val[0])
10083 		cand_list = atoi(val);
10084 
10085 	val = get_param(cmd, "BTMQuery_Reason_Code");
10086 	if (val)
10087 		run_iwpriv(dut, ifname, "mbo_trans_rs %s", val);
10088 
10089 	if (dut->ap_btmreq_disassoc_imnt && !dut->ap_assoc_delay)
10090 		run_iwpriv(dut, ifname, "mbo_asoc_ret 1");
10091 
10092 	snprintf(buf, sizeof(buf),
10093 		 "wifitool %s sendbstmreq %02x:%02x:%02x:%02x:%02x:%02x %d %d 15 %d %d %d %d",
10094 		 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
10095 		 mac_addr[4], mac_addr[5], cand_list, disassoc_timer,
10096 		 dut->ap_btmreq_disassoc_imnt,
10097 		 dut->ap_btmreq_term_bit,
10098 		 dut->ap_btmreq_bss_term_tsf,
10099 		 dut->ap_btmreq_bss_term_dur);
10100 	run_system(dut, buf);
10101 
10102 	if (dut->ap_btmreq_term_bit) {
10103 		if (dut->ap_btmreq_bss_term_tsf >= 2)
10104 			inform_and_sleep(dut, dut->ap_btmreq_bss_term_tsf - 2);
10105 		run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10106 			   mac_addr[0], mac_addr[1], mac_addr[2],
10107 			   mac_addr[3], mac_addr[4], mac_addr[5]);
10108 		inform_and_sleep(dut, 2);
10109 		run_system_wrapper(dut, "ifconfig %s down", ifname);
10110 		inform_and_sleep(dut, 5);
10111 		run_system_wrapper(dut, "ifconfig %s up", ifname);
10112 	} else if (dut->ap_btmreq_disassoc_imnt) {
10113 		inform_and_sleep(dut, (disassoc_timer / 1000) + 1);
10114 		run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10115 			   mac_addr[0], mac_addr[1], mac_addr[2],
10116 			   mac_addr[3], mac_addr[4], mac_addr[5]);
10117 	}
10118 	return 0;
10119 }
10120 
10121 
10122 static int ath_ap_send_frame_disassoc(struct sigma_dut *dut,
10123 				      struct sigma_cmd *cmd, const char *ifname)
10124 {
10125 	unsigned char mac_addr[ETH_ALEN];
10126 	const char *val;
10127 
10128 	val = get_param(cmd, "Dest_MAC");
10129 	if (!val || parse_mac_address(dut, val, mac_addr) < 0) {
10130 		sigma_dut_print(dut, DUT_MSG_ERROR,
10131 				"MAC Address not in proper format");
10132 		return -1;
10133 	}
10134 
10135 	run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10136 		   mac_addr[0], mac_addr[1], mac_addr[2],
10137 		   mac_addr[3], mac_addr[4], mac_addr[5]);
10138 	return 0;
10139 }
10140 
10141 
10142 static int ath_ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn,
10143 				 struct sigma_cmd *cmd)
10144 {
10145 	const char *val;
10146 	const char *ifname;
10147 
10148 	ifname = get_main_ifname(dut);
10149 
10150 	val = get_param(cmd, "FrameName");
10151 	if (!val)
10152 		return -1;
10153 
10154 	if (strcasecmp(val, "BTMReq") == 0)
10155 		ath_ap_send_frame_btm_req(dut, cmd, ifname);
10156 	else if (strcasecmp(val, "BcnRptReq") == 0)
10157 		ath_ap_send_frame_bcn_rpt_req(dut, cmd, ifname);
10158 	else if (strcasecmp(val, "disassoc") == 0)
10159 		ath_ap_send_frame_disassoc(dut, cmd, ifname);
10160 	else
10161 		return -1;
10162 
10163 	return 1;
10164 }
10165 
10166 
10167 static int ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10168 			     struct sigma_cmd *cmd)
10169 {
10170 	switch (get_driver_type(dut)) {
10171 	case DRIVER_ATHEROS:
10172 		return ath_ap_send_frame_vht(dut, conn, cmd);
10173 		break;
10174 	case DRIVER_OPENWRT:
10175 		switch (get_openwrt_driver_type()) {
10176 		case OPENWRT_DRIVER_ATHEROS:
10177 			return ath_ap_send_frame_vht(dut, conn, cmd);
10178 		default:
10179 			send_resp(dut, conn, SIGMA_ERROR,
10180 				  "errorCode,Unsupported ap_send_frame with the current openwrt driver");
10181 			return 0;
10182 		}
10183 	default:
10184 		send_resp(dut, conn, SIGMA_ERROR,
10185 			  "errorCode,Unsupported ap_send_frame with the current driver");
10186 		return 0;
10187 	}
10188 }
10189 
10190 
10191 static int ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn,
10192 			     struct sigma_cmd *cmd)
10193 {
10194 	switch (get_driver_type(dut)) {
10195 	case DRIVER_ATHEROS:
10196 		return ath_ap_send_frame_loc(dut, conn, cmd);
10197 	case DRIVER_OPENWRT:
10198 		switch (get_openwrt_driver_type()) {
10199 		case OPENWRT_DRIVER_ATHEROS:
10200 			return ath_ap_send_frame_loc(dut, conn, cmd);
10201 		default:
10202 			send_resp(dut, conn, SIGMA_ERROR,
10203 				  "errorCode,Unsupported ap_send_frame_loc with the current openwrt driver");
10204 			return 0;
10205 		}
10206 	default:
10207 		send_resp(dut, conn, SIGMA_ERROR,
10208 			  "errorCode,Unsupported ap_send_frame_loc with the current driver");
10209 		return 0;
10210 	}
10211 }
10212 
10213 
10214 static int ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn,
10215 			     struct sigma_cmd *cmd)
10216 {
10217 	switch (get_driver_type(dut)) {
10218 	case DRIVER_ATHEROS:
10219 		return ath_ap_send_frame_mbo(dut, conn, cmd);
10220 	case DRIVER_OPENWRT:
10221 		switch (get_openwrt_driver_type()) {
10222 		case OPENWRT_DRIVER_ATHEROS:
10223 			return ath_ap_send_frame_mbo(dut, conn, cmd);
10224 		default:
10225 			send_resp(dut, conn, SIGMA_ERROR,
10226 				  "errorCode,Unsupported ap_send_frame with the current openwrt driver");
10227 			return 0;
10228 		}
10229 	default:
10230 		send_resp(dut, conn, SIGMA_ERROR,
10231 			  "errorCode,Unsupported ap_send_frame with the current driver");
10232 		return 0;
10233 	}
10234 }
10235 
10236 
10237 static int ap_send_frame_60g(struct sigma_dut *dut,
10238 			     struct sigma_conn *conn,
10239 			     struct sigma_cmd *cmd)
10240 {
10241 	switch (get_driver_type(dut)) {
10242 #ifdef __linux__
10243 	case DRIVER_WIL6210:
10244 		return wil6210_send_frame_60g(dut, conn, cmd);
10245 #endif /* __linux__ */
10246 	default:
10247 		send_resp(dut, conn, SIGMA_ERROR,
10248 			  "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10249 		return 0;
10250 	}
10251 }
10252 
10253 
10254 enum sigma_cmd_result cmd_ap_send_frame(struct sigma_dut *dut,
10255 					struct sigma_conn *conn,
10256 					struct sigma_cmd *cmd)
10257 {
10258 	/* const char *name = get_param(cmd, "NAME"); */
10259 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
10260 	const char *val;
10261 	enum send_frame_type frame;
10262 	enum send_frame_protection protected;
10263 	char buf[100];
10264 
10265 	val = get_param(cmd, "Program");
10266 	if (val) {
10267 		if (strcasecmp(val, "HS2") == 0 ||
10268 		    strcasecmp(val, "HS2-R2") == 0 ||
10269 		    strcasecmp(val, "IOTLP") == 0)
10270 			return ap_send_frame_hs2(dut, conn, cmd);
10271 		if (strcasecmp(val, "VHT") == 0)
10272 			return ap_send_frame_vht(dut, conn, cmd);
10273 		if (strcasecmp(val, "LOC") == 0)
10274 			return ap_send_frame_loc(dut, conn, cmd);
10275 		if (strcasecmp(val, "MBO") == 0)
10276 			return ap_send_frame_mbo(dut, conn, cmd);
10277 		if (strcasecmp(val, "60GHz") == 0)
10278 			return ap_send_frame_60g(dut, conn, cmd);
10279 	}
10280 
10281 	val = get_param(cmd, "PMFFrameType");
10282 	if (val == NULL)
10283 		val = get_param(cmd, "FrameName");
10284 	if (val == NULL)
10285 		val = get_param(cmd, "Type");
10286 	if (val == NULL)
10287 		return -1;
10288 	if (strcasecmp(val, "disassoc") == 0)
10289 		frame = DISASSOC;
10290 	else if (strcasecmp(val, "deauth") == 0)
10291 		frame = DEAUTH;
10292 	else if (strcasecmp(val, "saquery") == 0)
10293 		frame = SAQUERY;
10294 	else {
10295 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10296 			  "PMFFrameType");
10297 		return 0;
10298 	}
10299 
10300 	val = get_param(cmd, "PMFProtected");
10301 	if (val == NULL)
10302 		val = get_param(cmd, "Protected");
10303 	if (val == NULL)
10304 		return -1;
10305 	if (strcasecmp(val, "Correct-key") == 0 ||
10306 	    strcasecmp(val, "CorrectKey") == 0)
10307 		protected = CORRECT_KEY;
10308 	else if (strcasecmp(val, "IncorrectKey") == 0)
10309 		protected = INCORRECT_KEY;
10310 	else if (strcasecmp(val, "Unprotected") == 0)
10311 		protected = UNPROTECTED;
10312 	else {
10313 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10314 			  "PMFProtected");
10315 		return 0;
10316 	}
10317 
10318 	val = get_param(cmd, "stationID");
10319 	if (val == NULL)
10320 		return -1;
10321 
10322 	if (protected == INCORRECT_KEY ||
10323 	    (protected == UNPROTECTED && frame == SAQUERY))
10324 		return ap_inject_frame(dut, conn, frame, protected, val);
10325 
10326 	switch (frame) {
10327 	case DISASSOC:
10328 		snprintf(buf, sizeof(buf), "disassoc %s test=%d",
10329 			 val, protected == CORRECT_KEY);
10330 		break;
10331 	case DEAUTH:
10332 		snprintf(buf, sizeof(buf), "deauth %s test=%d",
10333 			 val, protected == CORRECT_KEY);
10334 		break;
10335 	case SAQUERY:
10336 		snprintf(buf, sizeof(buf), "sa_query %s", val);
10337 		break;
10338 	}
10339 
10340 	if (run_hostapd_cli(dut, buf) != 0)
10341 		return -2;
10342 
10343 	return 1;
10344 }
10345 
10346 
10347 static enum sigma_cmd_result cmd_ap_get_mac_address(struct sigma_dut *dut,
10348 						    struct sigma_conn *conn,
10349 						    struct sigma_cmd *cmd)
10350 {
10351 #if defined( __linux__)
10352 	/* const char *name = get_param(cmd, "NAME"); */
10353 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
10354 	char resp[100];
10355 	unsigned char addr[6];
10356 	char ifname[50];
10357 	struct ifreq ifr;
10358 	int s, wlan_tag = 1;
10359 	const char *val;
10360 
10361 	val = get_param(cmd, "WLAN_TAG");
10362 	if (val) {
10363 		wlan_tag = atoi(val);
10364 		if (wlan_tag < 1 || wlan_tag > 3) {
10365 			/*
10366 			 * The only valid WLAN Tags as of now as per the latest
10367 			 * WFA scripts are 1, 2, and 3.
10368 			 */
10369 			send_resp(dut, conn, SIGMA_ERROR,
10370 				  "errorCode,Unsupported WLAN_TAG");
10371 			return 0;
10372 		}
10373 	}
10374 
10375 	get_if_name(dut, ifname, sizeof(ifname), wlan_tag);
10376 
10377 	s = socket(AF_INET, SOCK_DGRAM, 0);
10378 	if (s < 0)
10379 		return -1;
10380 	memset(&ifr, 0, sizeof(ifr));
10381 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10382 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
10383 		perror("ioctl");
10384 		close(s);
10385 		snprintf(resp, sizeof(resp),
10386 			 "errorCode,Could not find interface %s", ifname);
10387 		send_resp(dut, conn, SIGMA_ERROR, resp);
10388 		return 0;
10389 	}
10390 	close(s);
10391 	memcpy(addr, ifr.ifr_hwaddr.sa_data, 6);
10392 
10393 	snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x",
10394 		 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
10395 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
10396 	return 0;
10397 #elif defined( __QNXNTO__)
10398 	char resp[50];
10399 	unsigned char addr[6];
10400 
10401 	if (!dut->main_ifname) {
10402 		send_resp(dut, conn, SIGMA_ERROR, "ifname is null");
10403 		return 0;
10404 	}
10405 
10406 	if (get_hwaddr(get_main_ifname(dut), addr) != 0) {
10407 		send_resp(dut, conn, SIGMA_ERROR,
10408 			  "errorCode,Failed to get address");
10409 		return 0;
10410 	}
10411 	snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x",
10412 		 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
10413 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
10414 	return 0;
10415 #else /* __linux__ */
10416 	send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_get_mac_address not "
10417 		  "yet supported");
10418 	return 0;
10419 #endif /* __linux__ */
10420 }
10421 
10422 
10423 int sta_cfon_get_mac_address(struct sigma_dut *dut, struct sigma_conn *conn,
10424 			     struct sigma_cmd *cmd)
10425 {
10426 	return cmd_ap_get_mac_address(dut, conn, cmd);
10427 }
10428 
10429 
10430 static enum sigma_cmd_result cmd_ap_set_pmf(struct sigma_dut *dut,
10431 					    struct sigma_conn *conn,
10432 					    struct sigma_cmd *cmd)
10433 {
10434 	/*
10435 	 * Ignore the command since the parameters are already handled through
10436 	 * ap_set_security.
10437 	 */
10438 
10439 	return 1;
10440 }
10441 
10442 
10443 static enum sigma_cmd_result cmd_ap_set_hs2(struct sigma_dut *dut,
10444 					    struct sigma_conn *conn,
10445 					    struct sigma_cmd *cmd)
10446 {
10447 	/* const char *name = get_param(cmd, "NAME"); */
10448 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
10449 	const char *val, *dest;
10450 	char *pos, buf[100];
10451 	int i, wlan_tag = 1, res;
10452 
10453 	sigma_dut_print(dut, DUT_MSG_INFO, "ap_set_hs2: Processing the "
10454 			"following parameters");
10455 	for (i = 0; i < cmd->count; i++) {
10456 		sigma_dut_print(dut, DUT_MSG_INFO, "%s %s", cmd->params[i],
10457 				(cmd->values[i] ? cmd->values[i] : "NULL"));
10458 	}
10459 
10460 	val = get_param(cmd, "ICMPv4_ECHO");
10461 	if (val && atoi(val)) {
10462 		snprintf(buf, sizeof(buf), "ebtables -F");
10463 		if (system(buf) != 0) {
10464 			sigma_dut_print(dut, DUT_MSG_ERROR,
10465 					"Failed to set ebtables rules, RULE-12");
10466 		}
10467 		return 1;
10468 	}
10469 
10470 	val = get_param(cmd, "WLAN_TAG");
10471 	if (val) {
10472 		wlan_tag = atoi(val);
10473 		if (wlan_tag != 1 && wlan_tag != 2) {
10474 			send_resp(dut, conn, SIGMA_INVALID,
10475 				  "errorCode,Invalid WLAN_TAG");
10476 			return 0;
10477 		}
10478 	}
10479 
10480 	if (wlan_tag == 2) {
10481 		val = get_param(cmd, "PROXY_ARP");
10482 		if (val)
10483 			dut->ap2_proxy_arp = atoi(val);
10484 
10485 		val = get_param(cmd, "OSU");
10486 		if (val)
10487 			dut->ap2_osu = atoi(val);
10488 		return 1;
10489 	}
10490 
10491 	dest = get_param(cmd, "STA_MAC");
10492 	if (dest) {
10493 		/* This is a special/ugly way of using this command.
10494 		 * If "Dest" MAC is included, assume that this command
10495 		 * is being issued after ap_config_commit for dynamically
10496 		 * setting the QoS Map Set.
10497 		 */
10498 		val = get_param(cmd, "QoS_MAP_SET");
10499 		if (val) {
10500 			dut->ap_qos_map_set = atoi(val);
10501 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
10502 					dut->ap_qos_map_set);
10503 		}
10504 
10505 		if (dut->ap_qos_map_set == 1)
10506 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1);
10507 		else if (dut->ap_qos_map_set == 2)
10508 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2);
10509 
10510 		snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest);
10511 		if (run_hostapd_cli(dut, buf) != 0)
10512 			return -1;
10513 	}
10514 
10515 	val = get_param(cmd, "DGAF_DISABLE");
10516 	if (val)
10517 		dut->ap_dgaf_disable = atoi(val);
10518 
10519 	dut->ap_interworking = 1;
10520 
10521 	val = get_param(cmd, "INTERWORKING");
10522 	if (val == NULL)
10523 		val = get_param(cmd, "INTERNETWORKING");
10524 	if (val != NULL && atoi(val) == 0) {
10525 		dut->ap_interworking = 0;
10526 		dut->ap_hs2 = 0;
10527 		return 1;
10528 	}
10529 
10530 	val = get_param(cmd, "ACCS_NET_TYPE");
10531 	if (val) {
10532 		if (strcasecmp(val, "Chargeable_Public_Network") == 0 ||
10533 		    strcasecmp(val, "Chargable_Public_Network") == 0 ||
10534 		    strcasecmp(val, "Chargable Public Network") == 0)
10535 			dut->ap_access_net_type = 2;
10536 		else
10537 			dut->ap_access_net_type = atoi(val);
10538 	}
10539 
10540 	val = get_param(cmd, "INTERNET");
10541 	if (val)
10542 		dut->ap_internet = atoi(val);
10543 
10544 	val = get_param(cmd, "VENUE_GRP");
10545 	if (val) {
10546 		if (strcasecmp(val, "Business") == 0)
10547 			dut->ap_venue_group = 2;
10548 		else
10549 			dut->ap_venue_group = atoi(val);
10550 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d",
10551 				dut->ap_venue_name);
10552 	}
10553 
10554 	val = get_param(cmd, "VENUE_TYPE");
10555 	if (val) {
10556 		if (strcasecmp(val, "R&D") == 0)
10557 			dut->ap_venue_type = 8;
10558 		else
10559 			dut->ap_venue_type = atoi(val);
10560 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_type %d",
10561 				dut->ap_venue_type);
10562 	}
10563 
10564 	val = get_param(cmd, "HESSID");
10565 	if (val) {
10566 		if (strlen(val) >= sizeof(dut->ap_hessid)) {
10567 			send_resp(dut, conn, SIGMA_ERROR,
10568 				  "errorCode,Invalid HESSID");
10569 			return 0;
10570 		}
10571 		snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), "%s", val);
10572 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_hessid %s",
10573 				dut->ap_hessid);
10574 	}
10575 
10576 	val = get_param(cmd, "ROAMING_CONS");
10577 	if (val) {
10578 		if (strlen(val) >= sizeof(dut->ap_roaming_cons)) {
10579 			send_resp(dut, conn, SIGMA_ERROR,
10580 				  "errorCode,Invalid ROAMING_CONS");
10581 			return 0;
10582 		}
10583 		if (strcasecmp(val, "Disabled") == 0) {
10584 			dut->ap_roaming_cons[0] = '\0';
10585 		} else {
10586 			snprintf(dut->ap_roaming_cons,
10587 				 sizeof(dut->ap_roaming_cons), "%s", val);
10588 		}
10589 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_roaming_cons %s",
10590 				dut->ap_roaming_cons);
10591 	}
10592 
10593 	val = get_param(cmd, "ANQP");
10594 	if (val)
10595 		dut->ap_anqpserver_on = atoi(val);
10596 
10597 	val = get_param(cmd, "NAI_REALM_LIST");
10598 	if (val) {
10599 		dut->ap_nai_realm_list = atoi(val);
10600 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_nai_realm_list %d",
10601 				dut->ap_nai_realm_list);
10602 	}
10603 
10604 	val = get_param(cmd, "3GPP_INFO");
10605 	if (val) {
10606 		/* What kind of encoding format is used?! */
10607 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,3GPP_INFO "
10608 			  "not yet supported (contents not fully defined)");
10609 		return 0;
10610 	}
10611 
10612 	val = get_param(cmd, "DOMAIN_LIST");
10613 	if (val) {
10614 		if (strlen(val) >= sizeof(dut->ap_domain_name_list)) {
10615 			send_resp(dut, conn, SIGMA_ERROR, "errorCode,Too long "
10616 				  "DOMAIN_LIST");
10617 			return 0;
10618 		}
10619 		snprintf(dut->ap_domain_name_list,
10620 			 sizeof(dut->ap_domain_name_list), "%s", val);
10621 		pos = dut->ap_domain_name_list;
10622 		while (*pos) {
10623 			if (*pos == ';')
10624 				*pos = ',';
10625 			pos++;
10626 		}
10627 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_domain_name_list %s",
10628 				dut->ap_domain_name_list);
10629 	}
10630 
10631 	val = get_param(cmd, "OPER_NAME");
10632 	if (val) {
10633 		dut->ap_oper_name = atoi(val);
10634 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_name %d",
10635 				dut->ap_oper_name);
10636 	}
10637 
10638 	val = get_param(cmd, "VENUE_NAME");
10639 	if (val) {
10640 		dut->ap_venue_name = atoi(val);
10641 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d",
10642 				dut->ap_venue_name);
10643 	}
10644 
10645 	val = get_param(cmd, "GAS_CB_DELAY");
10646 	if (val) {
10647 		dut->ap_gas_cb_delay = atoi(val);
10648 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_gas_cb_delay %d",
10649 				dut->ap_gas_cb_delay);
10650 	}
10651 
10652 	val = get_param(cmd, "MIH");
10653 	if (val && atoi(val) > 0) {
10654 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,MIH not "
10655 			  "supported");
10656 		return 0;
10657 	}
10658 
10659 	val = get_param(cmd, "L2_TRAFFIC_INSPECT");
10660 	if (val) {
10661 		dut->ap_l2tif = atoi(val);
10662 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_l2tif %d",
10663 				dut->ap_l2tif);
10664 	}
10665 
10666 	val = get_param(cmd, "BCST_UNCST");
10667 	if (val) {
10668 		send_resp(dut, conn, SIGMA_ERROR,
10669 			  "errorCode,BCST_UNCST not yet supported");
10670 		return 0;
10671 	}
10672 
10673 	val = get_param(cmd, "PLMN_MCC");
10674 	if (val) {
10675 		char mcc[100], *start, *end;
10676 		int i = 0;
10677 		if (strlen(val) >= sizeof(mcc)) {
10678 			send_resp(dut, conn, SIGMA_ERROR,
10679 				  "errorCode,PLMN_MCC too long");
10680 			return 0;
10681 		}
10682 		strlcpy(mcc, val, sizeof(mcc));
10683 		start = mcc;
10684 		while ((end = strchr(start, ';'))) {
10685 			/* process all except the last */
10686 			*end = '\0';
10687 			if (strlen(start) != 3) {
10688 				send_resp(dut, conn, SIGMA_ERROR,
10689 					  "errorCode,Invalid PLMN_MCC");
10690 				return 0;
10691 			}
10692 			res = snprintf(dut->ap_plmn_mcc[i],
10693 				       sizeof(dut->ap_plmn_mcc[i]), "%s",
10694 				       start);
10695 			if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i]))
10696 				return ERROR_SEND_STATUS;
10697 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s",
10698 					dut->ap_plmn_mcc[i]);
10699 			i++;
10700 			start = end + 1;
10701 			*end = ';';
10702 		}
10703 		if (strlen(start) != 3) {
10704 			send_resp(dut, conn, SIGMA_ERROR,
10705 				  "errorCode,Invalid PLMN_MCC");
10706 			return 0;
10707 		}
10708 		/* process last or only one */
10709 		res = snprintf(dut->ap_plmn_mcc[i],
10710 			       sizeof(dut->ap_plmn_mcc[i]), "%s", start);
10711 		if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i]))
10712 			return ERROR_SEND_STATUS;
10713 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s",
10714 			dut->ap_plmn_mcc[i]);
10715 	}
10716 
10717 	val = get_param(cmd, "PLMN_MNC");
10718 	if (val) {
10719 		char mnc[100], *start, *end;
10720 		int i = 0;
10721 		if (strlen(val) >= sizeof(mnc)) {
10722 			send_resp(dut, conn, SIGMA_ERROR,
10723 				  "errorCode,PLMN_MNC too long");
10724 			return 0;
10725 		}
10726 		strlcpy(mnc, val, sizeof(mnc));
10727 		start = mnc;
10728 		while ((end = strchr(start, ';'))) {
10729 			*end = '\0';
10730 			if (strlen(start) != 2 && strlen(start) != 3) {
10731 				send_resp(dut, conn, SIGMA_ERROR,
10732 					"errorCode,Invalid PLMN_MNC");
10733 				return 0;
10734 			}
10735 			res = snprintf(dut->ap_plmn_mnc[i],
10736 				       sizeof(dut->ap_plmn_mnc[i]), "%s",
10737 				       start);
10738 			if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i]))
10739 				return ERROR_SEND_STATUS;
10740 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s",
10741 				dut->ap_plmn_mnc[i]);
10742 			i++;
10743 			start = end + 1;
10744 			*end = ';';
10745 		}
10746 		if (strlen(start) != 2 && strlen(start) != 3) {
10747 			send_resp(dut, conn, SIGMA_ERROR,
10748 				  "errorCode,Invalid PLMN_MNC");
10749 			return 0;
10750 		}
10751 		res = snprintf(dut->ap_plmn_mnc[i],
10752 			       sizeof(dut->ap_plmn_mnc[i]), "%s", start);
10753 		if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i]))
10754 			return ERROR_SEND_STATUS;
10755 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s",
10756 			dut->ap_plmn_mnc[i]);
10757 	}
10758 
10759 	val = get_param(cmd, "PROXY_ARP");
10760 	if (val) {
10761 		dut->ap_proxy_arp = atoi(val);
10762 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_proxy_arp %d",
10763 				dut->ap_proxy_arp);
10764 	}
10765 
10766 	val = get_param(cmd, "WAN_METRICS");
10767 	if (val) {
10768 		dut->ap_wan_metrics = atoi(val);
10769 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_wan_metrics %d",
10770 				dut->ap_wan_metrics);
10771 	}
10772 
10773 	val = get_param(cmd, "CONN_CAP");
10774 	if (val) {
10775 		dut->ap_conn_capab = atoi(val);
10776 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_conn_capab %d",
10777 				dut->ap_conn_capab);
10778 	}
10779 
10780 	val = get_param(cmd, "IP_ADD_TYPE_AVAIL");
10781 	if (val) {
10782 		dut->ap_ip_addr_type_avail = atoi(val);
10783 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_ip_addr_type_avail %d",
10784 				dut->ap_ip_addr_type_avail);
10785 	}
10786 
10787 	val = get_param(cmd, "NET_AUTH_TYPE");
10788 	if (val) {
10789 		dut->ap_net_auth_type = atoi(val);
10790 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_net_auth_type %d",
10791 				dut->ap_net_auth_type);
10792 	}
10793 
10794 	val = get_param(cmd, "OP_CLASS");
10795 	if (val == NULL)
10796 		val = get_param(cmd, "OPER_CLASS");
10797 	if (val) {
10798 		dut->ap_oper_class = atoi(val);
10799 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_class %d",
10800 				dut->ap_oper_class);
10801 	}
10802 
10803 	val = get_param(cmd, "OSU_PROVIDER_LIST");
10804 	if (val) {
10805 		dut->ap_osu_provider_list = atoi(val);
10806 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_osu_provider_list %d",
10807 				dut->ap_osu_provider_list);
10808 	}
10809 
10810 	val = get_param(cmd, "OSU_PROVIDER_NAI_LIST");
10811 	if (val) {
10812 		dut->ap_osu_provider_nai_list = atoi(val);
10813 		sigma_dut_print(dut, DUT_MSG_INFO,
10814 				"ap_osu_provider_nai_list %d",
10815 				dut->ap_osu_provider_nai_list);
10816 	}
10817 
10818 	val = get_param(cmd, "OSU_SERVER_URI");
10819 	if (val) {
10820 		i = 0;
10821 		do {
10822 			int len;
10823 			const char *uri = val;
10824 			val = strchr(val, ' ');
10825 			len = val ? (val++ - uri) : (int) strlen(uri);
10826 			if (len > 0 && len < 256) {
10827 				memcpy(dut->ap_osu_server_uri[i], uri, len);
10828 				dut->ap_osu_server_uri[i][len] = '\0';
10829 				sigma_dut_print(dut, DUT_MSG_INFO,
10830 						"ap_osu_server_uri[%d] %s", i,
10831 						dut->ap_osu_server_uri[i]);
10832 			}
10833 		} while (val && ++i < 10);
10834 	}
10835 
10836 	val = get_param(cmd, "OSU_METHOD");
10837 	if (val) {
10838 		i = 0;
10839 		do {
10840 			int len;
10841 			const char *method = val;
10842 			val = strchr(val, ' ');
10843 			len = val ? (val++ - method) : (int) strlen(method);
10844 			if (len > 0) {
10845 				if (strncasecmp(method, "SOAP", len) == 0)
10846 					dut->ap_osu_method[i] = 1;
10847 				else if (strncasecmp(method, "OMADM", len) == 0)
10848 					dut->ap_osu_method[i] = 0;
10849 				else
10850 					return -2;
10851 			}
10852 		} while (val && ++i < 10);
10853 	}
10854 
10855 	val = get_param(cmd, "OSU_SSID");
10856 	if (val) {
10857 		if (strlen(val) > 0 && strlen(val) <= 32) {
10858 			strlcpy(dut->ap_osu_ssid, val,
10859 				sizeof(dut->ap_osu_ssid));
10860 			sigma_dut_print(dut, DUT_MSG_INFO,
10861 					"ap_osu_ssid %s",
10862 					dut->ap_osu_ssid);
10863 		}
10864 	}
10865 
10866 	val = get_param(cmd, "OSU_ICON_TAG");
10867 	if (val)
10868 		dut->ap_osu_icon_tag = atoi(val);
10869 
10870 	val = get_param(cmd, "QoS_MAP_SET");
10871 	if (val) {
10872 		dut->ap_qos_map_set = atoi(val);
10873 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
10874 				dut->ap_qos_map_set);
10875 	}
10876 
10877 	val = get_param(cmd, "BSS_LOAD");
10878 	if (val) {
10879 		dut->ap_bss_load = atoi(val);
10880 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_bss_load %d",
10881 				dut->ap_bss_load);
10882 	}
10883 
10884 	val = get_param(cmd, "Venue_URL");
10885 	if (val)
10886 		dut->ap_venue_url = atoi(val);
10887 
10888 	val = get_param(cmd, "Advice_of_Charge");
10889 	if (val)
10890 		dut->ap_advice_of_charge = atoi(val);
10891 
10892 	val = get_param(cmd, "Operator_Icon_Metadata");
10893 	if (val)
10894 		dut->ap_oper_icon_metadata = atoi(val);
10895 
10896 	val = get_param(cmd, "TnC_File_Name");
10897 	if (val)
10898 		dut->ap_tnc_file_name = atoi(val);
10899 
10900 	val = get_param(cmd, "TnC_File_Time_Stamp");
10901 	if (val)
10902 		dut->ap_tnc_time_stamp = strtol(val, NULL, 10);
10903 
10904 	return 1;
10905 }
10906 
10907 
10908 void nfc_status(struct sigma_dut *dut, const char *state, const char *oper)
10909 {
10910 	char buf[100];
10911 
10912 	if (!file_exists("nfc-status"))
10913 		return;
10914 
10915 	snprintf(buf, sizeof(buf), "./nfc-status %s %s", state, oper);
10916 	run_system(dut, buf);
10917 }
10918 
10919 
10920 static int run_nfc_command(struct sigma_dut *dut, const char *cmd,
10921 			   const char *info)
10922 {
10923 	int res;
10924 
10925 	printf("\n\n\n=====[ NFC operation ]=========================\n\n");
10926 	printf("%s\n\n", info);
10927 
10928 	nfc_status(dut, "START", info);
10929 	res = run_system(dut, cmd);
10930 	nfc_status(dut, res ? "FAIL" : "SUCCESS", info);
10931 	if (res) {
10932 		sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s': %d",
10933 				cmd, res);
10934 		return res;
10935 	}
10936 
10937 	return 0;
10938 }
10939 
10940 
10941 static int ap_nfc_write_config_token(struct sigma_dut *dut,
10942 				     struct sigma_conn *conn,
10943 				     struct sigma_cmd *cmd)
10944 {
10945 	int res;
10946 	char buf[300];
10947 
10948 	run_system(dut, "killall wps-ap-nfc.py");
10949 	unlink("nfc-success");
10950 	snprintf(buf, sizeof(buf),
10951 		 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-config",
10952 		 dut->summary_log ? "--summary " : "",
10953 		 dut->summary_log ? dut->summary_log : "");
10954 	res = run_nfc_command(dut, buf,
10955 			      "Touch NFC Tag to write WPS configuration token");
10956 	if (res || !file_exists("nfc-success")) {
10957 		send_resp(dut, conn, SIGMA_ERROR,
10958 			  "ErrorCode,Failed to write tag");
10959 		return 0;
10960 	}
10961 
10962 	return 1;
10963 }
10964 
10965 
10966 static int ap_nfc_wps_read_passwd(struct sigma_dut *dut,
10967 				  struct sigma_conn *conn,
10968 				  struct sigma_cmd *cmd)
10969 {
10970 	int res;
10971 	char buf[300];
10972 
10973 	run_system(dut, "killall wps-ap-nfc.py");
10974 
10975 	unlink("nfc-success");
10976 	snprintf(buf, sizeof(buf),
10977 		 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success",
10978 		 dut->summary_log ? "--summary " : "",
10979 		 dut->summary_log ? dut->summary_log : "");
10980 	res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
10981 	if (res || !file_exists("nfc-success")) {
10982 		send_resp(dut, conn, SIGMA_ERROR,
10983 			  "ErrorCode,Failed to read tag");
10984 		return 0;
10985 	}
10986 
10987 	return 1;
10988 }
10989 
10990 
10991 static int ap_nfc_write_password_token(struct sigma_dut *dut,
10992 				       struct sigma_conn *conn,
10993 				       struct sigma_cmd *cmd)
10994 {
10995 	int res;
10996 	char buf[300];
10997 
10998 	run_system(dut, "killall wps-ap-nfc.py");
10999 	unlink("nfc-success");
11000 	snprintf(buf, sizeof(buf),
11001 		 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-password",
11002 		 dut->summary_log ? "--summary " : "",
11003 		 dut->summary_log ? dut->summary_log : "");
11004 	res = run_nfc_command(dut, buf,
11005 			      "Touch NFC Tag to write WPS password token");
11006 	if (res || !file_exists("nfc-success")) {
11007 		send_resp(dut, conn, SIGMA_ERROR,
11008 			  "ErrorCode,Failed to write tag");
11009 		return 0;
11010 	}
11011 
11012 	if (run_hostapd_cli(dut, "wps_nfc_token enable") != 0) {
11013 		send_resp(dut, conn, SIGMA_ERROR,
11014 			  "ErrorCode,Failed to enable NFC password token");
11015 		return 0;
11016 	}
11017 
11018 	return 1;
11019 }
11020 
11021 
11022 static int ap_nfc_wps_connection_handover(struct sigma_dut *dut,
11023 					  struct sigma_conn *conn,
11024 					  struct sigma_cmd *cmd)
11025 {
11026 	int res;
11027 	char buf[300];
11028 
11029 	run_system(dut, "killall wps-ap-nfc.py");
11030 	unlink("nfc-success");
11031 	snprintf(buf, sizeof(buf),
11032 		 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success",
11033 		 dut->summary_log ? "--summary " : "",
11034 		 dut->summary_log ? dut->summary_log : "");
11035 	res = run_nfc_command(dut, buf,
11036 			      "Touch NFC Device to respond to WPS connection handover");
11037 	if (res) {
11038 		send_resp(dut, conn, SIGMA_ERROR,
11039 			  "ErrorCode,Failed to enable NFC for connection "
11040 			  "handover");
11041 		return 0;
11042 	}
11043 	if (!file_exists("nfc-success")) {
11044 		send_resp(dut, conn, SIGMA_ERROR,
11045 			  "ErrorCode,Failed to complete NFC connection handover");
11046 		return 0;
11047 	}
11048 
11049 	return 1;
11050 }
11051 
11052 
11053 static enum sigma_cmd_result cmd_ap_nfc_action(struct sigma_dut *dut,
11054 					       struct sigma_conn *conn,
11055 					       struct sigma_cmd *cmd)
11056 {
11057 	/* const char *name = get_param(cmd, "Name"); */
11058 	/* const char *intf = get_param(cmd, "Interface"); */
11059 	const char *oper = get_param(cmd, "Operation");
11060 
11061 	if (oper == NULL)
11062 		return -1;
11063 
11064 	if (strcasecmp(oper, "WRITE_CONFIG") == 0)
11065 		return ap_nfc_write_config_token(dut, conn, cmd);
11066 	if (strcasecmp(oper, "WRITE_PASSWD") == 0)
11067 		return ap_nfc_write_password_token(dut, conn, cmd);
11068 	if (strcasecmp(oper, "WPS_READ_PASSWD") == 0)
11069 		return ap_nfc_wps_read_passwd(dut, conn, cmd);
11070 	if (strcasecmp(oper, "WPS_CONN_HNDOVR") == 0)
11071 		return ap_nfc_wps_connection_handover(dut, conn, cmd);
11072 
11073 	send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported operation");
11074 	return 0;
11075 }
11076 
11077 
11078 static enum sigma_cmd_result cmd_ap_wps_read_pin(struct sigma_dut *dut,
11079 						 struct sigma_conn *conn,
11080 						 struct sigma_cmd *cmd)
11081 {
11082 	char *pin = "12345670"; /* TODO: use random PIN */
11083 	char resp[100];
11084 
11085 	snprintf(resp, sizeof(resp), "PIN,%s", pin);
11086 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
11087 
11088 	return 0;
11089 }
11090 
11091 
11092 static enum sigma_cmd_result cmd_ap_wps_enter_pin(struct sigma_dut *dut,
11093 						  struct sigma_conn *conn,
11094 						  struct sigma_cmd *cmd)
11095 {
11096 	const char *pin = get_param(cmd, "PIN");
11097 	char wps_pin[11];
11098 
11099 	if (!pin)
11100 		return -1;
11101 
11102 	sigma_dut_print(dut, DUT_MSG_DEBUG,
11103 			"Authorize a client to join with WPS PIN %s", pin);
11104 
11105 	strlcpy(wps_pin, pin, sizeof(wps_pin));
11106 	/* we need to tolerate extra '-' characters entered */
11107 	str_remove_chars(wps_pin, '-');
11108 	strlcpy(dut->wps_pin, wps_pin, sizeof(dut->wps_pin));
11109 	dut->wps_method = WFA_CS_WPS_PIN_KEYPAD;
11110 
11111 	return 1;
11112 }
11113 
11114 
11115 static enum sigma_cmd_result cmd_ap_wps_set_pbc(struct sigma_dut *dut,
11116 						struct sigma_conn *conn,
11117 						struct sigma_cmd *cmd)
11118 {
11119 	sigma_dut_print(dut, DUT_MSG_DEBUG,
11120 			"Selecting the push button configuration method");
11121 
11122 	dut->wps_method = WFA_CS_WPS_PBC;
11123 
11124 	return 1;
11125 }
11126 
11127 
11128 int ap_wps_registration(struct sigma_dut *dut, struct sigma_conn *conn,
11129 			struct sigma_cmd *cmd)
11130 {
11131 	char buf[100], resp[256];
11132 	const char *intf = get_param(cmd, "interface");
11133 	const char *config_method = get_param(cmd, "WPSConfigMethod");
11134 
11135 	if (config_method && strcasecmp(config_method, "PBC") == 0)
11136 		dut->wps_method = WFA_CS_WPS_PBC;
11137 
11138 	if (!intf)
11139 		intf = get_main_ifname(dut);
11140 
11141 	if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
11142 		send_resp(dut, conn, SIGMA_ERROR,
11143 			  "ErrorCode,WPS parameters not yet set");
11144 		return STATUS_SENT;
11145 	}
11146 
11147 	if (dut->wps_method == WFA_CS_WPS_PBC)
11148 		snprintf(buf, sizeof(buf), "WPS_PBC");
11149 	else /* WFA_CS_WPS_PIN_KEYPAD */
11150 		snprintf(buf, sizeof(buf), "WPS_PIN any %s", dut->wps_pin);
11151 
11152 	/* Run WPS command */
11153 	if (hapd_command(intf, buf) < 0) {
11154 		/* command fails immediately if overlapped session detected */
11155 		snprintf(resp, sizeof(resp), "WpsState,OverlapSession");
11156 		send_resp(dut, conn, SIGMA_COMPLETE, resp);
11157 		return STATUS_SENT;
11158 	}
11159 
11160 	/* In AP mode return immediately and do not wait for WPS registration */
11161 	return SUCCESS_SEND_STATUS;
11162 }
11163 
11164 
11165 static enum sigma_cmd_result cmd_ap_get_parameter(struct sigma_dut *dut,
11166 						  struct sigma_conn *conn,
11167 						  struct sigma_cmd *cmd)
11168 {
11169 	char value[256], resp[512];
11170 	const char *param = get_param(cmd, "parameter");
11171 	const char *ifname = get_param(cmd, "Interface");
11172 	const char *var;
11173 
11174 	if (!ifname)
11175 		ifname = get_main_ifname(dut);
11176 
11177 	if (!param) {
11178 		send_resp(dut, conn, SIGMA_ERROR,
11179 			  "ErrorCode,Parameter not specified");
11180 		return 0;
11181 	}
11182 
11183 	if (strcasecmp(param, "SSID") == 0) {
11184 		if (get_hapd_config(ifname, "ssid", value, sizeof(value))) {
11185 			sigma_dut_print(dut, DUT_MSG_ERROR,
11186 					"Failed to get SSID");
11187 			return -2;
11188 		}
11189 		snprintf(resp, sizeof(resp), "SSID,%s", value);
11190 	} else if (strcasecmp(param, "PSK") == 0) {
11191 		if (get_hapd_config(ifname, "passphrase", value,
11192 				    sizeof(value))) {
11193 			sigma_dut_print(dut, DUT_MSG_ERROR,
11194 					"Failed to get PSK");
11195 			return -2;
11196 		}
11197 		snprintf(resp, sizeof(resp), "PSK,%s", value);
11198 	} else if (strcasecmp(param, "PMK") == 0) {
11199 		var = get_param(cmd, "STA_MAC_Address");
11200 		if (!var)
11201 			return INVALID_SEND_STATUS;
11202 		snprintf(resp, sizeof(resp), "GET_PMK %s", var);
11203 		if (hapd_command_resp(ifname, resp, &resp[4],
11204 				      sizeof(resp) - 4) < 0) {
11205 			send_resp(dut, conn, SIGMA_ERROR,
11206 				  "ErrorCode,GET_PMK failed");
11207 			return STATUS_SENT_ERROR;
11208 		}
11209 		memcpy(resp, "PMK,", 4);
11210 	} else {
11211 		send_resp(dut, conn, SIGMA_ERROR,
11212 			  "ErrorCode,Unsupported parameter");
11213 		return 0;
11214 	}
11215 
11216 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
11217 	return 0;
11218 }
11219 
11220 
11221 static int ath_vht_op_mode_notif(struct sigma_dut *dut, const char *ifname,
11222 				 const char *val)
11223 {
11224 	char *token, *result;
11225 	int nss = 0, chwidth = 0;
11226 	char *saveptr;
11227 
11228 	/*
11229 	 * The following commands should be invoked to generate
11230 	 * VHT op mode notification
11231 	 */
11232 
11233 	/* Extract the NSS info */
11234 	token = strdup(val);
11235 	if (!token)
11236 		return -1;
11237 	result = strtok_r(token, ";", &saveptr);
11238 	if (result) {
11239 		int count = atoi(result);
11240 
11241 		/* We do not support NSS > 3 */
11242 		if (count < 0 || count > 3) {
11243 			free(token);
11244 			return -1;
11245 		}
11246 
11247 		/* Convert nss to chainmask */
11248 		while (count--)
11249 			nss = (nss << 1) | 1;
11250 
11251 		run_iwpriv(dut, ifname, "rxchainmask %d", nss);
11252 	}
11253 
11254 	/* Extract the Channel width info */
11255 	result = strtok_r(NULL, ";", &saveptr);
11256 	if (result) {
11257 		switch (atoi(result)) {
11258 		case 20:
11259 			chwidth = 0;
11260 			break;
11261 		case 40:
11262 			chwidth = 1;
11263 			break;
11264 		case 80:
11265 			chwidth = 2;
11266 			break;
11267 		case 160:
11268 			chwidth = 3;
11269 			break;
11270 		default:
11271 			chwidth = 2;
11272 			break;
11273 		}
11274 		run_iwpriv(dut, ifname, "chwidth %d", chwidth);
11275 	}
11276 
11277 	/* Send the opmode notification */
11278 	run_iwpriv(dut, ifname, "opmode_notify 1");
11279 	free(token);
11280 
11281 	return 0;
11282 }
11283 
11284 
11285 static int ath_vht_nss_mcs(struct sigma_dut *dut, const char *ifname,
11286 			   const char *val)
11287 {
11288 	/* String (nss_operating_mode; mcs_operating_mode) */
11289 	int nss, mcs;
11290 	char *token, *result;
11291 	char *saveptr;
11292 
11293 	token = strdup(val);
11294 	if (!token)
11295 		return -1;
11296 	result = strtok_r(token, ";", &saveptr);
11297 	if (!result) {
11298 		sigma_dut_print(dut, DUT_MSG_ERROR,
11299 				"VHT NSS not specified");
11300 		goto end;
11301 	}
11302 	if (strcasecmp(result, "def") != 0) {
11303 		nss = atoi(result);
11304 
11305 		if (nss == 4)
11306 			ath_disable_txbf(dut, ifname);
11307 
11308 		run_iwpriv(dut, ifname, "nss %d", nss);
11309 	} else {
11310 		if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1)
11311 			run_iwpriv(dut, ifname, "nss 1");
11312 		if (dut->device_type == AP_testbed &&
11313 		    dut->program == PROGRAM_HE) {
11314 			nss = dut->ap_tx_streams;
11315 			run_iwpriv(dut, ifname, "nss %d", nss);
11316 		}
11317 	}
11318 
11319 	result = strtok_r(NULL, ";", &saveptr);
11320 	if (!result) {
11321 		sigma_dut_print(dut, DUT_MSG_ERROR,
11322 				"VHT MCS not specified");
11323 		goto end;
11324 	}
11325 	if (strcasecmp(result, "def") == 0) {
11326 		if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1)
11327 			run_iwpriv(dut, ifname, "vhtmcs 7");
11328 		else
11329 			run_iwpriv(dut, ifname, "set11NRates 0");
11330 		if (dut->device_type == AP_testbed &&
11331 		    dut->program == PROGRAM_HE)
11332 			run_iwpriv(dut, ifname, "he_mcs 7");
11333 	} else {
11334 		mcs = atoi(result);
11335 		if (dut->program == PROGRAM_HE)
11336 			run_iwpriv(dut, ifname, "he_mcs %d", mcs);
11337 		else
11338 			run_iwpriv(dut, ifname, "vhtmcs %d", mcs);
11339 	}
11340 
11341 end:
11342 	free(token);
11343 	return 0;
11344 }
11345 
11346 
11347 static int ath_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
11348 			      const char *val)
11349 {
11350 	char *token, *result;
11351 	int channel = 36;
11352 	int chwidth = 80;
11353 	char *saveptr;
11354 
11355 	/* Extract the channel info */
11356 	token = strdup(val);
11357 	if (!token)
11358 		return -1;
11359 	result = strtok_r(token, ";", &saveptr);
11360 	if (result)
11361 		channel = atoi(result);
11362 
11363 	/* Extract the channel width info */
11364 	result = strtok_r(NULL, ";", &saveptr);
11365 	if (result)
11366 		chwidth = atoi(result);
11367 
11368 	/* Issue the channel switch command */
11369 	run_iwpriv(dut, ifname, "doth_ch_chwidth %d 10 %d", channel, chwidth);
11370 
11371 	free(token);
11372 	return 0;
11373 }
11374 
11375 
11376 static int ath_ndpa_stainfo_mac(struct sigma_dut *dut, const char *ifname,
11377 				const char *val)
11378 {
11379 	char buf[80];
11380 	unsigned char mac_addr[6];
11381 
11382 	if (parse_mac_address(dut, val, mac_addr) < 0)
11383 		return -1;
11384 
11385 	snprintf(buf, sizeof(buf),
11386 		 "wifitool %s beeliner_fw_test 92 0x%02x%02x%02x%02x",
11387 		 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3]);
11388 	run_system(dut, buf);
11389 
11390 	snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 93 0x%02x%02x",
11391 		 ifname, mac_addr[4], mac_addr[5]);
11392 	run_system(dut, buf);
11393 
11394 	snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 94 1", ifname);
11395 	run_system(dut, buf);
11396 
11397 	return 0;
11398 }
11399 
11400 
11401 void novap_reset(struct sigma_dut *dut, const char *ifname, int reset)
11402 {
11403 	run_iwpriv(dut, ifname, "novap_reset %d", reset);
11404 }
11405 
11406 
11407 static struct mbo_pref_ap * mbo_find_nebor_ap_entry(struct sigma_dut *dut,
11408 						    const uint8_t *mac_addr)
11409 {
11410 	int i;
11411 
11412 	for (i = 0; i < dut->mbo_pref_ap_cnt; i++) {
11413 		if (memcmp(mac_addr, dut->mbo_pref_aps[i].mac_addr,
11414 			   ETH_ALEN) == 0)
11415 			return &dut->mbo_pref_aps[i];
11416 	}
11417 	return NULL;
11418 }
11419 
11420 
11421 static void mbo_add_nebor_entry(struct sigma_dut *dut, const uint8_t *mac_addr,
11422 				int ap_ne_class, int ap_ne_op_ch,
11423 				int ap_ne_pref)
11424 {
11425 	struct mbo_pref_ap *entry;
11426 	uint8_t self_mac[ETH_ALEN];
11427 	char ifname[50];
11428 
11429 	get_if_name(dut, ifname, sizeof(ifname), 1);
11430 	get_hwaddr(ifname, self_mac);
11431 
11432 	if (memcmp(mac_addr, self_mac, ETH_ALEN) == 0)
11433 		entry = &dut->mbo_self_ap_tuple;
11434 	else
11435 		entry = mbo_find_nebor_ap_entry(dut, mac_addr);
11436 
11437 	if (!entry) {
11438 		if (dut->mbo_pref_ap_cnt >= MBO_MAX_PREF_BSSIDS) {
11439 			sigma_dut_print(dut, DUT_MSG_ERROR,
11440 					"Nebor AP List is full. Not adding");
11441 			return;
11442 		}
11443 		entry = &dut->mbo_pref_aps[dut->mbo_pref_ap_cnt];
11444 		dut->mbo_pref_ap_cnt++;
11445 		memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
11446 		entry->ap_ne_class = -1;
11447 		entry->ap_ne_op_ch = -1;
11448 		entry->ap_ne_pref = -1;
11449 	}
11450 	if (ap_ne_class != -1)
11451 		entry->ap_ne_class = ap_ne_class;
11452 	if (ap_ne_op_ch != -1)
11453 		entry->ap_ne_op_ch = ap_ne_op_ch;
11454 	if (ap_ne_pref != -1)
11455 		entry->ap_ne_pref = ap_ne_pref;
11456 }
11457 
11458 
11459 static int ath_set_nebor_bssid(struct sigma_dut *dut, const char *ifname,
11460 			       struct sigma_cmd *cmd)
11461 {
11462 	unsigned char mac_addr[ETH_ALEN];
11463 	const char *val;
11464 	/*
11465 	 * -1 is invalid value for the following
11466 	 *  to differentiate between unset and set values
11467 	 *  -1 => implies not set by CAPI
11468 	 */
11469 	int ap_ne_class = -1, ap_ne_op_ch = -1, ap_ne_pref = -1;
11470 	int list_offset = dut->mbo_pref_ap_cnt;
11471 
11472 	if (list_offset >= MBO_MAX_PREF_BSSIDS) {
11473 		sigma_dut_print(dut, DUT_MSG_ERROR,
11474 				"AP Pref Entry list is full");
11475 		return -1;
11476 	}
11477 
11478 	val = get_param(cmd, "Nebor_Op_Class");
11479 	if (val)
11480 		ap_ne_class = atoi(val);
11481 
11482 	val = get_param(cmd, "Nebor_Op_Ch");
11483 	if (val)
11484 		ap_ne_op_ch = atoi(val);
11485 
11486 	val = get_param(cmd, "Nebor_Pref");
11487 	if (val)
11488 		ap_ne_pref = atoi(val);
11489 
11490 	val = get_param(cmd, "Nebor_BSSID");
11491 	if (!val || parse_mac_address(dut, val, mac_addr) < 0)
11492 		return -1;
11493 
11494 	mbo_add_nebor_entry(dut, mac_addr, ap_ne_class, ap_ne_op_ch,
11495 			    ap_ne_pref);
11496 	apply_mbo_pref_ap_list(dut);
11497 	return 0;
11498 }
11499 
11500 
11501 static enum sigma_cmd_result he_ltf(struct sigma_dut *dut,
11502 				    struct sigma_conn *conn,
11503 				    const char *ifname, const char *val)
11504 {
11505 	const char *var;
11506 
11507 	if (dut->ap_he_ulofdma == VALUE_ENABLED)
11508 		var = "he_ul_ltf";
11509 	else
11510 		var = "he_ltf";
11511 
11512 	if (strcmp(val, "6.4") == 0) {
11513 		run_iwpriv(dut, ifname, "%s 2", var);
11514 	} else if (strcmp(val, "12.8") == 0) {
11515 		run_iwpriv(dut, ifname, "%s 3", var);
11516 	} else if (strcmp(val, "3.2") == 0) {
11517 		run_iwpriv(dut, ifname, "%s 1", var);
11518 	} else {
11519 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported LTF");
11520 		return STATUS_SENT_ERROR;
11521 	}
11522 
11523 	return SUCCESS_SEND_STATUS;
11524 }
11525 
11526 
11527 static enum sigma_cmd_result he_shortgi(struct sigma_dut *dut,
11528 					struct sigma_conn *conn,
11529 					const char *ifname,
11530 					const char *val)
11531 {
11532 	const char *var;
11533 
11534 	if (dut->ap_he_ulofdma == VALUE_ENABLED)
11535 		var = "he_ul_shortgi";
11536 	else
11537 		var = "shortgi";
11538 
11539 	if (strcmp(val, "0.8") == 0) {
11540 		run_iwpriv(dut, ifname, "%s 0", var);
11541 	} else if (strcmp(val, "1.6") == 0) {
11542 		run_iwpriv(dut, ifname, "%s 2", var);
11543 	} else if (strcmp(val, "3.2") == 0) {
11544 		run_iwpriv(dut, ifname, "%s 3", var);
11545 	} else {
11546 		send_resp(dut, conn, SIGMA_ERROR,
11547 			  "errorCode,Unsupported shortGI");
11548 		return STATUS_SENT_ERROR;
11549 	}
11550 
11551 	return SUCCESS_SEND_STATUS;
11552 }
11553 
11554 
11555 static enum sigma_cmd_result he_ar_gi_ltf_mask(struct sigma_dut *dut,
11556 					       struct sigma_conn *conn,
11557 					       const char *ifname,
11558 					       const char *val)
11559 {
11560 
11561 	uint32_t he_ar_gi_ltf;
11562 	uint16_t he_ar_gi, he_ar_ltf;
11563 
11564 	if (strcmp(val, "0.4") == 0) {
11565 		he_ar_gi = 0x01;
11566 	} else if (strcmp(val, "0.8") == 0) {
11567 		he_ar_gi = 0x02;
11568 	} else if (strcmp(val, "1.6") == 0) {
11569 		he_ar_gi = 0x04;
11570 	} else if (strcmp(val, "3.2") == 0) {
11571 		he_ar_gi = 0x08;
11572 	} else {
11573 		send_resp(dut, conn, SIGMA_ERROR,
11574 			  "errorCode,Unsupported shortGI");
11575 		return STATUS_SENT_ERROR;
11576 	}
11577 
11578 	if (dut->ar_ltf && strcmp(dut->ar_ltf, "6.4") == 0) {
11579 		he_ar_ltf = 0x02;
11580 	} else if (dut->ar_ltf && strcmp(dut->ar_ltf, "12.8") == 0) {
11581 		he_ar_ltf = 0x04;
11582 	} else if (dut->ar_ltf && strcmp(dut->ar_ltf, "3.2") == 0) {
11583 		he_ar_ltf = 0x01;
11584 	} else {
11585 		send_resp(dut, conn, SIGMA_ERROR,
11586 			  "errorCode,Unsupported LTF");
11587 		return STATUS_SENT_ERROR;
11588 	}
11589 
11590 	he_ar_gi_ltf = (he_ar_gi << 8) | he_ar_ltf;
11591 	run_iwpriv(dut, ifname, "he_ar_gi_ltf %lu", he_ar_gi_ltf);
11592 
11593 	return SUCCESS_SEND_STATUS;
11594 }
11595 
11596 
11597 static enum sigma_cmd_result he_rualloctones(struct sigma_dut *dut,
11598 					     struct sigma_conn *conn,
11599 					     const char *ifname,
11600 					     const char *val)
11601 {
11602 	char *token, *result;
11603 	int value;
11604 	char *saveptr;
11605 	int rualloc_type;
11606 	enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
11607 
11608 	token = strdup(val);
11609 	if (!token)
11610 		return -1;
11611 	result = strtok_r(token, ":", &saveptr);
11612 	if (!result) {
11613 		free(token);
11614 		send_resp(dut, conn, SIGMA_ERROR,
11615 			  "errorCode,RUAllocTones not specified");
11616 		return STATUS_SENT_ERROR;
11617 	}
11618 
11619 	/*
11620 	* ru_allocation_type can take the values of:
11621 	* 1 - DL OFDMA data RU allocation
11622 	* 3 - UL OFDMA data RU allocation
11623 	*/
11624 	rualloc_type = dut->ap_he_ulofdma == VALUE_ENABLED ? 3 : 1;
11625 
11626 
11627 	value = atoi(result);
11628 	if (value == 106) {
11629 		enum value_not_set_enabled_disabled ap_he_rualloc_106_80 =
11630 			VALUE_NOT_SET;
11631 
11632 		result = strtok_r(NULL, ":", &saveptr);
11633 		if (result) {
11634 			result = strtok_r(NULL, ":", &saveptr);
11635 			if (result)
11636 				ap_he_rualloc_106_80 = VALUE_ENABLED;
11637 			else
11638 				ap_he_rualloc_106_80 = VALUE_DISABLED;
11639 		}
11640 		if (ap_he_rualloc_106_80 == VALUE_ENABLED) {
11641 			run_system_wrapper(dut,
11642 					   "wifitool %s setUnitTestCmd 0x4b 9 %d 0 2 1 2 2 2 3 2",
11643 					   ifname, rualloc_type);
11644 		} else {
11645 			run_system_wrapper(dut,
11646 					   "wifitool %s setUnitTestCmd 0x4b 5 %d 0 2 1 2",
11647 					   ifname, rualloc_type);
11648 		}
11649 	} else if (value == 242) {
11650 		run_system_wrapper(
11651 			dut,
11652 			"wifitool %s setUnitTestCmd 0x4b 9 %d 0 3 1 3 2 3 3 3",
11653 			ifname, rualloc_type);
11654 	} else if (value == 26) {
11655 		run_system_wrapper(
11656 			dut,
11657 			"wifitool %s setUnitTestCmd 0x4b 9 %d 0 0 2 0 5 0 7 0",
11658 			ifname, rualloc_type);
11659 	} else if (value == 52) {
11660 		run_system_wrapper(
11661 			dut,
11662 			"wifitool %s setUnitTestCmd 0x4b 9 %d 0 1 1 1 2 1 3 1",
11663 			ifname, rualloc_type);
11664 	} else if (value == 484) {
11665 		run_system_wrapper(
11666 			dut,
11667 			"wifitool %s setUnitTestCmd 0x4b 5 %d 0 4 1 4",
11668 			ifname, rualloc_type);
11669 	} else if (value == 996) {
11670 		run_system_wrapper(dut,
11671 				   "wifitool %s setUnitTestCmd 0x4b 3 %d 0 5",
11672 				   ifname, rualloc_type);
11673 	} else {
11674 		send_resp(dut, conn, SIGMA_ERROR,
11675 			  "errorCode,Unsupported RUAllocTones");
11676 		ret = STATUS_SENT_ERROR;
11677 	}
11678 
11679 	free(token);
11680 	return ret;
11681 }
11682 
11683 
11684 static void ath_set_trigger_type_0(struct sigma_dut *dut, const char *ifname)
11685 {
11686 	/* TriggerType "0" for Basic trigger */
11687 	if (dut->ap_channel >= 36) {
11688 		/* 1 and 2 here is interpreted to 5g and 2g (bitmasks) */
11689 		run_system_wrapper(dut,
11690 				   "wifitool %s setUnitTestCmd 0x47 2 42 1",
11691 				   ifname);
11692 	} else {
11693 		run_system_wrapper(dut,
11694 				   "wifitool %s setUnitTestCmd 0x47 2 42 2",
11695 				   ifname);
11696 	}
11697 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 6",
11698 			   ifname);
11699 }
11700 
11701 
11702 static void ath_set_trigger_type_1(struct sigma_dut *dut, const char *ifname)
11703 {
11704 	/* TriggerType "1" for MU BRP */
11705 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 1",
11706 			   ifname);
11707 	mubrp_commands(dut, ifname);
11708 }
11709 
11710 
11711 static void ath_set_trigger_type_2(struct sigma_dut *dut, const char *ifname)
11712 {
11713 	/* TriggerType "2" for MU BAR */
11714 	if (dut->ap_channel >= 36) {
11715 		/* RU allocation RU 242 - DL OFDMA data */
11716 		run_system_wrapper(dut,
11717 				   "wifitool %s setUnitTestCmd 0x4b 5 9 0 3 1 3 2 3 3 3",
11718 				   ifname);
11719 		/* RU allocation RU 52 - UL BA */
11720 		run_system_wrapper(dut,
11721 				   "wifitool %s setUnitTestCmd 0x4b 5 9 0 2 1 2 2 2 3 2",
11722 				   ifname);
11723 	} else {
11724 		/* RU allocation RU 52 - DL ofdma data */
11725 		run_system_wrapper(dut,
11726 				   "wifitool %s setUnitTestCmd 0x4b 5 9 0 1 1 1 2 1 3 1",
11727 				   ifname);
11728 	}
11729 	/* Force TBPPDU duration to 400 us */
11730 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 400",
11731 			   ifname);
11732 	/* 0 to enable MU BAR, 1 to enable SU BAR */
11733 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 49 0",
11734 			   ifname);
11735 	/* MU BAR */
11736 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 64 0",
11737 			   ifname);
11738 }
11739 
11740 
11741 static void ath_set_trigger_type_3(struct sigma_dut *dut, const char *ifname)
11742 {
11743 	/* TriggerType "3" for MU RTS */
11744 	/* Send MU RTS Trigger - '1' is to enable MU RTS */
11745 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 101 1",
11746 			   ifname);
11747 }
11748 
11749 
11750 static void ath_set_trigger_type_4(struct sigma_dut *dut, const char *ifname,
11751 				   const char *basedev)
11752 {
11753 	/* TriggerType "4" for BSRP */
11754 	run_system_wrapper(dut, "cfg80211tool %s he_ul_trig_int 200", basedev);
11755 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 1000",
11756 			   ifname);
11757 	if (dut->ap_channel >= 36) {
11758 		run_system_wrapper(dut,
11759 				   "wifitool %s setUnitTestCmd 0x47 2 42 1",
11760 				   ifname);
11761 	} else {
11762 		run_system_wrapper(dut,
11763 				   "wifitool %s setUnitTestCmd 0x47 2 42 2",
11764 				   ifname);
11765 	}
11766 	/* Send BSRP command */
11767 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 7",
11768 			   ifname);
11769 }
11770 
11771 
11772 static enum sigma_cmd_result ath_ap_set_rfeature(struct sigma_dut *dut,
11773 						 struct sigma_conn *conn,
11774 						 struct sigma_cmd *cmd)
11775 {
11776 	const char *val;
11777 	const char *ifname;
11778 	enum sigma_cmd_result res;
11779 	const char *basedev = "wifi0";
11780 	int trigtype;
11781 	int he_ackpolicymac = 0;
11782 	char *num_ss = NULL;
11783 	char *nss[4] = { NULL, NULL, NULL, NULL };
11784 	char *aid[4] = { NULL, NULL, NULL, NULL };
11785 	char *aid_ss = NULL;
11786 	int omctrl_rxnss = 0, omctrl_chwidth = 0;
11787 	int param;
11788 	unsigned char mac_addr[ETH_ALEN];
11789 
11790 	memset(mac_addr, 0x00, ETH_ALEN);
11791 
11792 	ifname = get_main_ifname(dut);
11793 
11794 	if (sigma_radio_ifname[0])
11795 		basedev = sigma_radio_ifname[0];
11796 
11797 	/* Disable vap reset between the commands */
11798 	novap_reset(dut, ifname, 1);
11799 
11800 	val = get_param(cmd, "Opt_md_notif_ie");
11801 	if (val && ath_vht_op_mode_notif(dut, ifname, val) < 0)
11802 		return ERROR_SEND_STATUS;
11803 
11804 	/* TODO: Optional arguments */
11805 
11806 	val = get_param(cmd, "nss_mcs_opt");
11807 	if (val && ath_vht_nss_mcs(dut, ifname, val) < 0)
11808 		return ERROR_SEND_STATUS;
11809 
11810 	val = get_param(cmd, "chnum_band");
11811 	if (val && ath_vht_chnum_band(dut, ifname, val) < 0)
11812 		return ERROR_SEND_STATUS;
11813 
11814 	val = get_param(cmd, "RTS_FORCE");
11815 	if (val)
11816 		ath_config_rts_force(dut, ifname, val);
11817 
11818 	val = get_param(cmd, "DYN_BW_SGNL");
11819 	if (val)
11820 		ath_config_dyn_bw_sig(dut, ifname, val);
11821 
11822 	val = get_param(cmd, "CTS_WIDTH");
11823 	if (val)
11824 		ath_set_cts_width(dut, ifname, val);
11825 
11826 	val = get_param(cmd, "Ndpa_stainfo_mac");
11827 	if (val && ath_ndpa_stainfo_mac(dut, ifname, val) < 0)
11828 		return ERROR_SEND_STATUS;
11829 
11830 	val = get_param(cmd, "txBandwidth");
11831 	if (val && ath_set_width(dut, conn, ifname, val) < 0)
11832 		return ERROR_SEND_STATUS;
11833 
11834 	val = get_param(cmd, "Assoc_Disallow");
11835 	if (val)
11836 		ath_set_assoc_disallow(dut, ifname, val);
11837 
11838 
11839 	ath_set_nebor_bssid(dut, ifname, cmd);
11840 	val = get_param(cmd, "BTMReq_DisAssoc_Imnt");
11841 	if (val) {
11842 		dut->ap_btmreq_disassoc_imnt = atoi(val);
11843 		dut->ap_disassoc_timer = 1000;
11844 	}
11845 
11846 	val = get_param(cmd, "BTMReq_Term_Bit");
11847 	if (val)
11848 		dut->ap_btmreq_term_bit = atoi(val);
11849 
11850 	val = get_param(cmd, "Assoc_Delay");
11851 	if (val) {
11852 		dut->ap_assoc_delay = 1;
11853 		run_iwpriv(dut, ifname, "mbo_asoc_ret %s", val);
11854 	}
11855 
11856 	val = get_param(cmd, "Disassoc_Timer");
11857 	if (val)
11858 		dut->ap_disassoc_timer = atoi(val);
11859 
11860 	val = get_param(cmd, "BSS_Term_Duration");
11861 	if (val)
11862 		dut->ap_btmreq_bss_term_dur = atoi(val);
11863 
11864 	val = get_param(cmd, "BSS_Term_TSF");
11865 	if (val)
11866 		dut->ap_btmreq_bss_term_tsf = atoi(val);
11867 
11868 	val = get_param(cmd, "TxPower");
11869 	if (val)
11870 		ath_set_txpower(dut, ifname, val);
11871 
11872 	val = get_param(cmd, "DownlinkAvailCap");
11873 	if (val)
11874 		dut->ap_dl_availcap = atoi(val);
11875 
11876 	val = get_param(cmd, "UplinkAvailCap");
11877 	if (val) {
11878 		dut->ap_ul_availcap = atoi(val);
11879 		run_iwpriv(dut, ifname, "oce_wan_mtr %d %d",
11880 			   dut->ap_dl_availcap, dut->ap_ul_availcap);
11881 	}
11882 
11883 	val = get_param(cmd, "RSSIthreshold");
11884 	if (val) {
11885 		int rssithreshold;
11886 
11887 		run_iwpriv(dut, ifname, "oce_asoc_rej 1");
11888 		rssithreshold = atoi(val);
11889 		run_iwpriv(dut, ifname, "oce_asoc_rssi %d", rssithreshold);
11890 	}
11891 
11892 	val = get_param(cmd, "RetryDelay");
11893 	if (val) {
11894 		int retrydelay;
11895 
11896 		run_iwpriv(dut, ifname, "oce_asoc_rej 1");
11897 		retrydelay = atoi(val);
11898 		run_iwpriv(dut, ifname, "oce_asoc_dly %d", retrydelay);
11899 	}
11900 
11901 	val = get_param(cmd, "LTF");
11902 	if (val) {
11903 		if (dut->ap_fixed_rate) {
11904 			res = he_ltf(dut, conn, ifname, val);
11905 			if (res != SUCCESS_SEND_STATUS)
11906 				return res;
11907 		} else {
11908 			free(dut->ar_ltf);
11909 			dut->ar_ltf = strdup(val);
11910 			if (!dut->ar_ltf)
11911 				return ERROR_SEND_STATUS;
11912 		}
11913 	}
11914 
11915 	val = get_param(cmd, "GI");
11916 	if (val) {
11917 		if (dut->ap_fixed_rate)
11918 			res = he_shortgi(dut, conn, ifname, val);
11919 		else
11920 			res = he_ar_gi_ltf_mask(dut, conn, ifname, val);
11921 		if (res != SUCCESS_SEND_STATUS)
11922 			return res;
11923 	}
11924 
11925 	val = get_param(cmd, "RUAllocTones");
11926 	if (val) {
11927 		res = he_rualloctones(dut, conn, ifname, val);
11928 		if (res != SUCCESS_SEND_STATUS)
11929 			return res;
11930 	}
11931 
11932 	val = get_param(cmd, "MPDU_MU_SpacingFactor");
11933 	if (val)
11934 		run_system_wrapper(dut,
11935 				   "wifitool %s setUnitTestCmd 0x48 2 119, %s",
11936 				   ifname, val);
11937 
11938 	val = get_param(cmd, "PPDUTxType");
11939 	if (val) {
11940 		if (strcasecmp(val, "HE-SU") == 0) {
11941 			/* Change PPDU format type to HE-SU MCS 1 */
11942 			run_system_wrapper(dut,
11943 					   "wifitool %s setUnitTestCmd 0x48 2 89 0x401",
11944 					   ifname);
11945 		} else if (strcasecmp(val, "legacy") == 0) {
11946 			/* Change PPDU format type to non-HT */
11947 			run_system_wrapper(dut,
11948 					   "wifitool %s setUnitTestCmd 0x48 2 89 3",
11949 					   ifname);
11950 		} else {
11951 			send_resp(dut, conn, SIGMA_ERROR,
11952 				  "errorCode,Unsupported PPDUTxType");
11953 			return STATUS_SENT_ERROR;
11954 		}
11955 	}
11956 
11957 	val = get_param(cmd, "TXOPDuration");
11958 	if (val) {
11959 		if (strcasecmp(val, "UNSPECIFIED") == 0) {
11960 			/* The hardware is hardcoded with 0x7f; do nothing */
11961 		} else {
11962 			send_resp(dut, conn, SIGMA_ERROR,
11963 				  "errorCode,Unsupported TXOPDuration");
11964 			return STATUS_SENT_ERROR;
11965 		}
11966 	}
11967 
11968 	val = get_param(cmd, "Trig_Usrinfo_UL-MCS");
11969 	if (val)
11970 		run_iwpriv(dut, ifname, "he_ul_mcs %d", atoi(val));
11971 
11972 	val = get_param(cmd, "Trig_Usrinfo_UL-Target-RSSI");
11973 	if (val) {
11974 		/* Set target RSSI to -55 dBm */
11975 		run_system_wrapper(dut,
11976 				   "wifitool %s setUnitTestCmd 0x4b 2 7 %d",
11977 				   ifname, atoi(val) - 110);
11978 	}
11979 
11980 	val = get_param(cmd, "Trig_Interval");
11981 	if (val)
11982 		run_iwpriv(dut, basedev, "he_ul_trig_int %d", atoi(val));
11983 
11984 	val = get_param(cmd, "Trig_ComInfo_ULLength");
11985 	if (val)
11986 		run_system_wrapper(dut,
11987 				   "wifitool %s setUnitTestCmd 0x48 2 141 %d",
11988 				   ifname, atoi(val));
11989 
11990 	val = get_param(cmd, "DisableTriggerType");
11991 	if (val) {
11992 		trigtype = atoi(val);
11993 		switch (trigtype) {
11994 		case 0:
11995 			/* DisableTriggerType "0" for basic trigger */
11996 			run_system_wrapper(dut,
11997 					   "wifitool %s setUnitTestCmd 0x47 2 42 0",
11998 					   ifname);
11999 			break;
12000 		default:
12001 			/* Nothing to be done for now */
12002 			break;
12003 		}
12004 	}
12005 
12006 	val = get_param(cmd, "Trigger_TxBF");
12007 	if (val) {
12008 		if (strcasecmp(val, "enable") == 0) {
12009 			run_iwpriv(dut, ifname, "he_sounding_mode 0x9");
12010 		} else if (strcasecmp(val, "disable") == 0) {
12011 			run_iwpriv(dut, ifname, "he_sounding_mode 0x1");
12012 		} else {
12013 			send_resp(dut, conn, SIGMA_ERROR,
12014 				  "errorCode,Unsupported trigger_txbf");
12015 			return STATUS_SENT_ERROR;
12016 		}
12017 	}
12018 
12019 	val = get_param(cmd, "Trig_UsrInfo_RUAlloc");
12020 	if (val) {
12021 		res = he_rualloctones(dut, conn, ifname, val);
12022 		if (res != SUCCESS_SEND_STATUS)
12023 			return res;
12024 	}
12025 
12026 	val = get_param(cmd, "TriggerCoding");
12027 	if (val) {
12028 		if (strcasecmp(val, "BCC") == 0) {
12029 			/* In case of LDPC enable this command can force BCC if
12030 			 * RU size <= 242 */
12031 			run_iwpriv(dut, ifname, "he_ul_ldpc 0");
12032 		} else if (strcasecmp(val, "LDPC") == 0) {
12033 			novap_reset(dut, ifname, 0);
12034 			run_iwpriv(dut, ifname, "he_ul_ldpc 1");
12035 			novap_reset(dut, ifname, 1);
12036 		} else {
12037 			send_resp(dut, conn, SIGMA_ERROR,
12038 				  "errorCode,Unsupported TriggerCoding");
12039 			return STATUS_SENT_ERROR;
12040 		}
12041 	}
12042 
12043 	val = get_param(cmd, "AckPolicy_MAC");
12044 	if (val) {
12045 		if (parse_mac_address(dut, val, mac_addr) < 0) {
12046 			send_resp(dut, conn, SIGMA_ERROR,
12047 				  "errorCode,MAC Address not in proper format");
12048 			return STATUS_SENT_ERROR;
12049 		}
12050 		he_ackpolicymac = 1;
12051 	}
12052 
12053 	val = get_param(cmd, "AckPolicy");
12054 	if (val) {
12055 		int ap_he_ackpolicy;
12056 
12057 		ap_he_ackpolicy = atoi(val);
12058 		if (ap_he_ackpolicy == 0 && he_ackpolicymac) {
12059 			/* Disable all-BAR ackpolicy for MU-MIMO */
12060 			run_system_wrapper(dut,
12061 					   "wifitool %s setUnitTestCmd 0x48 2 62 0",
12062 					   ifname);
12063 			/* Disable all-BAR ackpolicy first */
12064 			run_system_wrapper(dut,
12065 					   "wifitool %s setUnitTestCmd 0x48 2 64 0",
12066 					   ifname);
12067 			/* Set normal ack policy for the STA with the specified
12068 			 * MAC address in DL-TX case */
12069 			run_system_wrapper(dut,
12070 					   "wifitool %s setUnitTestCmd 0x4b 8 8 1 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
12071 					   ifname, mac_addr[0], mac_addr[1],
12072 					   mac_addr[2], mac_addr[3],
12073 					   mac_addr[4], mac_addr[5]);
12074 		} else if (ap_he_ackpolicy == 3) {
12075 			/* Enable all-BAR ackpolicy for MU-MIMO DL */
12076 			run_system_wrapper(dut,
12077 					   "wifitool %s setUnitTestCmd 0x48 2 62 1",
12078 					   ifname);
12079 			/* Enable all-BAR ackpolicy */
12080 			run_system_wrapper(dut,
12081 					   "wifitool %s setUnitTestCmd 0x48 2 64 1",
12082 					   ifname);
12083 		} else if (ap_he_ackpolicy == 4) {
12084 			/* Enable htp-ack ackpolicy */
12085 			run_system_wrapper(dut,
12086 					   "wifitool %s setUnitTestCmd 0x47 2 99 1",
12087 					   ifname);
12088 		} else {
12089 			send_resp(dut, conn, SIGMA_ERROR,
12090 				  "errorCode,Invalid AckPolicy setting");
12091 			return STATUS_SENT_ERROR;
12092 		}
12093 	}
12094 
12095 	val = get_param(cmd, "Trig_ComInfo_GI-LTF");
12096 	if (val) {
12097 		int trig_gi_ltf;
12098 
12099 		trig_gi_ltf = atoi(val);
12100 		if (trig_gi_ltf == 0) {
12101 			he_ltf(dut, conn, ifname, "3.2");
12102 			he_shortgi(dut, conn, ifname, "1.6");
12103 		} else if (trig_gi_ltf == 1) {
12104 			he_ltf(dut, conn, ifname, "6.4");
12105 			he_shortgi(dut, conn, ifname, "1.6");
12106 		} else if (trig_gi_ltf == 2) {
12107 			he_ltf(dut, conn, ifname, "12.8");
12108 			he_shortgi(dut, conn, ifname, "3.2");
12109 		} else {
12110 			send_resp(dut, conn, SIGMA_ERROR,
12111 				  "errorCode,Unsupported Trig_ComInfo_GI-LTF");
12112 			return STATUS_SENT_ERROR;
12113 		}
12114 	}
12115 
12116 	val = get_param(cmd, "Trig_ComInfo_BW");
12117 	if (val) {
12118 		int chwidth;
12119 
12120 		chwidth = atoi(val);
12121 		/* Set the channel width */
12122 		run_iwpriv(dut, ifname, "chwidth %d", chwidth);
12123 	}
12124 
12125 	val = get_param(cmd, "NumSS");
12126 	if (val) {
12127 		int i = 0;
12128 		char *numss_val;
12129 		char *saveptr;
12130 
12131 		num_ss = strdup(val);
12132 		if (!num_ss)
12133 			return ERROR_SEND_STATUS;
12134 
12135 		numss_val = strtok_r(num_ss, " ", &saveptr);
12136 		for (i = 0; numss_val && i < 4; i++) {
12137 			nss[i] = numss_val;
12138 			numss_val = strtok_r(NULL, " ", &saveptr);
12139 		}
12140 	}
12141 
12142 	val = get_param(cmd, "NumSS_MAC");
12143 	if (val) {
12144 		char *sta_mac_str;
12145 		char *saveptr;
12146 		char *sta_mac_list_str;
12147 
12148 		sta_mac_list_str = strdup(val);
12149 		if (!sta_mac_list_str) {
12150 			free(num_ss);
12151 			return ERROR_SEND_STATUS;
12152 		}
12153 
12154 		sta_mac_str = strtok_r(sta_mac_list_str, " ", &saveptr);
12155 		if (sta_mac_str && nss[0]) {
12156 			run_system_wrapper(dut,
12157 					   "wifitool %s chmask_persta %s %s",
12158 					   ifname, sta_mac_str, nss[0]);
12159 		}
12160 
12161 		sta_mac_str = strtok_r(NULL, " ", &saveptr);
12162 		if (sta_mac_str && nss[1]) {
12163 			run_system_wrapper(dut,
12164 					   "wifitool %s chmask_persta %s %s",
12165 					   ifname, sta_mac_str, nss[1]);
12166 		}
12167 
12168 		sta_mac_str = strtok_r(NULL, " ", &saveptr);
12169 		if (sta_mac_str && nss[2]) {
12170 			run_system_wrapper(dut,
12171 					   "wifitool %s chmask_persta %s %s",
12172 					   ifname, sta_mac_str, nss[2]);
12173 		}
12174 
12175 		sta_mac_str = strtok_r(NULL, " ", &saveptr);
12176 		if (sta_mac_str && nss[3]) {
12177 			run_system_wrapper(dut,
12178 					   "wifitool %s chmask_persta %s %s",
12179 					   ifname, sta_mac_str, nss[3]);
12180 		}
12181 
12182 		free(sta_mac_list_str);
12183 	}
12184 
12185 	free(num_ss);
12186 	num_ss = NULL;
12187 
12188 	val = get_param(cmd, "AID");
12189 	if (val) {
12190 		int i = 0;
12191 		char *aid_val;
12192 		char *saveptr;
12193 
12194 		aid_ss = strdup(val);
12195 		if (!aid_ss)
12196 			return ERROR_SEND_STATUS;
12197 
12198 		aid_val = strtok_r(aid_ss, " ", &saveptr);
12199 		for (i = 0; aid_val && i < 4; i++) {
12200 			aid[i] = aid_val;
12201 			aid_val = strtok_r(NULL, " ", &saveptr);
12202 		}
12203 	}
12204 
12205 	val = get_param(cmd, "AddbaReq");
12206 	if (val) {
12207 		if (strcasecmp(val, "enable") == 0) {
12208 			run_iwpriv(dut, ifname, "setaddbaoper 1");
12209 			run_system_wrapper(dut,
12210 					   "wifitool %s sendaddba %s 0 64",
12211 					   ifname, aid[0]);
12212 		} else {
12213 			send_resp(dut, conn, SIGMA_ERROR,
12214 				  "errorCode,Unsupported AddbaReq value");
12215 			free(aid_ss);
12216 			return STATUS_SENT_ERROR;
12217 		}
12218 	}
12219 
12220 	val = get_param(cmd, "AddbaResp");
12221 	if (val) {
12222 		if (aid_ss && strcasecmp(val, "accepted") == 0) {
12223 			int aid_1 = atoi(aid_ss);
12224 
12225 			if (aid_1 == 1)
12226 				aid_1 = 2;
12227 			else
12228 				aid_1 = aid_1 - 1;
12229 
12230 			/* There is no mechanism in place to reject Add BA Req
12231 			 * from all STAs and selectively accept Add BA Req from
12232 			 * a specified STA. Instead, it can accept Add BA Req
12233 			 * from all STAs and selectively reject from specified
12234 			 * STAs. Make changes for the same using the below
12235 			 * commands. */
12236 			run_system_wrapper(dut, ifname, "setaddbaoper 1");
12237 			run_system_wrapper(dut, "wifitool %s refusealladdbas 0",
12238 					   ifname);
12239 			run_system_wrapper(dut,
12240 					   "wifitool %s setaddbaresp %d 0 37",
12241 					   ifname, aid_1);
12242 		} else {
12243 			send_resp(dut, conn, SIGMA_ERROR,
12244 				  "errorCode,Unsupported Addbaresp value");
12245 			free(aid_ss);
12246 			return STATUS_SENT_ERROR;
12247 		}
12248 	}
12249 
12250 	val = get_param(cmd, "Trig_UsrInfo_SSAlloc_RA-RU");
12251 	if (val) {
12252 		char *ssalloc_str;
12253 		char *saveptr;
12254 		char *ssalloc_list_str;
12255 
12256 		ssalloc_list_str = strdup(val);
12257 		if (!ssalloc_list_str) {
12258 			free(aid_ss);
12259 			return ERROR_SEND_STATUS;
12260 		}
12261 
12262 		ssalloc_str = strtok_r(ssalloc_list_str, ":", &saveptr);
12263 		if (ssalloc_str && aid[0]) {
12264 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12265 					   ifname, aid[0], ssalloc_str);
12266 		}
12267 
12268 		ssalloc_str = strtok_r(NULL, " ", &saveptr);
12269 		if (ssalloc_str && aid[1]) {
12270 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12271 					   ifname, aid[1], ssalloc_str);
12272 		}
12273 
12274 		ssalloc_str = strtok_r(NULL, " ", &saveptr);
12275 		if (ssalloc_str && aid[2]) {
12276 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12277 					   ifname, aid[2], ssalloc_str);
12278 		}
12279 
12280 		ssalloc_str = strtok_r(NULL, " ", &saveptr);
12281 		if (ssalloc_str && aid[3]) {
12282 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12283 					   ifname, aid[3], ssalloc_str);
12284 		}
12285 
12286 		free(ssalloc_list_str);
12287 	}
12288 
12289 	free(aid_ss);
12290 	aid_ss = NULL;
12291 
12292 	val = get_param(cmd, "OMCtrl_RxNSS");
12293 	if (val)
12294 		omctrl_rxnss = atoi(val);
12295 
12296 	val = get_param(cmd, "OMCtrl_ChnlWidth");
12297 	if (val)
12298 		omctrl_chwidth = atoi(val);
12299 
12300 	val = get_param(cmd, "Client_mac");
12301 	if (val) {
12302 		if (parse_mac_address(dut, val, mac_addr) < 0) {
12303 			send_resp(dut, conn, SIGMA_ERROR,
12304 				  "errorCode,MAC Address not in proper format");
12305 			return STATUS_SENT_ERROR;
12306 		}
12307 
12308 		/* setUnitTestCmd 13 7 1 mac3mac2mac1mac0 mac5mac4 <rx_nss>
12309 		 * <bw> <ulmu> <tx_nss> */
12310 		run_system_wrapper(dut,
12311 				   "wifitool %s setUnitTestCmd 13 7 1 0x%02x%02x%02x%02x 0x%02x%02x %d %d 1 %d",
12312 				   ifname, mac_addr[3], mac_addr[2],
12313 				   mac_addr[1], mac_addr[0], mac_addr[5],
12314 				   mac_addr[4], omctrl_rxnss,
12315 				   omctrl_chwidth, omctrl_rxnss);
12316 	}
12317 
12318 	val = get_param(cmd, "TriggerType");
12319 	if (val) {
12320 		trigtype = atoi(val);
12321 		switch (trigtype) {
12322 		case 0:
12323 			ath_set_trigger_type_0(dut, ifname);
12324 			break;
12325 		case 1:
12326 			ath_set_trigger_type_1(dut, ifname);
12327 			break;
12328 		case 2:
12329 			ath_set_trigger_type_2(dut, ifname);
12330 			break;
12331 		case 3:
12332 			ath_set_trigger_type_3(dut, ifname);
12333 			break;
12334 		case 4:
12335 			ath_set_trigger_type_4(dut, ifname, basedev);
12336 			break;
12337 		default:
12338 			send_resp(dut, conn, SIGMA_ERROR,
12339 				  "errorCode,TriggerType not supported");
12340 			return STATUS_SENT_ERROR;
12341 		}
12342 	}
12343 
12344 	val = get_param(cmd, "HE_TXOPDurRTSThr");
12345 	if (val)
12346 		run_iwpriv(dut, ifname, "he_rtsthrshld %d", atoi(val));
12347 
12348 	val = get_param(cmd, "NAV_Update");
12349 	if (val) {
12350 		if (strcasecmp(val, "disable") == 0) {
12351 			run_iwpriv(dut, basedev, "nav_config 1 0");
12352 		} else if (strcasecmp(val, "enable") == 0) {
12353 			/* Do nothing */
12354 		} else {
12355 			send_resp(dut, conn, SIGMA_ERROR,
12356 				  "errorCode,Unsupported NAV update");
12357 			return STATUS_SENT_ERROR;
12358 		}
12359 	}
12360 
12361 	/* Configure WMM Parameter Elements */
12362 	val = get_param(cmd, "STA_WMMPE_ECWmin_BE");
12363 	if (val) {
12364 		param = atoi(val);
12365 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BE, param);
12366 	}
12367 
12368 	val = get_param(cmd, "STA_WMMPE_ECWmin_BK");
12369 	if (val) {
12370 		param = atoi(val);
12371 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BK, param);
12372 	}
12373 
12374 	val = get_param(cmd, "STA_WMMPE_ECWmin_VI");
12375 	if (val) {
12376 		param = atoi(val);
12377 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VI, param);
12378 	}
12379 
12380 	val = get_param(cmd, "STA_WMMPE_ECWmin_VO");
12381 	if (val) {
12382 		param = atoi(val);
12383 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VO, param);
12384 	}
12385 
12386 	val = get_param(cmd, "STA_WMMPE_ECWmax_BE");
12387 	if (val) {
12388 		param = atoi(val);
12389 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BE, param);
12390 	}
12391 
12392 	val = get_param(cmd, "STA_WMMPE_ECWmax_BK");
12393 	if (val) {
12394 		param = atoi(val);
12395 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BK, param);
12396 	}
12397 
12398 	val = get_param(cmd, "STA_WMMPE_ECWmax_VI");
12399 	if (val) {
12400 		param = atoi(val);
12401 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VI, param);
12402 	}
12403 
12404 	val = get_param(cmd, "STA_WMMPE_ECWmax_VO");
12405 	if (val) {
12406 		param = atoi(val);
12407 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VO, param);
12408 	}
12409 
12410 	val = get_param(cmd, "STA_WMMPE_AIFSN_BE");
12411 	if (val) {
12412 		param = atoi(val);
12413 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BE, param);
12414 	}
12415 
12416 	val = get_param(cmd, "STA_WMMPE_AIFSN_BK");
12417 	if (val) {
12418 		param = atoi(val);
12419 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BK, param);
12420 	}
12421 
12422 	val = get_param(cmd, "STA_WMMPE_AIFSN_VI");
12423 	if (val) {
12424 		param = atoi(val);
12425 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VI, param);
12426 	}
12427 
12428 	val = get_param(cmd, "STA_WMMPE_AIFSN_VO");
12429 	if (val) {
12430 		param = atoi(val);
12431 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VO, param);
12432 	}
12433 
12434 
12435 	val = get_param(cmd, "STA_WMMPE_TXOP_BE");
12436 	if (val) {
12437 		param = atoi(val);
12438 		run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BE, param);
12439 	}
12440 
12441 	val = get_param(cmd, "STA_WMMPE_TOXP_BK");
12442 	if (val) {
12443 		param = atoi(val);
12444 		run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BK, param);
12445 	}
12446 
12447 	val = get_param(cmd, "STA_WMMPE_TXOP_VI");
12448 	if (val) {
12449 		param = atoi(val);
12450 		run_iwpriv(dut, ifname, "txoplimit %d %d", AP_AC_VI, param);
12451 	}
12452 
12453 	val = get_param(cmd, "STA_WMMPE_TXOP_VO");
12454 	if (val) {
12455 		param = atoi(val);
12456 		run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_VO, param);
12457 	}
12458 
12459 	/* Configure MU EDCA */
12460 	val = get_param(cmd, "STA_MUEDCA_ECWmin_BE");
12461 	if (val) {
12462 		param = atoi(val);
12463 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BE, param);
12464 	}
12465 
12466 	val = get_param(cmd, "STA_MUEDCA_ECWmin_BK");
12467 	if (val) {
12468 		param = atoi(val);
12469 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BK, param);
12470 	}
12471 
12472 	val = get_param(cmd, "STA_MUEDCA_ECWmin_VI");
12473 	if (val) {
12474 		param = atoi(val);
12475 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VI, param);
12476 	}
12477 
12478 	val = get_param(cmd, "STA_MUEDCA_ECWmin_VO");
12479 	if (val) {
12480 		param = atoi(val);
12481 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VO, param);
12482 	}
12483 
12484 	val = get_param(cmd, "STA_MUEDCA_ECWmax_BE");
12485 	if (val) {
12486 		param = atoi(val);
12487 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BE, param);
12488 	}
12489 
12490 	val = get_param(cmd, "STA_MUEDCA_ECWmax_BK");
12491 	if (val) {
12492 		param = atoi(val);
12493 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BK, param);
12494 	}
12495 
12496 	val = get_param(cmd, "STA_MUEDCA_ECWmax_VI");
12497 	if (val) {
12498 		param = atoi(val);
12499 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VI, param);
12500 	}
12501 
12502 	val = get_param(cmd, "STA_MUEDCA_ECWmax_VO");
12503 	if (val) {
12504 		param = atoi(val);
12505 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VO, param);
12506 	}
12507 
12508 	val = get_param(cmd, "STA_MUEDCA_AIFSN_BE");
12509 	if (val) {
12510 		param = atoi(val);
12511 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BE, param);
12512 	}
12513 
12514 	val = get_param(cmd, "STA_MUEDCA_AIFSN_BK");
12515 	if (val) {
12516 		param = atoi(val);
12517 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BK, param);
12518 	}
12519 
12520 	val = get_param(cmd, "STA_MUEDCA_AIFSN_VI");
12521 	if (val) {
12522 		param = atoi(val);
12523 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VI, param);
12524 	}
12525 
12526 	val = get_param(cmd, "STA_MUEDCA_AIFSN_VO");
12527 	if (val) {
12528 		param = atoi(val);
12529 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VO, param);
12530 	}
12531 
12532 	val = get_param(cmd, "STA_MUEDCA_Timer_BE");
12533 	if (val) {
12534 		param = atoi(val);
12535 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BE, param);
12536 	}
12537 
12538 	val = get_param(cmd, "STA_MUEDCA_Timer_BK");
12539 	if (val) {
12540 		param = atoi(val);
12541 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BK, param);
12542 	}
12543 
12544 	val = get_param(cmd, "STA_MUEDCA_Timer_VI");
12545 	if (val) {
12546 		param = atoi(val);
12547 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VI, param);
12548 	}
12549 
12550 	val = get_param(cmd, "STA_MUEDCA_Timer_VO");
12551 	if (val) {
12552 		param = atoi(val);
12553 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VO, param);
12554 	}
12555 
12556 	return SUCCESS_SEND_STATUS;
12557 }
12558 
12559 
12560 static int wcn_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
12561 			      const char *val)
12562 {
12563 	char *token, *result;
12564 	int channel = 36;
12565 	char *saveptr;
12566 
12567 	/* Extract the channel info */
12568 	token = strdup(val);
12569 	if (!token)
12570 		return -1;
12571 	result = strtok_r(token, ";", &saveptr);
12572 	if (result)
12573 		channel = atoi(result);
12574 
12575 	/* Issue the channel switch command */
12576 	run_iwpriv(dut, ifname, "setChanChange %d", channel);
12577 
12578 	free(token);
12579 	return 0;
12580 }
12581 
12582 
12583 static enum sigma_cmd_result wcn_ap_set_rfeature(struct sigma_dut *dut,
12584 						 struct sigma_conn *conn,
12585 						 struct sigma_cmd *cmd)
12586 {
12587 	const char *val;
12588 	const char *ifname;
12589 
12590 	ifname = get_main_ifname(dut);
12591 
12592 	val = get_param(cmd, "chnum_band");
12593 	if (val && wcn_vht_chnum_band(dut, ifname, val) < 0)
12594 		return ERROR_SEND_STATUS;
12595 
12596 	val = get_param(cmd, "txBandwidth");
12597 	if (val) {
12598 		int old_ch_bw = dut->ap_chwidth;
12599 
12600 		if (strcasecmp(val, "Auto") == 0) {
12601 			dut->ap_chwidth = 0;
12602 		} else if (strcasecmp(val, "20") == 0) {
12603 			dut->ap_chwidth = 0;
12604 		} else if (strcasecmp(val, "40") == 0) {
12605 			dut->ap_chwidth = 1;
12606 		} else if (strcasecmp(val, "80") == 0) {
12607 			dut->ap_chwidth = 2;
12608 		} else if (strcasecmp(val, "160") == 0) {
12609 			dut->ap_chwidth = 3;
12610 		} else {
12611 			send_resp(dut, conn, SIGMA_ERROR,
12612 				  "ErrorCode,WIDTH not supported");
12613 			return STATUS_SENT_ERROR;
12614 		}
12615 		if (old_ch_bw != dut->ap_chwidth) {
12616 			if (cmd_ap_config_commit(dut, conn, cmd) <= 0)
12617 				return STATUS_SENT_ERROR;
12618 		} else {
12619 			sigma_dut_print(dut, DUT_MSG_DEBUG, "No change in BW");
12620 		}
12621 	}
12622 
12623 	val = get_param(cmd, "GI");
12624 	if (val) {
12625 		int fix_rate_sgi;
12626 
12627 		if (strcmp(val, "0.8") == 0) {
12628 			run_iwpriv(dut, ifname, "enable_short_gi 9");
12629 			fix_rate_sgi = 1;
12630 		} else if (strcmp(val, "1.6") == 0) {
12631 			run_iwpriv(dut, ifname, "enable_short_gi 10");
12632 			fix_rate_sgi = 2;
12633 		} else if (strcmp(val, "3.2") == 0) {
12634 			run_iwpriv(dut, ifname, "enable_short_gi 11");
12635 			fix_rate_sgi = 3;
12636 		} else {
12637 			send_resp(dut, conn, SIGMA_ERROR,
12638 				  "errorCode,GI value not supported");
12639 			return STATUS_SENT_ERROR;
12640 		}
12641 		run_iwpriv(dut, ifname, "enable_short_gi %d", fix_rate_sgi);
12642 	}
12643 
12644 	val = get_param(cmd, "LTF");
12645 	if (val) {
12646 #ifdef NL80211_SUPPORT
12647 		if (strcmp(val, "3.2") == 0) {
12648 			wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_1X);
12649 		} if (strcmp(val, "6.4") == 0) {
12650 			wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_2X);
12651 		} else if (strcmp(val, "12.8") == 0) {
12652 			wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_4X);
12653 		} else {
12654 			send_resp(dut, conn, SIGMA_ERROR,
12655 				  "errorCode,LTF value not supported");
12656 			return STATUS_SENT;
12657 		}
12658 #else /* NL80211_SUPPORT */
12659 		sigma_dut_print(dut, DUT_MSG_ERROR,
12660 				"LTF cannot be set without NL80211_SUPPORT defined");
12661 		return ERROR_SEND_STATUS;
12662 #endif /* NL80211_SUPPORT */
12663 	}
12664 
12665 	return SUCCESS_SEND_STATUS;
12666 }
12667 
12668 
12669 static int mac80211_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
12670 				   const char *val)
12671 {
12672 	char *token, *result;
12673 	int channel = 36, chwidth = 80, center_freq_idx, center_freq,
12674 		channel_freq;
12675 	char buf[100];
12676 	char *saveptr;
12677 	int res;
12678 
12679 	/* Extract the channel info */
12680 	token = strdup(val);
12681 	if (!token)
12682 		return -1;
12683 	result = strtok_r(token, ";", &saveptr);
12684 	if (result)
12685 		channel = atoi(result);
12686 
12687 	/* Extract the channel width info */
12688 	result = strtok_r(NULL, ";", &saveptr);
12689 	if (result)
12690 		chwidth = atoi(result);
12691 
12692 	center_freq_idx = get_oper_centr_freq_seq_idx(chwidth, channel);
12693 	if (center_freq_idx < 0) {
12694 		free(token);
12695 		return -1;
12696 	}
12697 
12698 	center_freq = get_5g_channel_freq(center_freq_idx);
12699 	channel_freq = get_5g_channel_freq(channel);
12700 
12701 	/* Issue the channel switch command */
12702 	res = snprintf(buf, sizeof(buf),
12703 		       " -i %s chan_switch 10 %d sec_channel_offset=1 center_freq1=%d bandwidth=%d blocktx vht",
12704 		       ifname, channel_freq, center_freq, chwidth);
12705 	if (res < 0 || res >= sizeof(buf) || run_hostapd_cli(dut, buf) != 0) {
12706 		sigma_dut_print(dut, DUT_MSG_ERROR,
12707 				"hostapd_cli chan_switch failed");
12708 	}
12709 
12710 	free(token);
12711 	return 0;
12712 }
12713 
12714 
12715 static int mac80211_ap_set_rfeature(struct sigma_dut *dut,
12716 				    struct sigma_conn *conn,
12717 				    struct sigma_cmd *cmd)
12718 {
12719 	const char *val;
12720 	const char *ifname;
12721 
12722 	ifname = get_main_ifname(dut);
12723 
12724 	val = get_param(cmd, "RTS_FORCE");
12725 	if (val)
12726 		mac80211_config_rts_force(dut, ifname, val);
12727 
12728 	val = get_param(cmd, "chnum_band");
12729 	if (val && mac80211_vht_chnum_band(dut, ifname, val) < 0)
12730 		return -1;
12731 
12732 	return 1;
12733 }
12734 
12735 
12736 #ifdef __linux__
12737 static int wil6210_ap_set_rfeature(struct sigma_dut *dut,
12738 				   struct sigma_conn *conn,
12739 				   struct sigma_cmd *cmd)
12740 {
12741 	const char *val;
12742 
12743 	val = get_param(cmd, "ExtSchIE");
12744 	if (val && !strcasecmp(val, "Enable")) {
12745 		struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
12746 		int count = MAX_ESE_ALLOCS;
12747 
12748 		if (sta_extract_60g_ese(dut, cmd, allocs, &count))
12749 			return -1;
12750 		if (wil6210_set_ese(dut, count, allocs))
12751 			return -1;
12752 		return 1;
12753 	}
12754 
12755 	send_resp(dut, conn, SIGMA_ERROR,
12756 		  "errorCode,Invalid ap_set_rfeature(60G)");
12757 	return 0;
12758 }
12759 #endif /* __linux__ */
12760 
12761 
12762 static enum sigma_cmd_result cmd_ap_set_rfeature(struct sigma_dut *dut,
12763 						 struct sigma_conn *conn,
12764 						 struct sigma_cmd *cmd)
12765 {
12766 	/* const char *name = get_param(cmd, "NAME"); */
12767 	/* const char *type = get_param(cmd, "Type"); */
12768 	const char *val, *oci_chan, *oci_frametype;
12769 	char buf[100];
12770 	const char *ifname = get_hostapd_ifname(dut);
12771 
12772 	val = get_param(cmd, "ReassocResp_RSNXE_Used");
12773 	if (val) {
12774 		if (atoi(val) == 0)
12775 			snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 2");
12776 		else
12777 			snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 1");
12778 		if (hapd_command(ifname, buf) < 0) {
12779 			send_resp(dut, conn, SIGMA_ERROR,
12780 				  "ErrorCode,Failed to set ft_rsnxe_used");
12781 			return STATUS_SENT_ERROR;
12782 		}
12783 	}
12784 
12785 	oci_chan = get_param(cmd, "OCIChannel");
12786 	oci_frametype = get_param(cmd, "OCIFrameType");
12787 	if (oci_chan && oci_frametype) {
12788 		unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
12789 
12790 		if (!oci_freq) {
12791 			send_resp(dut, conn, SIGMA_ERROR,
12792 				  "errorCode,Invalid OCIChannel number");
12793 			return STATUS_SENT_ERROR;
12794 		}
12795 
12796 		if (strcasecmp(oci_frametype, "eapolM3") == 0) {
12797 			snprintf(buf, sizeof(buf),
12798 				 "SET oci_freq_override_eapol_m3 %d", oci_freq);
12799 		} else if (strcasecmp(oci_frametype, "eapolG1") == 0) {
12800 			snprintf(buf, sizeof(buf),
12801 				 "SET oci_freq_override_eapol_g1 %d", oci_freq);
12802 		} else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
12803 			snprintf(buf, sizeof(buf),
12804 				 "SET oci_freq_override_saquery_req %d",
12805 				 oci_freq);
12806 		} else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
12807 			snprintf(buf, sizeof(buf),
12808 				 "SET oci_freq_override_saquery_resp %d",
12809 				 oci_freq);
12810 		} else {
12811 			send_resp(dut, conn, SIGMA_ERROR,
12812 				  "errorCode,Unsupported OCIFrameType");
12813 			return STATUS_SENT_ERROR;
12814 		}
12815 		if (hapd_command(ifname, buf) < 0) {
12816 			send_resp(dut, conn, SIGMA_ERROR,
12817 				  "errorCode,Failed to set oci_freq_override");
12818 			return STATUS_SENT_ERROR;
12819 		}
12820 		return SUCCESS_SEND_STATUS;
12821 	}
12822 
12823 	switch (get_driver_type(dut)) {
12824 	case DRIVER_ATHEROS:
12825 		return ath_ap_set_rfeature(dut, conn, cmd);
12826 	case DRIVER_OPENWRT:
12827 		switch (get_openwrt_driver_type()) {
12828 		case OPENWRT_DRIVER_ATHEROS:
12829 			return ath_ap_set_rfeature(dut, conn, cmd);
12830 		default:
12831 			send_resp(dut, conn, SIGMA_ERROR,
12832 				  "errorCode,Unsupported ap_set_rfeature with the current openwrt driver");
12833 			return 0;
12834 		}
12835 	case DRIVER_LINUX_WCN:
12836 	case DRIVER_WCN:
12837 		return wcn_ap_set_rfeature(dut, conn, cmd);
12838 	case DRIVER_MAC80211:
12839 		return mac80211_ap_set_rfeature(dut, conn, cmd);
12840 #ifdef __linux__
12841 	case DRIVER_WIL6210:
12842 		return wil6210_ap_set_rfeature(dut, conn, cmd);
12843 #endif /* __linux__ */
12844 	default:
12845 		send_resp(dut, conn, SIGMA_ERROR,
12846 			  "errorCode,Unsupported ap_set_rfeature with the current driver");
12847 		return 0;
12848 	}
12849 }
12850 
12851 
12852 static enum sigma_cmd_result cmd_accesspoint(struct sigma_dut *dut,
12853 					     struct sigma_conn *conn,
12854 					     struct sigma_cmd *cmd)
12855 {
12856 	/* const char *name = get_param(cmd, "NAME"); */
12857 	return 1;
12858 }
12859 
12860 
12861 static enum sigma_cmd_result
12862 cmd_ap_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
12863 			     struct sigma_cmd *cmd)
12864 {
12865 	const char *val;
12866 
12867 	val = get_param(cmd, "Oper_Chn");
12868 	if (val) {
12869 		dut->ap_oper_chn = 1;
12870 		dut->ap_channel = atoi(val);
12871 	}
12872 
12873 	val = get_param(cmd, "DPPConfiguratorAddress");
12874 	if (val) {
12875 		free(dut->ap_dpp_conf_addr);
12876 		dut->ap_dpp_conf_addr = strdup(val);
12877 	}
12878 
12879 	val = get_param(cmd, "DPPConfiguratorPKHash");
12880 	if (val) {
12881 		free(dut->ap_dpp_conf_pkhash);
12882 		dut->ap_dpp_conf_pkhash = strdup(val);
12883 	}
12884 
12885 	return 1;
12886 }
12887 
12888 
12889 void ap_register_cmds(void)
12890 {
12891 	sigma_dut_reg_cmd("ap_ca_version", NULL, cmd_ap_ca_version);
12892 	sigma_dut_reg_cmd("ap_set_wireless", NULL, cmd_ap_set_wireless);
12893 	sigma_dut_reg_cmd("ap_send_addba_req", NULL, cmd_ap_send_addba_req);
12894 	sigma_dut_reg_cmd("ap_set_11n_wireless", NULL, cmd_ap_set_wireless);
12895 	sigma_dut_reg_cmd("ap_set_11n", NULL, cmd_ap_set_wireless);
12896 	sigma_dut_reg_cmd("ap_set_11d", NULL, cmd_ap_set_wireless);
12897 	sigma_dut_reg_cmd("ap_set_11h", NULL, cmd_ap_set_wireless);
12898 	sigma_dut_reg_cmd("ap_set_security", NULL, cmd_ap_set_security);
12899 	sigma_dut_reg_cmd("ap_set_apqos", NULL, cmd_ap_set_apqos);
12900 	sigma_dut_reg_cmd("ap_set_staqos", NULL, cmd_ap_set_staqos);
12901 	sigma_dut_reg_cmd("ap_set_radius", NULL, cmd_ap_set_radius);
12902 	sigma_dut_reg_cmd("ap_reboot", NULL, cmd_ap_reboot);
12903 	sigma_dut_reg_cmd("ap_config_commit", NULL, cmd_ap_config_commit);
12904 	sigma_dut_reg_cmd("ap_reset_default", NULL, cmd_ap_reset_default);
12905 	sigma_dut_reg_cmd("ap_get_info", NULL, cmd_ap_get_info);
12906 	sigma_dut_reg_cmd("ap_deauth_sta", NULL, cmd_ap_deauth_sta);
12907 	sigma_dut_reg_cmd("ap_send_frame", NULL, cmd_ap_send_frame);
12908 	sigma_dut_reg_cmd("ap_get_mac_address", NULL, cmd_ap_get_mac_address);
12909 	sigma_dut_reg_cmd("ap_set_pmf", NULL, cmd_ap_set_pmf);
12910 	sigma_dut_reg_cmd("ap_set_hs2", NULL, cmd_ap_set_hs2);
12911 	sigma_dut_reg_cmd("ap_set_rfeature", NULL, cmd_ap_set_rfeature);
12912 	sigma_dut_reg_cmd("ap_nfc_action", NULL, cmd_ap_nfc_action);
12913 	sigma_dut_reg_cmd("ap_wps_read_pin", NULL, cmd_ap_wps_read_pin);
12914 	sigma_dut_reg_cmd("ap_wps_enter_pin", NULL, cmd_ap_wps_enter_pin);
12915 	sigma_dut_reg_cmd("ap_wps_set_pbc", NULL, cmd_ap_wps_set_pbc);
12916 	sigma_dut_reg_cmd("ap_get_parameter", NULL, cmd_ap_get_parameter);
12917 	sigma_dut_reg_cmd("AccessPoint", NULL, cmd_accesspoint);
12918 	sigma_dut_reg_cmd("ap_preset_testparameters", NULL,
12919 			  cmd_ap_preset_testparameters);
12920 }
12921