xref: /wlan-dirver/utils/sigma-dut/ap.c (revision d2e9bb3ec6c7854c0e58f2b2641fc9173bfbcfa8)
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 	return SUCCESS_SEND_STATUS;
1894 }
1895 
1896 
1897 static void ath_inject_frame(struct sigma_dut *dut, const char *ifname, int tid)
1898 {
1899 	char buf[256];
1900 	int tid_to_dscp[] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
1901 
1902 	if (tid < 0 ||
1903 	    tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
1904 		sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
1905 		return;
1906 	}
1907 
1908 	snprintf(buf, sizeof(buf),
1909 		 "wlanconfig %s list sta | grep : | cut -b 1-17 > %s",
1910 		 ifname, VI_QOS_TMP_FILE);
1911 	if (system(buf) != 0)
1912 		return;
1913 
1914 	snprintf(buf, sizeof(buf),
1915 		 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
1916 		 ifname, VI_QOS_TMP_FILE);
1917 	if (system(buf) != 0)
1918 		sigma_dut_print(dut, DUT_MSG_ERROR, "Retrieve HWaddr failed");
1919 
1920 	snprintf(buf, sizeof(buf), "sed -n '3,$p' %s >> %s",
1921 		 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
1922 	if (system(buf) != 0) {
1923 		sigma_dut_print(dut, DUT_MSG_ERROR,
1924 				"Output redirection to VI_QOS_TMP_FILE failed");
1925 	}
1926 
1927 	snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
1928 		 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
1929 	if (system(buf) != 0) {
1930 		sigma_dut_print(dut, DUT_MSG_ERROR,
1931 				"Append TID to VI_QOS_FILE failed ");
1932 	}
1933 
1934 	snprintf(buf, sizeof(buf), "ethinject %s %s", ifname, VI_QOS_FILE);
1935 	if (system(buf) != 0)
1936 		sigma_dut_print(dut, DUT_MSG_ERROR, "Ethinject frame failed");
1937 }
1938 
1939 
1940 static int ath_ap_send_addba_req(struct sigma_dut *dut, struct sigma_conn *conn,
1941 				 struct sigma_cmd *cmd)
1942 {
1943 	const char *val;
1944 	const char *ifname;
1945 	char buf[256];
1946 	int tid = 0;
1947 
1948 	ifname = get_main_ifname(dut);
1949 	val = get_param(cmd, "TID");
1950 	if (val) {
1951 		tid = atoi(val);
1952 		if (tid)
1953 			ath_inject_frame(dut, ifname, tid);
1954 	}
1955 
1956 	/* NOTE: This is the command sequence on Peregrine for ADDBA */
1957 	run_iwpriv(dut, ifname, "setaddbaoper 1");
1958 
1959 	snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4",
1960 		 ifname, tid);
1961 	if (system(buf) != 0) {
1962 		sigma_dut_print(dut, DUT_MSG_ERROR,
1963 				"wifitool senddelba failed");
1964 	}
1965 
1966 	snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64",
1967 		 ifname, tid);
1968 	if (system(buf) != 0) {
1969 		sigma_dut_print(dut, DUT_MSG_ERROR,
1970 				"wifitool sendaddba failed");
1971 	}
1972 
1973 	return 1;
1974 }
1975 
1976 
1977 static int ath10k_debug_enable_addba_req(struct sigma_dut *dut, int tid,
1978 					 const char *sta_mac,
1979 					 const char *dir_path)
1980 {
1981 	DIR *dir;
1982 	struct dirent *entry;
1983 	char buf[128], path[128];
1984 	int ret = 0, res;
1985 
1986 	dir = opendir(dir_path);
1987 	if (!dir)
1988 		return 0;
1989 
1990 	while ((entry = readdir(dir))) {
1991 		ret = 1;
1992 
1993 		if (strcmp(entry->d_name, ".") == 0 ||
1994 		    strcmp(entry->d_name, "..") == 0)
1995 			continue;
1996 
1997 		res = snprintf(path, sizeof(path) - 1, "%s/%s",
1998 			       dir_path, entry->d_name);
1999 		if (res < 0 || res >= sizeof(path))
2000 			continue;
2001 
2002 		if (strcmp(entry->d_name, sta_mac) == 0) {
2003 			res = snprintf(buf, sizeof(buf),
2004 				       "echo 1 > %s/aggr_mode", path);
2005 			if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
2006 				sigma_dut_print(dut, DUT_MSG_ERROR,
2007 						"Failed to set aggr mode for ath10k");
2008 			}
2009 
2010 			res = snprintf(buf, sizeof(buf),
2011 				       "echo %d 32 > %s/addba", tid, path);
2012 			if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
2013 				sigma_dut_print(dut, DUT_MSG_ERROR,
2014 						"Failed to set addbareq for ath10k");
2015 			}
2016 
2017 			break;
2018 		}
2019 
2020 		/* Recursively search subdirectories */
2021 		ath10k_debug_enable_addba_req(dut, tid, sta_mac, path);
2022 	}
2023 
2024 	closedir(dir);
2025 
2026 	return ret;
2027 }
2028 
2029 
2030 static int ath10k_ap_send_addba_req(struct sigma_dut *dut,
2031 				    struct sigma_cmd *cmd)
2032 {
2033 	const char *val;
2034 	int tid = 0;
2035 
2036 	val = get_param(cmd, "TID");
2037 	if (val)
2038 		tid = atoi(val);
2039 
2040 	val = get_param(cmd, "sta_mac_address");
2041 	if (!val) {
2042 		sigma_dut_print(dut, DUT_MSG_ERROR,
2043 				"Failed to parse station MAC address");
2044 		return 0;
2045 	}
2046 
2047 	return ath10k_debug_enable_addba_req(dut, tid, val,
2048 					     "/sys/kernel/debug/ieee80211");
2049 }
2050 
2051 
2052 static enum sigma_cmd_result cmd_ap_send_addba_req(struct sigma_dut *dut,
2053 						   struct sigma_conn *conn,
2054 						   struct sigma_cmd *cmd)
2055 {
2056 	/* const char *name = get_param(cmd, "NAME"); */
2057 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
2058 	struct stat s;
2059 
2060 	switch (get_driver_type(dut)) {
2061 	case DRIVER_ATHEROS:
2062 		return ath_ap_send_addba_req(dut, conn, cmd);
2063 #ifdef __linux__
2064 	case DRIVER_WIL6210:
2065 		return send_addba_60g(dut, conn, cmd, "sta_mac_address");
2066 #endif /* __linux__ */
2067 	case DRIVER_OPENWRT:
2068 		switch (get_openwrt_driver_type()) {
2069 		case OPENWRT_DRIVER_ATHEROS:
2070 			return ath_ap_send_addba_req(dut, conn, cmd);
2071 		default:
2072 			send_resp(dut, conn, SIGMA_ERROR,
2073 				  "errorCode,ap_send_addba_req not supported with this driver");
2074 			return 0;
2075 		}
2076 	case DRIVER_WCN:
2077 	case DRIVER_LINUX_WCN:
2078 		/* AP automatically sends ADDBA request after association. */
2079 		sigma_dut_print(dut, DUT_MSG_INFO,
2080 				"ap_send_addba_req command ignored");
2081 		return 1;
2082 	case DRIVER_MAC80211:
2083 		if (stat("/sys/module/ath10k_core", &s) == 0)
2084 			return ath10k_ap_send_addba_req(dut, cmd);
2085 		/* fall through */
2086 	default:
2087 		send_resp(dut, conn, SIGMA_ERROR,
2088 			  "errorCode,ap_send_addba_req not supported with this driver");
2089 		return 0;
2090 	}
2091 }
2092 
2093 
2094 static enum sigma_cmd_result cmd_ap_set_security(struct sigma_dut *dut,
2095 						 struct sigma_conn *conn,
2096 						 struct sigma_cmd *cmd)
2097 {
2098 	/* const char *name = get_param(cmd, "NAME"); */
2099 	const char *val;
2100 	unsigned int wlan_tag = 1;
2101 	const char *security;
2102 
2103 	val = get_param(cmd, "WLAN_TAG");
2104 	if (val)
2105 		wlan_tag = atoi(val);
2106 
2107 	security = get_param(cmd, "Security");
2108 
2109 	if (wlan_tag > 1) {
2110 		val = get_param(cmd, "KEYMGNT");
2111 		if (!val)
2112 			val = get_param(cmd, "KeyMgmtType");
2113 		if (val) {
2114 			if (strcasecmp(val, "NONE") == 0) {
2115 				dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OPEN;
2116 			} else if (strcasecmp(val, "OSEN") == 0 &&
2117 				   wlan_tag == 2) {
2118 				/*
2119 				 * OSEN only supported on WLAN_TAG = 2 for now
2120 				 */
2121 				dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OSEN;
2122 			} else if (strcasecmp(val, "WPA2-PSK") == 0 ||
2123 				   (security &&
2124 				    strcasecmp(security, "PSK") == 0 &&
2125 				    strcasecmp(val, "WPA2") == 0)) {
2126 				dut->ap_tag_key_mgmt[wlan_tag - 2] =
2127 					AP2_WPA2_PSK;
2128 			} else if (strcasecmp(val, "OWE") == 0 &&
2129 				   wlan_tag == 2) {
2130 				dut->ap_tag_key_mgmt[wlan_tag - 2] =
2131 					AP2_WPA2_OWE;
2132 			} else {
2133 				send_resp(dut, conn, SIGMA_INVALID,
2134 					  "errorCode,Unsupported KEYMGNT");
2135 				return 0;
2136 			}
2137 			return 1;
2138 		}
2139 	}
2140 
2141 	val = get_param(cmd, "KEYMGNT");
2142 	if (!val)
2143 		val = get_param(cmd,"KeyMgmtType");
2144 	if (val) {
2145 		if (strcasecmp(val, "WPA2-PSK") == 0 ||
2146 		    (security && strcasecmp(security, "PSK") == 0 &&
2147 		     strcasecmp(val, "WPA2") == 0)) {
2148 			dut->ap_key_mgmt = AP_WPA2_PSK;
2149 			dut->ap_cipher = AP_CCMP;
2150 		} else if (strcasecmp(val, "WPA2-EAP") == 0 ||
2151 			   strcasecmp(val, "WPA2-Ent") == 0) {
2152 			dut->ap_key_mgmt = AP_WPA2_EAP;
2153 			dut->ap_cipher = AP_CCMP;
2154 		} else if (strcasecmp(val, "SuiteB") == 0) {
2155 			dut->ap_key_mgmt = AP_SUITEB;
2156 			dut->ap_cipher = AP_GCMP_256;
2157 			dut->ap_pmf = AP_PMF_REQUIRED;
2158 		} else if (strcasecmp(val, "WPA-PSK") == 0) {
2159 			dut->ap_key_mgmt = AP_WPA_PSK;
2160 			dut->ap_cipher = AP_TKIP;
2161 		} else if (strcasecmp(val, "WPA-EAP") == 0 ||
2162 			   strcasecmp(val, "WPA-Ent") == 0) {
2163 			dut->ap_key_mgmt = AP_WPA_EAP;
2164 			dut->ap_cipher = AP_TKIP;
2165 		} else if (strcasecmp(val, "WPA2-Mixed") == 0) {
2166 			dut->ap_key_mgmt = AP_WPA2_EAP_MIXED;
2167 			dut->ap_cipher = AP_CCMP_TKIP;
2168 		} else if (strcasecmp(val, "WPA2-PSK-Mixed") == 0) {
2169 			dut->ap_key_mgmt = AP_WPA2_PSK_MIXED;
2170 			dut->ap_cipher = AP_CCMP_TKIP;
2171 		} else if (strcasecmp(val, "WPA2-SAE") == 0 ||
2172 			   strcasecmp(val, "SAE") == 0) {
2173 			dut->ap_key_mgmt = AP_WPA2_SAE;
2174 			dut->ap_cipher = AP_CCMP;
2175 			dut->ap_pmf = AP_PMF_REQUIRED;
2176 		} else if (strcasecmp(val, "WPA2-PSK-SAE") == 0) {
2177 			dut->ap_key_mgmt = AP_WPA2_PSK_SAE;
2178 			dut->ap_cipher = AP_CCMP;
2179 			dut->ap_pmf = AP_PMF_OPTIONAL;
2180 		} else if (strcasecmp(val, "OWE") == 0) {
2181 			dut->ap_key_mgmt = AP_WPA2_OWE;
2182 			dut->ap_cipher = AP_CCMP;
2183 			dut->ap_pmf = AP_PMF_REQUIRED;
2184 		} else if (strcasecmp(val, "WPA2-ENT-OSEN") == 0) {
2185 			dut->ap_key_mgmt = AP_WPA2_EAP_OSEN;
2186 			dut->ap_cipher = AP_CCMP;
2187 			dut->ap_pmf = AP_PMF_OPTIONAL;
2188 		} else if (strcasecmp(val, "OSEN") == 0) {
2189 			dut->ap_key_mgmt = AP_OSEN;
2190 			dut->ap_cipher = AP_CCMP;
2191 		} else if (strcasecmp(val, "FT-EAP") == 0) {
2192 			dut->ap_key_mgmt = AP_WPA2_FT_EAP;
2193 			dut->ap_cipher = AP_CCMP;
2194 			dut->ap_pmf = AP_PMF_OPTIONAL;
2195 		} else if (strcasecmp(val, "FT-PSK") == 0) {
2196 			dut->ap_key_mgmt = AP_WPA2_FT_PSK;
2197 			dut->ap_cipher = AP_CCMP;
2198 			dut->ap_pmf = AP_PMF_OPTIONAL;
2199 		} else if (strcasecmp(val, "WPA2-ENT-256") == 0) {
2200 			dut->ap_key_mgmt = AP_WPA2_EAP_SHA256;
2201 			dut->ap_cipher = AP_CCMP;
2202 			dut->ap_pmf = AP_PMF_OPTIONAL;
2203 		} else if (strcasecmp(val, "WPA2-PSK-256") == 0) {
2204 			dut->ap_key_mgmt = AP_WPA2_PSK_SHA256;
2205 			dut->ap_cipher = AP_CCMP;
2206 			dut->ap_pmf = AP_PMF_OPTIONAL;
2207 		} else if (strcasecmp(val, "WPA2-ENT-FT-EAP") == 0) {
2208 			dut->ap_key_mgmt = AP_WPA2_ENT_FT_EAP;
2209 			dut->ap_cipher = AP_CCMP;
2210 			dut->ap_pmf = AP_PMF_OPTIONAL;
2211 		} else if (strcasecmp(val, "NONE") == 0) {
2212 			dut->ap_key_mgmt = AP_OPEN;
2213 			dut->ap_cipher = AP_PLAIN;
2214 		} else {
2215 			send_resp(dut, conn, SIGMA_INVALID,
2216 				  "errorCode,Unsupported KEYMGNT");
2217 			return 0;
2218 		}
2219 	}
2220 
2221 	val = get_param(cmd, "ECGroupID");
2222 	if (val) {
2223 		free(dut->ap_sae_groups);
2224 		dut->ap_sae_groups = strdup(val);
2225 	}
2226 
2227 	val = get_param(cmd, "AntiCloggingThreshold");
2228 	if (val)
2229 		dut->sae_anti_clogging_threshold = atoi(val);
2230 
2231 	val = get_param(cmd, "Reflection");
2232 	if (val)
2233 		dut->sae_reflection = strcasecmp(val, "SAE") == 0;
2234 
2235 	val = get_param(cmd, "InvalidSAEElement");
2236 	if (val) {
2237 		free(dut->sae_commit_override);
2238 		dut->sae_commit_override = strdup(val);
2239 	}
2240 
2241 	val = get_param(cmd, "SAEPasswords");
2242 	if (val) {
2243 		free(dut->ap_sae_passwords);
2244 		dut->ap_sae_passwords = strdup(val);
2245 	}
2246 
2247 	val = get_param(cmd, "SAE_Confirm_Immediate");
2248 	if (val)
2249 		dut->sae_confirm_immediate = get_enable_disable(val);
2250 
2251 	val = get_param(cmd, "sae_pwe");
2252 	if (val) {
2253 		if (strcasecmp(val, "h2e") == 0) {
2254 			dut->sae_pwe = SAE_PWE_H2E;
2255 		} else if (strcasecmp(val, "loop") == 0 ||
2256 			   strcasecmp(val, "looping") == 0) {
2257 			dut->sae_pwe = SAE_PWE_LOOP;
2258 		} else {
2259 			send_resp(dut, conn, SIGMA_ERROR,
2260 				  "errorCode,Unsupported sae_pwe value");
2261 			return STATUS_SENT_ERROR;
2262 		}
2263 	}
2264 
2265 	val = get_param(cmd, "RSNXE_Content");
2266 	if (val) {
2267 		if (strncasecmp(val, "EapolM3:", 8) != 0) {
2268 			send_resp(dut, conn, SIGMA_ERROR,
2269 				  "errorCode,Unsupported RSNXE_Content value");
2270 			return STATUS_SENT_ERROR;
2271 		}
2272 		val += 8;
2273 		free(dut->rsnxe_override_eapol);
2274 		dut->rsnxe_override_eapol = strdup(val);
2275 	}
2276 
2277 	val = get_param(cmd, "ENCRYPT");
2278 	if (!val)
2279 		val = get_param(cmd, "EncpType");
2280 	if (val) {
2281 		if (strcasecmp(val, "WEP") == 0) {
2282 			dut->ap_cipher = AP_WEP;
2283 		} else if (strcasecmp(val, "TKIP") == 0) {
2284 			dut->ap_cipher = AP_TKIP;
2285 		} else if (strcasecmp(val, "AES") == 0 ||
2286 			   strcasecmp(val, "AES-CCMP") == 0) {
2287 			dut->ap_cipher = AP_CCMP;
2288 		} else if (strcasecmp(val, "AES-GCMP") == 0) {
2289 			dut->ap_cipher = AP_GCMP_128;
2290 		} else {
2291 			send_resp(dut, conn, SIGMA_INVALID,
2292 				  "errorCode,Unsupported ENCRYPT");
2293 			return 0;
2294 		}
2295 	}
2296 
2297 	val = get_param(cmd, "PairwiseCipher");
2298 	if (val) {
2299 		if (strcasecmp(val, "AES-GCMP-256") == 0) {
2300 			dut->ap_cipher = AP_GCMP_256;
2301 		} else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2302 			dut->ap_cipher = AP_CCMP_256;
2303 		} else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2304 			dut->ap_cipher = AP_GCMP_128;
2305 		} else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2306 			dut->ap_cipher = AP_CCMP;
2307 		} else if (strcasecmp(val, "AES-CCMP-128 AES-GCMP-256") == 0 ||
2308 			   strcasecmp(val, "AES-GCMP-256 AES-CCMP-128") == 0) {
2309 			dut->ap_cipher = AP_CCMP_128_GCMP_256;
2310 		} else {
2311 			send_resp(dut, conn, SIGMA_INVALID,
2312 				  "errorCode,Unsupported PairwiseCipher");
2313 			return 0;
2314 		}
2315 	}
2316 
2317 	val = get_param(cmd, "GroupCipher");
2318 	if (val) {
2319 		if (strcasecmp(val, "AES-GCMP-256") == 0) {
2320 			dut->ap_group_cipher = AP_GCMP_256;
2321 		} else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2322 			dut->ap_group_cipher = AP_CCMP_256;
2323 		} else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2324 			dut->ap_group_cipher = AP_GCMP_128;
2325 		} else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2326 			dut->ap_group_cipher = AP_CCMP;
2327 		} else {
2328 			send_resp(dut, conn, SIGMA_INVALID,
2329 				  "errorCode,Unsupported GroupCipher");
2330 			return 0;
2331 		}
2332 	}
2333 
2334 	val = get_param(cmd, "GroupMgntCipher");
2335 	if (val) {
2336 		if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2337 			dut->ap_group_mgmt_cipher = AP_BIP_GMAC_256;
2338 		} else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2339 			dut->ap_group_mgmt_cipher = AP_BIP_CMAC_256;
2340 		} else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2341 			dut->ap_group_mgmt_cipher = AP_BIP_GMAC_128;
2342 		} else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2343 			dut->ap_group_mgmt_cipher = AP_BIP_CMAC_128;
2344 		} else {
2345 			send_resp(dut, conn, SIGMA_INVALID,
2346 				  "errorCode,Unsupported GroupMgntCipher");
2347 			return 0;
2348 		}
2349 	}
2350 
2351 	val = get_param(cmd, "WEPKEY");
2352 	if (val) {
2353 		size_t len;
2354 		if (dut->ap_cipher != AP_WEP) {
2355 			send_resp(dut, conn, SIGMA_INVALID,
2356 				  "errorCode,Unexpected WEPKEY without WEP "
2357 				  "configuration");
2358 			return 0;
2359 		}
2360 		len = strlen(val);
2361 		if (len != 10 && len != 26) {
2362 			send_resp(dut, conn, SIGMA_INVALID,
2363 				  "errorCode,Unexpected WEPKEY length");
2364 			return 0;
2365 		}
2366 		snprintf(dut->ap_wepkey, sizeof(dut->ap_wepkey), "%s", val);
2367 	}
2368 
2369 	val = get_param(cmd, "PSK");
2370 	if (!val)
2371 		val = get_param(cmd, "passphrase");
2372 	if (val) {
2373 		if (dut->ap_key_mgmt != AP_WPA2_SAE &&
2374 		    (dut->ap_akm_values & (AKM_WPA_PSK | AKM_SAE)) !=
2375 		    AKM_SAE &&
2376 		    strlen(val) > 64) {
2377 			sigma_dut_print(dut, DUT_MSG_ERROR,
2378 					"Too long PSK/passphtase");
2379 			return -1;
2380 		}
2381 		if (strlen(val) > sizeof(dut->ap_passphrase) - 1)
2382 			return -1;
2383 		snprintf(dut->ap_passphrase, sizeof(dut->ap_passphrase),
2384 			 "%s", val);
2385 	}
2386 
2387 	val = get_param(cmd, "PSKHEX");
2388 	if (val) {
2389 		if (strlen(val) != 64)
2390 			return -1;
2391 		strlcpy(dut->ap_psk, val, sizeof(dut->ap_psk));
2392 	}
2393 
2394 	if (dut->program == PROGRAM_OCE && dut->dev_role == DEVROLE_STA_CFON)
2395 		dut->ap_pmf = AP_PMF_OPTIONAL;
2396 
2397 	val = get_param(cmd, "PMF");
2398 	if (val) {
2399 		if (strcasecmp(val, "Disabled") == 0) {
2400 			dut->ap_pmf = AP_PMF_DISABLED;
2401 		} else if (strcasecmp(val, "Optional") == 0) {
2402 			dut->ap_pmf = AP_PMF_OPTIONAL;
2403 		} else if (strcasecmp(val, "Required") == 0) {
2404 			dut->ap_pmf = AP_PMF_REQUIRED;
2405 		} else {
2406 			send_resp(dut, conn, SIGMA_INVALID,
2407 				  "errorCode,Unsupported PMF");
2408 			return 0;
2409 		}
2410 	}
2411 
2412 	dut->ap_add_sha256 = 0;
2413 	val = get_param(cmd, "SHA256AD");
2414 	if (val == NULL)
2415 		val = get_param(cmd, "SHA256");
2416 	if (val) {
2417 		if (strcasecmp(val, "Disabled") == 0) {
2418 		} else if (strcasecmp(val, "Enabled") == 0) {
2419 			dut->ap_add_sha256 = 1;
2420 		} else {
2421 			send_resp(dut, conn, SIGMA_INVALID,
2422 				  "errorCode,Unsupported SHA256");
2423 			return 0;
2424 		}
2425 	}
2426 
2427 	val = get_param(cmd, "PreAuthentication");
2428 	if (val) {
2429 		if (strcasecmp(val, "disabled") == 0) {
2430 			dut->ap_rsn_preauth = 0;
2431 		} else if (strcasecmp(val, "enabled") == 0) {
2432 			dut->ap_rsn_preauth = 1;
2433 		} else {
2434 			send_resp(dut, conn, SIGMA_INVALID,
2435 				  "errorCode,Unsupported PreAuthentication value");
2436 			return 0;
2437 		}
2438 	}
2439 
2440 	val = get_param(cmd, "AKMSuiteType");
2441 	if (val) {
2442 		const char *in_pos = val;
2443 
2444 		dut->ap_akm_values = 0;
2445 		while (*in_pos) {
2446 			int akm = atoi(in_pos);
2447 
2448 			if (akm < 0 || akm >= 32) {
2449 				send_resp(dut, conn, SIGMA_ERROR,
2450 					  "errorCode,Unsupported AKMSuiteType value");
2451 				return STATUS_SENT;
2452 			}
2453 
2454 			dut->ap_akm_values |= 1 << akm;
2455 
2456 			in_pos = strchr(in_pos, ';');
2457 			if (!in_pos)
2458 				break;
2459 			while (*in_pos == ';')
2460 				in_pos++;
2461 		}
2462 		dut->ap_akm = 1;
2463 		if (dut->ap_akm_values & (1 << 14))
2464 			dut->ap_add_sha384 = 1;
2465 		if (dut->ap_akm_values & (1 << 15))
2466 			dut->ap_add_sha384 = 1;
2467 	}
2468 
2469 	if (dut->ap_key_mgmt == AP_OPEN && !dut->ap_akm_values) {
2470 		dut->ap_hs2 = 0;
2471 		dut->ap_pmf = AP_PMF_DISABLED;
2472 	}
2473 
2474 	val = get_param(cmd, "PMKSACaching");
2475 	if (val) {
2476 		dut->ap_pmksa = 1;
2477 		if (strcasecmp(val, "disabled") == 0) {
2478 			dut->ap_pmksa_caching = 1;
2479 		} else if (strcasecmp(val, "enabled") == 0) {
2480 			dut->ap_pmksa_caching = 0;
2481 		} else {
2482 			send_resp(dut, conn, SIGMA_INVALID,
2483 				  "errorCode,Unsupported PMKSACaching value");
2484 			return 0;
2485 		}
2486 	}
2487 
2488 	val = get_param(cmd, "BeaconProtection");
2489 	if (val)
2490 		dut->ap_beacon_prot = atoi(val);
2491 
2492 	val = get_param(cmd, "Transition_Disable");
2493 	if (val) {
2494 		if (atoi(val)) {
2495 			val = get_param(cmd, "Transition_Disable_Index");
2496 			if (!val) {
2497 				send_resp(dut, conn, SIGMA_INVALID,
2498 					  "errorCode,Transition_Disable without Transition_Disable_Index");
2499 				return STATUS_SENT;
2500 			}
2501 			dut->ap_transition_disable = 1 << atoi(val);
2502 		} else {
2503 			dut->ap_transition_disable = 0;
2504 		}
2505 	}
2506 
2507 	return 1;
2508 }
2509 
2510 
2511 int sta_cfon_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
2512 			  struct sigma_cmd *cmd)
2513 {
2514 	int status;
2515 
2516 	status = cmd_ap_set_wireless(dut, conn, cmd);
2517 	if (status != 1)
2518 		return status;
2519 	status = cmd_ap_set_security(dut, conn, cmd);
2520 	if (status != 1)
2521 		return status;
2522 	return cmd_ap_config_commit(dut, conn, cmd);
2523 }
2524 
2525 
2526 static enum sigma_cmd_result cmd_ap_set_radius(struct sigma_dut *dut,
2527 					       struct sigma_conn *conn,
2528 					       struct sigma_cmd *cmd)
2529 {
2530 	/* const char *name = get_param(cmd, "NAME"); */
2531 	const char *val;
2532 	unsigned int wlan_tag = 1, radius_port = 0;
2533 	char *radius_ipaddr = NULL, *radius_password = NULL;
2534 
2535 	val = get_param(cmd, "WLAN_TAG");
2536 	if (val) {
2537 		wlan_tag = atoi(val);
2538 		if (wlan_tag != 1 && wlan_tag != 2) {
2539 			send_resp(dut, conn, SIGMA_INVALID,
2540 				  "errorCode,Invalid WLAN_TAG");
2541 			return 0;
2542 		}
2543 	}
2544 
2545 	val = get_param(cmd, "PORT");
2546 	if (val)
2547 		radius_port = atoi(val);
2548 
2549 	if (wlan_tag == 1) {
2550 		if (radius_port)
2551 			dut->ap_radius_port = radius_port;
2552 		radius_ipaddr = dut->ap_radius_ipaddr;
2553 		radius_password = dut->ap_radius_password;
2554 	} else if (wlan_tag == 2) {
2555 		if (radius_port)
2556 			dut->ap2_radius_port = radius_port;
2557 		radius_ipaddr = dut->ap2_radius_ipaddr;
2558 		radius_password = dut->ap2_radius_password;
2559 	}
2560 
2561 	val = get_param(cmd, "IPADDR");
2562 	if (val) {
2563 		if (strlen(val) > sizeof(dut->ap_radius_ipaddr) - 1)
2564 			return -1;
2565 		snprintf(radius_ipaddr, sizeof(dut->ap_radius_ipaddr),
2566 			 "%s", val);
2567 	}
2568 
2569 	val = get_param(cmd, "PASSWORD");
2570 	if (val) {
2571 		if (strlen(val) > sizeof(dut->ap_radius_password) - 1)
2572 			return -1;
2573 		snprintf(radius_password,
2574 			 sizeof(dut->ap_radius_password), "%s", val);
2575 	}
2576 
2577 	return 1;
2578 }
2579 
2580 
2581 static void owrt_ap_set_qcawifi(struct sigma_dut *dut, const char *key,
2582 				const char *val)
2583 {
2584 	if (!val) {
2585 		run_system_wrapper(dut, "uci delete wireless.qcawifi.%s", key);
2586 		return;
2587 	}
2588 
2589 	run_system(dut, "uci set wireless.qcawifi=qcawifi");
2590 	run_system_wrapper(dut, "uci set wireless.qcawifi.%s=%s", key, val);
2591 }
2592 
2593 
2594 static void owrt_ap_set_radio(struct sigma_dut *dut, int id,
2595 			      const char *key, const char *val)
2596 {
2597 	char buf[100];
2598 
2599 	if (val == NULL) {
2600 		snprintf(buf, sizeof(buf),
2601 			 "uci delete wireless.wifi%d.%s", id, key);
2602 		run_system(dut, buf);
2603 		return;
2604 	}
2605 
2606 	snprintf(buf, sizeof(buf), "uci set wireless.wifi%d.%s=%s",
2607 		 id, key, val);
2608 	run_system(dut, buf);
2609 }
2610 
2611 
2612 static void owrt_ap_set_list_radio(struct sigma_dut *dut, int id,
2613 				   const char *key, const char *val)
2614 {
2615 	char buf[256];
2616 
2617 	if (val == NULL) {
2618 		snprintf(buf, sizeof(buf),
2619 			 "uci del_list wireless.wifi%d.%s", id, key);
2620 		run_system(dut, buf);
2621 		return;
2622 	}
2623 
2624 	snprintf(buf, sizeof(buf), "uci add_list wireless.wifi%d.%s=%s",
2625 		 id, key, val);
2626 	run_system(dut, buf);
2627 }
2628 
2629 
2630 static void owrt_ap_set_vap(struct sigma_dut *dut, int id, const char *key,
2631 			    const char *val)
2632 {
2633 	char buf[256];
2634 
2635 	if (val == NULL) {
2636 		snprintf(buf, sizeof(buf),
2637 			 "uci delete wireless.@wifi-iface[%d].%s", id, key);
2638 		run_system(dut, buf);
2639 		return;
2640 	}
2641 
2642 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2643 		 id, key, val);
2644 	run_system(dut, buf);
2645 }
2646 
2647 
2648 static void owrt_ap_set_list_vap(struct sigma_dut *dut, int id,
2649 				 const char *key, const char *val)
2650 {
2651 	char buf[1024];
2652 
2653 	if (val == NULL) {
2654 		snprintf(buf, sizeof(buf),
2655 			 "uci del_list wireless.@wifi-iface[%d].%s", id, key);
2656 		run_system(dut, buf);
2657 		return;
2658 	}
2659 
2660 	snprintf(buf, sizeof(buf),
2661 		 "uci add_list wireless.@wifi-iface[%d].%s=%s",
2662 		 id, key, val);
2663 	run_system(dut, buf);
2664 }
2665 
2666 
2667 static void owrt_ap_add_vap(struct sigma_dut *dut, int id, const char *key,
2668 			    const char *val)
2669 {
2670 	char buf[256];
2671 	int res;
2672 
2673 	if (val == NULL) {
2674 		res = snprintf(buf, sizeof(buf),
2675 			       "uci delete wireless.@wifi-iface[%d].%s",
2676 			       id, key);
2677 		if (res >= 0 && res < sizeof(buf))
2678 			run_system(dut, buf);
2679 		return;
2680 	}
2681 
2682 	run_system(dut, "uci add wireless wifi-iface");
2683 	res = snprintf(buf, sizeof(buf),
2684 		       "uci set wireless.@wifi-iface[%d].%s=%s",
2685 		       id, key, val);
2686 	if (res >= 0 && res < sizeof(buf))
2687 		run_system(dut, buf);
2688 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2689 		 id, "network", "lan");
2690 	run_system(dut, buf);
2691 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2692 		 id, "mode", "ap");
2693 	run_system(dut, buf);
2694 	snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2695 		 id, "encryption", "none");
2696 	run_system(dut, buf);
2697 }
2698 
2699 
2700 #define OPENWRT_MAX_NUM_RADIOS (MAX_RADIO + 1)
2701 static int owrt_ap_config_radio(struct sigma_dut *dut)
2702 {
2703 	int radio_id[MAX_RADIO] = { 0, 1, 2 };
2704 	int radio_count, radio_no;
2705 	char buf[64];
2706 
2707 	for (radio_count = 0; radio_count < OPENWRT_MAX_NUM_RADIOS;
2708 	     radio_count++) {
2709 		snprintf(buf, sizeof(buf), "%s%d", "wifi", radio_count);
2710 		for (radio_no = 0; radio_no < MAX_RADIO; radio_no++) {
2711 			if (!sigma_radio_ifname[radio_no] ||
2712 			    strcmp(sigma_radio_ifname[radio_no], buf) != 0)
2713 				continue;
2714 			owrt_ap_set_radio(dut, radio_count, "disabled", "0");
2715 			owrt_ap_set_vap(dut, radio_count, "device", buf);
2716 			radio_id[radio_no] = radio_count;
2717 		}
2718 	}
2719 
2720 	/* Hardware mode (11a/b/g/n/ac) & HT mode selection */
2721 	switch (dut->ap_mode) {
2722 	case AP_11g:
2723 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11g");
2724 		break;
2725 	case AP_11b:
2726 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11b");
2727 		break;
2728 	case AP_11ng:
2729 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng");
2730 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2731 		break;
2732 	case AP_11a:
2733 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11a");
2734 		break;
2735 	case AP_11na:
2736 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11na");
2737 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2738 		break;
2739 	case AP_11ac:
2740 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ac");
2741 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2742 		break;
2743 	case AP_11ax:
2744 		if (dut->ap_channel >= 36) {
2745 			owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axa");
2746 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2747 		} else {
2748 			owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axg");
2749 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2750 		}
2751 		break;
2752 	case AP_inval:
2753 		sigma_dut_print(dut, DUT_MSG_ERROR,
2754 				"MODE NOT SPECIFIED!");
2755 		return -1;
2756 	default:
2757 		owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng");
2758 		owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2759 		break;
2760 	}
2761 
2762 	if (dut->ap_is_dual) {
2763 		/* Hardware mode (11a/b/g/n/ac) & HT mode selection */
2764 		switch (dut->ap_mode_1) {
2765 		case AP_11g:
2766 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11g");
2767 			break;
2768 		case AP_11b:
2769 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11b");
2770 			break;
2771 		case AP_11ng:
2772 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng");
2773 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2774 			break;
2775 		case AP_11a:
2776 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11a");
2777 			break;
2778 		case AP_11na:
2779 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11na");
2780 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2781 			break;
2782 		case AP_11ac:
2783 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ac");
2784 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT80");
2785 			break;
2786 		case AP_11ax:
2787 			if (dut->ap_channel >= 36) {
2788 				owrt_ap_set_radio(dut, radio_id[1],
2789 						  "hwmode", "11axa");
2790 				owrt_ap_set_radio(dut, radio_id[1],
2791 						  "htmode", "HT80");
2792 			} else {
2793 				owrt_ap_set_radio(dut, radio_id[1],
2794 						  "hwmode", "11axg");
2795 				owrt_ap_set_radio(dut, radio_id[1],
2796 						  "htmode", "HT20");
2797 			}
2798 			break;
2799 		case AP_inval:
2800 			sigma_dut_print(dut, DUT_MSG_ERROR,
2801 					"MODE NOT SPECIFIED!");
2802 			return -1;
2803 		default:
2804 			owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng");
2805 			owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2806 			break;
2807 		}
2808 
2809 	}
2810 
2811 	/* Channel */
2812 	snprintf(buf, sizeof(buf), "%d", dut->ap_channel);
2813 	owrt_ap_set_radio(dut, radio_id[0], "channel", buf);
2814 
2815 	switch (dut->ap_chwidth) {
2816 		case AP_20:
2817 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2818 			break;
2819 		case AP_40:
2820 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT40");
2821 			break;
2822 		case AP_80:
2823 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2824 			break;
2825 		case AP_160:
2826 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT160");
2827 			break;
2828 		case AP_80_80:
2829 			owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80_80");
2830 			break;
2831 		case AP_AUTO:
2832 		default:
2833 			break;
2834 	}
2835 
2836 	if (dut->ap_channel == 140 || dut->ap_channel == 144) {
2837 		if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
2838 			owrt_ap_set_radio(dut, radio_id[0], "set_ch_144", "3");
2839 	}
2840 
2841 	if (dut->ap_is_dual) {
2842 		snprintf(buf, sizeof(buf), "%d", dut->ap_channel_1);
2843 		owrt_ap_set_radio(dut, radio_id[1], "channel", buf);
2844 	}
2845 
2846 	/* Country Code */
2847 	if (dut->ap_reg_domain == REG_DOMAIN_GLOBAL) {
2848 		const char *country;
2849 
2850 		country = dut->ap_countrycode[0] ? dut->ap_countrycode : "US";
2851 		snprintf(buf, sizeof(buf), "%s4", country);
2852 		owrt_ap_set_radio(dut, radio_id[0], "country", buf);
2853 		if (dut->ap_is_dual)
2854 			owrt_ap_set_radio(dut, radio_id[1], "country", buf);
2855 	} else if (dut->ap_countrycode[0]) {
2856 		owrt_ap_set_radio(dut, radio_id[0], "country",
2857 				  dut->ap_countrycode);
2858 	}
2859 
2860 	if (dut->ap_disable_protection == 1) {
2861 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'0 0'");
2862 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'1 0'");
2863 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'2 0'");
2864 		owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'3 0'");
2865 	}
2866 
2867 	if (dut->ap_oce == VALUE_ENABLED &&
2868 	    get_driver_type(dut) == DRIVER_OPENWRT)
2869 		owrt_ap_set_radio(dut, radio_id[0], "bcnburst", "1");
2870 
2871 	if (dut->ap_mbssid == VALUE_ENABLED)
2872 		owrt_ap_set_qcawifi(dut, "mbss_ie_enable", "1");
2873 
2874 	if (dut->program == PROGRAM_HE) {
2875 		owrt_ap_set_radio(dut, radio_id[0], "he_bsscolor", "'1 1'");
2876 		if (dut->ap_is_dual)
2877 			owrt_ap_set_radio(dut, radio_id[1], "he_bsscolor",
2878 					  "'2 1'");
2879 		owrt_ap_set_qcawifi(dut, "ap_bss_color_collision_detection",
2880 				    "1");
2881 	}
2882 
2883 	return 1;
2884 }
2885 
2886 
2887 static int owrt_ap_config_vap_hs2(struct sigma_dut *dut, int vap_id)
2888 {
2889 	char buf[256];
2890 
2891 	snprintf(buf, sizeof(buf), "%d", dut->ap_hs2);
2892 	owrt_ap_set_vap(dut, vap_id, "hs20", buf);
2893 	owrt_ap_set_vap(dut, vap_id, "qbssload", "1");
2894 	owrt_ap_set_vap(dut, vap_id, "hs20_deauth_req_timeout","3");
2895 
2896 	owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name",
2897 			     "'eng:Wi-Fi Alliance'");
2898 
2899 	owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name",
2900 			     "'chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f'");
2901 
2902 	if (dut->ap_wan_metrics == 1)
2903 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2904 				"'01:2500:384:0:0:10'");
2905 	else if (dut->ap_wan_metrics == 1)
2906 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2907 				"'01:1500:384:20:20:10'");
2908 	else if (dut->ap_wan_metrics == 2)
2909 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2910 				"'01:1500:384:20:20:10'");
2911 	else if (dut->ap_wan_metrics == 3)
2912 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2913 				"'01:2000:1000:20:20:10'");
2914 	else if (dut->ap_wan_metrics == 4)
2915 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2916 				"'01:8000:1000:20:20:10'");
2917 	else if (dut->ap_wan_metrics == 5)
2918 		owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
2919 				"'01:9000:5000:20:20:10'");
2920 
2921 	if (dut->ap_conn_capab == 1) {
2922 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", "'1:0:0'");
2923 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2924 				     "'6:20:1'");
2925 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2926 				     "'6:22:0'");
2927 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2928 				     "'6:80:1'");
2929 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2930 				     "'6:443:1'");
2931 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2932 				     "'6:1723:0'");
2933 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2934 				     "'6:5060:0'");
2935 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2936 				     "'17:500:1'");
2937 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2938 				     "'17:5060:0'");
2939 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2940 				     "'17:4500:1'");
2941 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2942 				     "'50:0:1'");
2943 	} else if (dut->ap_conn_capab == 2) {
2944 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2945 				     "'6:80:1'");
2946 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2947 				     "'6:443:1'");
2948 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2949 				     "'17:5060:1'");
2950 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2951 				     "'6:5060:1'");
2952 	} else if (dut->ap_conn_capab == 3) {
2953 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2954 				     "'6:80:1'");
2955 		owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
2956 				     "'6:443:1'");
2957 	}
2958 
2959 	if (dut->ap_oper_class == 1)
2960 		snprintf(buf, sizeof(buf), "%s", "51");
2961 	else if (dut->ap_oper_class == 2)
2962 		snprintf(buf, sizeof(buf), "%s", "73");
2963 	else if (dut->ap_oper_class == 3)
2964 		snprintf(buf, sizeof(buf), "%s", "5173");
2965 
2966 	if (dut->ap_oper_class)
2967 		owrt_ap_set_vap(dut, vap_id, "hs20_operating_class", buf);
2968 
2969 	if (dut->ap_osu_provider_list) {
2970 		char *osu_friendly_name = NULL;
2971 		char *osu_icon = NULL;
2972 		char *osu_ssid = NULL;
2973 		char *osu_nai = NULL;
2974 		char *osu_service_desc = NULL;
2975 		char *hs20_icon_filename = NULL;
2976 		char hs20_icon[150];
2977 		int osu_method;
2978 
2979 		hs20_icon_filename = "icon_red_zxx.png";
2980 		if (dut->ap_osu_icon_tag == 2)
2981 			hs20_icon_filename = "wifi-abgn-logo_270x73.png";
2982 		snprintf(hs20_icon, sizeof(hs20_icon),
2983 			 "'128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s'",
2984 			 hs20_icon_filename);
2985 		osu_icon = "icon_red_zxx.png";
2986 		osu_ssid = "OSU";
2987 		osu_friendly_name = "'kor:SP 빨강 테스트 전용'";
2988 		osu_service_desc = "'kor:테스트 목적으로 무료 서비스'";
2989 		osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 :
2990 			dut->ap_osu_method[0];
2991 
2992 		if (strlen(dut->ap_osu_server_uri[0]))
2993 			owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri",
2994 					     dut->ap_osu_server_uri[0]);
2995 		else
2996 			owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri",
2997 					     "'https://osu-server.r2-testbed.wi-fi.org/'");
2998 		switch (dut->ap_osu_provider_list) {
2999 		case 1:
3000 		case 101:
3001 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3002 					     "'eng:SP Red Test Only'");
3003 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3004 					     "'eng:Free service for test purpose'");
3005 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3006 					     hs20_icon);
3007 
3008 			hs20_icon_filename = "icon_red_eng.png";
3009 			if (dut->ap_osu_icon_tag == 2)
3010 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3011 
3012 			snprintf(hs20_icon, sizeof(hs20_icon),
3013 				 "'160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s'",
3014 				 hs20_icon_filename);
3015 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3016 					     "icon_red_eng.png");
3017 			break;
3018 		case 2:
3019 		case 102:
3020 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3021 					     "'eng:Wireless Broadband Alliance'");
3022 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3023 					     "'eng:Free service for test purpose'");
3024 			hs20_icon_filename = "icon_orange_zxx.png";
3025 			if (dut->ap_osu_icon_tag == 2)
3026 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3027 
3028 			snprintf(hs20_icon, sizeof(hs20_icon),
3029 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3030 				 hs20_icon_filename);
3031 			osu_icon = "icon_orange_zxx.png";
3032 			osu_friendly_name = "'kor:와이어리스 브로드밴드 얼라이언스'";
3033 			break;
3034 		case 3:
3035 		case 103:
3036 			osu_friendly_name = "'spa:SP Red Test Only'";
3037 			osu_service_desc = "'spa:Free service for test purpose'";
3038 			break;
3039 		case 4:
3040 		case 104:
3041 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3042 					     "'eng:SP Orange Test Only'");
3043 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3044 					     "'eng:Free service for test purpose'");
3045 			hs20_icon_filename = "icon_orange_eng.png";
3046 			if (dut->ap_osu_icon_tag == 2)
3047 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3048 
3049 			snprintf(hs20_icon, sizeof(hs20_icon),
3050 				 "'160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s'",
3051 				 hs20_icon_filename);
3052 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3053 					     hs20_icon);
3054 			osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3055 
3056 			hs20_icon_filename = "icon_orange_zxx.png";
3057 			if (dut->ap_osu_icon_tag == 2)
3058 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3059 
3060 			snprintf(hs20_icon, sizeof(hs20_icon),
3061 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3062 				 hs20_icon_filename);
3063 			osu_icon = "icon_orange_zxx.png";
3064 			break;
3065 		case 5:
3066 		case 105:
3067 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3068 					     "'eng:SP Orange Test Only'");
3069 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3070 					     "'eng:Free service for test purpose'");
3071 			osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3072 
3073 			hs20_icon_filename = "icon_orange_zxx.png";
3074 			if (dut->ap_osu_icon_tag == 2)
3075 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3076 
3077 			snprintf(hs20_icon, sizeof(hs20_icon),
3078 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3079 				 hs20_icon_filename);
3080 			osu_icon = "icon_orange_zxx.png";
3081 			break;
3082 		case 6:
3083 		case 106:
3084 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3085 					     "'eng:SP Green Test Only'");
3086 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3087 					     "'kor:SP 초록 테스트 전용'");
3088 
3089 			hs20_icon_filename = "icon_green_zxx.png";
3090 			if (dut->ap_osu_icon_tag == 2)
3091 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3092 
3093 			snprintf(hs20_icon, sizeof(hs20_icon),
3094 				 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'",
3095 				 hs20_icon_filename);
3096 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3097 					     hs20_icon);
3098 
3099 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3100 					     "'icon_green_zxx.png'");
3101 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 :
3102 				dut->ap_osu_method[0];
3103 
3104 			snprintf(buf, sizeof(buf), "%d", osu_method);
3105 			owrt_ap_set_vap(dut, vap_id, "osu_method_list", buf);
3106 
3107 			if (strlen(dut->ap_osu_server_uri[1]))
3108 				owrt_ap_set_list_vap(dut, vap_id,
3109 						     "osu_server_uri",
3110 						     dut->ap_osu_server_uri[1]);
3111 			else
3112 				owrt_ap_set_list_vap(dut, vap_id,
3113 						     "osu_server_uri",
3114 						     "'https://osu-server.r2-testbed.wi-fi.org/'");
3115 
3116 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3117 					     "'eng:SP Orange Test Only'");
3118 
3119 			hs20_icon_filename = "icon_orange_zxx.png";
3120 			if (dut->ap_osu_icon_tag == 2)
3121 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3122 
3123 			snprintf(hs20_icon, sizeof(hs20_icon),
3124 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3125 				 hs20_icon_filename);
3126 
3127 			osu_icon = "icon_orange_zxx.png";
3128 			osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3129 			osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 :
3130 				dut->ap_osu_method[1];
3131 			osu_service_desc = NULL;
3132 			break;
3133 		case 7:
3134 		case 107:
3135 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3136 					     "'eng:SP Green Test Only'");
3137 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3138 					     "'eng:Free service for test purpose'");
3139 
3140 			hs20_icon_filename = "icon_green_eng.png";
3141 			if (dut->ap_osu_icon_tag == 2)
3142 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3143 
3144 			snprintf(hs20_icon, sizeof(hs20_icon),
3145 				 "'160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s'",
3146 				 hs20_icon_filename);
3147 			owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3148 					     hs20_icon);
3149 
3150 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3151 					     "'icon_green_eng.png'");
3152 			osu_friendly_name = "'kor:SP 초록 테스트 전용'";
3153 
3154 			hs20_icon_filename = "icon_green_zxx.png";
3155 			if (dut->ap_osu_icon_tag == 2)
3156 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3157 
3158 			snprintf(hs20_icon, sizeof(hs20_icon),
3159 				 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'",
3160 				 hs20_icon_filename);
3161 			osu_icon = "icon_green_zxx.png";
3162 			break;
3163 		case 8:
3164 		case 108:
3165 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3166 					     "'eng:SP Red Test Only'");
3167 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3168 					     "'eng:Free service for test purpose'");
3169 			osu_ssid = "OSU-Encrypted";
3170 			osu_nai = "'anonymous@hotspot.net'";
3171 			break;
3172 		case 9:
3173 		case 109:
3174 			osu_ssid = "OSU-OSEN";
3175 			osu_nai = "'test-anonymous@wi-fi.org'";
3176 			osu_friendly_name = "'eng:SP Orange Test Only'";
3177 			hs20_icon_filename = "icon_orange_zxx.png";
3178 			if (dut->ap_osu_icon_tag == 2)
3179 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3180 
3181 			snprintf(hs20_icon, sizeof(hs20_icon),
3182 				 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3183 				 hs20_icon_filename);
3184 			osu_icon = "icon_orange_zxx.png";
3185 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 :
3186 				dut->ap_osu_method[0];
3187 			osu_service_desc = NULL;
3188 			break;
3189 		default:
3190 			break;
3191 		}
3192 
3193 		if (strlen(dut->ap_osu_ssid)) {
3194 			if (dut->ap_tag_ssid[0][0] &&
3195 			    strcmp(dut->ap_tag_ssid[0],
3196 				   dut->ap_osu_ssid) != 0 &&
3197 			    strcmp(dut->ap_tag_ssid[0], osu_ssid) != 0) {
3198 				sigma_dut_print(dut, DUT_MSG_ERROR,
3199 						"OSU_SSID and WLAN_TAG2 SSID differ");
3200 				return -2;
3201 			}
3202 
3203 			snprintf(buf, sizeof(buf), "'\"%s\"'",
3204 				 dut->ap_osu_ssid);
3205 		} else {
3206 			snprintf(buf, sizeof(buf), "'\"%s\"'", osu_ssid);
3207 		}
3208 
3209 		owrt_ap_set_vap(dut, vap_id, "osu_ssid", buf);
3210 
3211 
3212 		if (osu_friendly_name)
3213 			owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3214 					     osu_friendly_name);
3215 		if (osu_service_desc)
3216 			owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3217 					     osu_service_desc);
3218 		if (osu_nai)
3219 			owrt_ap_set_vap(dut, vap_id, "osu_nai", osu_nai);
3220 
3221 		owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", hs20_icon);
3222 
3223 		if (osu_icon)
3224 			owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3225 					     osu_icon);
3226 
3227 		if (dut->ap_osu_provider_list > 100) {
3228 			owrt_ap_set_list_vap(dut, vap_id, "osu_method_list",
3229 					     "0");
3230 		} else {
3231 			snprintf(buf, sizeof(buf), "%d", osu_method);
3232 			owrt_ap_set_list_vap(dut, vap_id, "osu_method_list",
3233 					     buf);
3234 		}
3235 	}
3236 
3237 	return 0;
3238 }
3239 
3240 
3241 static int set_anqp_elem_value(struct sigma_dut *dut, const char *ifname,
3242 			       char *anqp_string, size_t str_size)
3243 {
3244 	unsigned char bssid[ETH_ALEN];
3245 	unsigned char dummy_mac[] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50 };
3246 	int preference = 0xff;
3247 
3248 	if (get_hwaddr(ifname, bssid) < 0)
3249 		return -1;
3250 	snprintf(anqp_string, str_size,
3251 		 "272:3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x",
3252 		 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5],
3253 		 preference,
3254 		 dummy_mac[0], dummy_mac[1], dummy_mac[2],
3255 		 dummy_mac[3], dummy_mac[4], dummy_mac[5],
3256 		 preference - 1);
3257 	return 0;
3258 }
3259 
3260 
3261 static const char * get_hostapd_ifname(struct sigma_dut *dut)
3262 {
3263 	enum driver_type drv;
3264 
3265 	/* Use the configured hostapd ifname */
3266 	if (dut->hostapd_ifname && if_nametoindex(dut->hostapd_ifname) > 0)
3267 		return dut->hostapd_ifname;
3268 
3269 	/* Use configured main ifname */
3270 	if (dut->main_ifname) {
3271 		if (dut->use_5g && dut->main_ifname_5g &&
3272 		    if_nametoindex(dut->main_ifname_5g) > 0)
3273 			return dut->main_ifname_5g;
3274 		if (!dut->use_5g && dut->main_ifname_2g &&
3275 		    if_nametoindex(dut->main_ifname_2g) > 0)
3276 			return dut->main_ifname_2g;
3277 		if (if_nametoindex(dut->main_ifname) > 0)
3278 			return dut->main_ifname;
3279 	}
3280 
3281 	/* Return based on driver type (indirectly started hostapd) */
3282 	drv = get_driver_type(dut);
3283 	if (drv == DRIVER_ATHEROS) {
3284 		if (dut->use_5g && if_nametoindex("ath1") > 0)
3285 			return "ath1";
3286 		return "ath0";
3287 	}
3288 
3289 	if (drv == DRIVER_OPENWRT) {
3290 		if (sigma_radio_ifname[0] &&
3291 		    strcmp(sigma_radio_ifname[0], "wifi2") == 0)
3292 			return "ath2";
3293 		if (sigma_radio_ifname[0] &&
3294 		    strcmp(sigma_radio_ifname[0], "wifi1") == 0)
3295 			return "ath1";
3296 		return "ath0";
3297 	}
3298 
3299 	/* wlan1-is-likely-5-GHz design */
3300 	if (dut->use_5g && if_nametoindex("wlan1") > 0)
3301 		return "wlan1";
3302 
3303 	/* If nothing else matches, hope for the best and guess this is wlan0 */
3304 	return "wlan0";
3305 }
3306 
3307 
3308 static void get_if_name(struct sigma_dut *dut, char *ifname_str,
3309 			size_t str_size, int wlan_tag)
3310 {
3311 	const char *ifname;
3312 	enum driver_type drv;
3313 
3314 	ifname = get_hostapd_ifname(dut);
3315 	drv = get_driver_type(dut);
3316 
3317 	if (drv == DRIVER_OPENWRT && wlan_tag > 1) {
3318 		/* Handle tagged-ifname only on OPENWRT for now */
3319 		snprintf(ifname_str, str_size, "%s%d", ifname, wlan_tag - 1);
3320 	} else if ((drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN) &&
3321 		   wlan_tag == 2) {
3322 		snprintf(ifname_str, str_size, "%s_1", ifname);
3323 	} else {
3324 		snprintf(ifname_str, str_size, "%s", ifname);
3325 	}
3326 }
3327 
3328 
3329 static int sae_pw_id_used(struct sigma_dut *dut)
3330 {
3331 	return dut->ap_sae_passwords &&
3332 		strchr(dut->ap_sae_passwords, ':');
3333 }
3334 
3335 
3336 static int owrt_ap_config_vap(struct sigma_dut *dut)
3337 {
3338 	char buf[256], *temp;
3339 	int vap_id = 0, vap_count, i, j, res;
3340 	const char *ifname;
3341 	char ifname2[50];
3342 
3343 	if (sigma_radio_ifname[0] &&
3344 	    strcmp(sigma_radio_ifname[0], "wifi2") == 0)
3345 		ifname = "ath2";
3346 	else if (sigma_radio_ifname[0] &&
3347 		 strcmp(sigma_radio_ifname[0], "wifi1") == 0)
3348 		ifname = "ath1";
3349 	else
3350 		ifname = "ath0";
3351 
3352 	for (vap_count = 0; vap_count < OPENWRT_MAX_NUM_RADIOS; vap_count++) {
3353 		snprintf(buf, sizeof(buf), "wifi%d", vap_count);
3354 
3355 		for (vap_id = 0; vap_id < MAX_RADIO; vap_id++) {
3356 			if (sigma_radio_ifname[vap_id] &&
3357 			    strcmp(sigma_radio_ifname[vap_id], buf) == 0)
3358 				break;
3359 		}
3360 		if (vap_id == MAX_RADIO)
3361 			continue;
3362 
3363 		/* Single VAP configuration */
3364 		if (!dut->ap_is_dual)
3365 			vap_id = vap_count;
3366 
3367 		for (j = 0; j < MAX_WLAN_TAGS - 1; j++) {
3368 			/*
3369 			 * We keep a separate array of ap_tag_ssid and
3370 			 * ap_tag_key_mgmt for tags starting from WLAN_TAG=2.
3371 			 * So j=0 => WLAN_TAG = 2
3372 			 */
3373 			int wlan_tag = j + 2;
3374 
3375 			if (wlan_tag == 2 && dut->program == PROGRAM_WPA3 &&
3376 			   (dut->ap_interface_5g || dut->ap_interface_2g)) {
3377 				res = snprintf(
3378 					dut->ap_tag_ssid[wlan_tag - 2],
3379 					sizeof(dut->ap_tag_ssid[wlan_tag - 2]),
3380 					"%s-owe", dut->ap_ssid);
3381 				if (res < 0 ||
3382 				    res >= sizeof(dut->ap_tag_ssid[wlan_tag -
3383 								   2]))
3384 					dut->ap_tag_ssid[wlan_tag - 2][0] =
3385 						'\0';
3386 			}
3387 
3388 			if (dut->ap_tag_ssid[j][0] == '\0')
3389 				continue;
3390 
3391 			snprintf(buf, sizeof(buf), "%s%d", "wifi", vap_count);
3392 			owrt_ap_add_vap(dut, vap_count + (wlan_tag - 1),
3393 					"device", buf);
3394 			/* SSID */
3395 			snprintf(buf, sizeof(buf), "\"%s\"",
3396 				 dut->ap_tag_ssid[j]);
3397 			owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3398 					"ssid", buf);
3399 
3400 			if (dut->ap_key_mgmt == AP_WPA2_OWE &&
3401 			    dut->ap_tag_ssid[0][0] &&
3402 			    dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
3403 				/* OWE transition mode */
3404 				snprintf(buf, sizeof(buf), "%s", ifname);
3405 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3406 						"owe_transition_ifname", buf);
3407 			}
3408 
3409 			if (dut->ap_key_mgmt == AP_OPEN &&
3410 			    dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3411 				/* OWE transition mode */
3412 				snprintf(buf, sizeof(buf), "%s", ifname);
3413 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3414 						"owe_transition_ifname", buf);
3415 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3416 						"hidden", "1");
3417 			}
3418 
3419 			if (ap_ft_enabled(dut)) {
3420 				unsigned char self_mac[ETH_ALEN];
3421 				char mac_str[20];
3422 
3423 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3424 						"mobility_domain",
3425 						dut->ap_mobility_domain);
3426 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3427 						"ft_over_ds",
3428 						dut->ap_ft_ds == VALUE_ENABLED ?
3429 						"1" : "0");
3430 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3431 						"ieee80211r", "1");
3432 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3433 						"nasid", "nas1.example.com");
3434 				if (get_hwaddr(sigma_radio_ifname[0],
3435 					       self_mac) < 0)
3436 					return -1;
3437 				snprintf(mac_str, sizeof(mac_str),
3438 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3439 					 self_mac[0], self_mac[1], self_mac[2],
3440 					 self_mac[3], self_mac[4], self_mac[5]);
3441 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3442 						"ap_macaddr", mac_str);
3443 				snprintf(mac_str, sizeof(mac_str),
3444 					 "%02x%02x%02x%02x%02x%02x",
3445 					 self_mac[0], self_mac[1], self_mac[2],
3446 					 self_mac[3], self_mac[4], self_mac[5]);
3447 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3448 						"r1_key_holder", mac_str);
3449 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3450 						"ft_psk_generate_local", "1");
3451 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3452 						"kh_key_hex",
3453 						"000102030405060708090a0b0c0d0e0f");
3454 				snprintf(mac_str, sizeof(mac_str),
3455 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3456 					 dut->ft_bss_mac_list[0][0],
3457 					 dut->ft_bss_mac_list[0][1],
3458 					 dut->ft_bss_mac_list[0][2],
3459 					 dut->ft_bss_mac_list[0][3],
3460 					 dut->ft_bss_mac_list[0][4],
3461 					 dut->ft_bss_mac_list[0][5]);
3462 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3463 						"ap2_macaddr", mac_str);
3464 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3465 						"ap2_r1_key_holder", mac_str);
3466 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3467 						"nasid2", "nas2.example.com");
3468 			}
3469 
3470 			if (dut->ap_tag_key_mgmt[j] == AP2_OSEN &&
3471 			    wlan_tag == 2) {
3472 				/* Only supported for WLAN_TAG=2 */
3473 				owrt_ap_set_vap(dut, vap_count + 1, "osen",
3474 						"1");
3475 				snprintf(buf, sizeof(buf), "wpa2");
3476 				owrt_ap_set_vap(dut, vap_count + 1,
3477 						"encryption", buf);
3478 				snprintf(buf, sizeof(buf), "%s",
3479 					 dut->ap2_radius_ipaddr);
3480 				owrt_ap_set_vap(dut, vap_count + 1,
3481 						"auth_server", buf);
3482 				snprintf(buf, sizeof(buf), "%d",
3483 					 dut->ap2_radius_port);
3484 				owrt_ap_set_vap(dut, vap_count + 1,
3485 						"auth_port", buf);
3486 				snprintf(buf, sizeof(buf), "%s",
3487 					 dut->ap2_radius_password);
3488 				owrt_ap_set_vap(dut, vap_count + 1,
3489 						"auth_secret", buf);
3490 			} else if (dut->ap_tag_key_mgmt[j] == AP2_WPA2_PSK) {
3491 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3492 						"encryption", "psk2+ccmp");
3493 				snprintf(buf, sizeof(buf), "\"%s\"",
3494 					 dut->ap_passphrase);
3495 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3496 						"key", buf);
3497 				snprintf(buf, sizeof(buf), "%d", dut->ap_pmf);
3498 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3499 						"ieee80211w", buf);
3500 			} else if (dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3501 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3502 						"owe", "1");
3503 				snprintf(buf, sizeof(buf), "ccmp");
3504 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3505 						"encryption", buf);
3506 				owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3507 						"ieee80211w", "2");
3508 				if (dut->ap_sae_groups) {
3509 					snprintf(buf, sizeof(buf), "\'%s\'",
3510 						 dut->ap_sae_groups);
3511 					owrt_ap_set_list_vap(dut, vap_count +
3512 							     (wlan_tag - 1),
3513 							     "owe_groups", buf);
3514 					if (dut->owe_ptk_workaround)
3515 						owrt_ap_set_list_vap(
3516 							dut, vap_count +
3517 							(wlan_tag - 1),
3518 							"owe_ptk_workaround",
3519 							"1");
3520 				}
3521 			}
3522 		}
3523 
3524 		/* Now set anqp_elem and ft_oa for wlan_tag = 1 */
3525 		if (dut->program == PROGRAM_MBO &&
3526 		    get_driver_type(dut) == DRIVER_OPENWRT) {
3527 			unsigned char self_mac[ETH_ALEN];
3528 			char mac_str[20];
3529 			char anqp_string[200];
3530 
3531 			if (set_anqp_elem_value(dut, sigma_radio_ifname[0],
3532 						anqp_string,
3533 						sizeof(anqp_string)) < 0)
3534 				return -1;
3535 			owrt_ap_set_list_vap(dut, vap_count, "anqp_elem",
3536 					     anqp_string);
3537 
3538 			if (ap_ft_enabled(dut)) {
3539 				owrt_ap_set_vap(dut, vap_count,
3540 						"mobility_domain",
3541 						dut->ap_mobility_domain);
3542 				owrt_ap_set_vap(dut, vap_count,
3543 						"ft_over_ds",
3544 						dut->ap_ft_ds == VALUE_ENABLED ?
3545 						"1" : "0");
3546 				owrt_ap_set_vap(dut, vap_count,
3547 						"ieee80211r", "1");
3548 				owrt_ap_set_vap(dut, vap_count,
3549 						"nasid", "nas1.example.com");
3550 				get_hwaddr(sigma_radio_ifname[0], self_mac);
3551 				snprintf(mac_str, sizeof(mac_str),
3552 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3553 					 self_mac[0], self_mac[1], self_mac[2],
3554 					 self_mac[3], self_mac[4], self_mac[5]);
3555 				owrt_ap_set_vap(dut, vap_count,
3556 						"ap_macaddr", mac_str);
3557 				snprintf(mac_str, sizeof(mac_str),
3558 					 "%02x%02x%02x%02x%02x%02x",
3559 					 self_mac[0], self_mac[1], self_mac[2],
3560 					 self_mac[3], self_mac[4], self_mac[5]);
3561 				owrt_ap_set_vap(dut, vap_count,
3562 						"r1_key_holder", mac_str);
3563 				owrt_ap_set_vap(dut, vap_count,
3564 						"ft_psk_generate_local", "1");
3565 				owrt_ap_set_vap(dut, vap_count,
3566 						"kh_key_hex",
3567 						"000102030405060708090a0b0c0d0e0f");
3568 				snprintf(mac_str, sizeof(mac_str),
3569 					 "%02x:%02x:%02x:%02x:%02x:%02x",
3570 					 dut->ft_bss_mac_list[0][0],
3571 					 dut->ft_bss_mac_list[0][1],
3572 					 dut->ft_bss_mac_list[0][2],
3573 					 dut->ft_bss_mac_list[0][3],
3574 					 dut->ft_bss_mac_list[0][4],
3575 					 dut->ft_bss_mac_list[0][5]);
3576 				owrt_ap_set_vap(dut, vap_count,
3577 						"ap2_macaddr", mac_str);
3578 				owrt_ap_set_vap(dut, vap_count,
3579 						"ap2_r1_key_holder", mac_str);
3580 				owrt_ap_set_vap(dut, vap_count,
3581 						"nasid2", "nas2.example.com");
3582 			}
3583 		}
3584 
3585 		if (dut->ap_oce == VALUE_ENABLED &&
3586 		    get_driver_type(dut) == DRIVER_OPENWRT) {
3587 			owrt_ap_set_vap(dut, vap_id, "oce", "1");
3588 			owrt_ap_set_vap(dut, vap_id, "qbssload", "1");
3589 			owrt_ap_set_vap(dut, vap_id, "bpr_enable", "1");
3590 
3591 			if (dut->ap_80plus80 == 1)
3592 				owrt_ap_set_vap(dut, vap_id, "cfreq2", "5775");
3593 
3594 			if (dut->ap_akm == 1) {
3595 				owrt_ap_set_vap(dut, vap_id, "wpa_group_rekey",
3596 						"3600");
3597 				owrt_ap_set_vap(dut, vap_id, "key", "12345678");
3598 				owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3599 						"1");
3600 				owrt_ap_set_vap(dut, vap_id, "fils_cache_id",
3601 						"1234");
3602 				owrt_ap_set_vap(dut, vap_id,
3603 						"erp_send_reauth_start", "1");
3604 			}
3605 
3606 			if (dut->ap_filshlp == VALUE_ENABLED) {
3607 				struct ifreq ifr;
3608 				char *ifname;
3609 				int s;
3610 				struct sockaddr_in *ipaddr;
3611 
3612 				s = socket(AF_INET, SOCK_DGRAM, 0);
3613 				if (s < 0) {
3614 					sigma_dut_print(dut, DUT_MSG_ERROR,
3615 							"Failed to open socket");
3616 					return -1;
3617 				}
3618 				ifr.ifr_addr.sa_family = AF_INET;
3619 
3620 				memset(&ifr, 0, sizeof(ifr));
3621 				ifname = "br-lan";
3622 				strlcpy(ifr.ifr_name, ifname,
3623 					sizeof(ifr.ifr_name));
3624 				if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
3625 					perror("ioctl");
3626 					close(s);
3627 					return -1;
3628 				}
3629 
3630 				ipaddr = (struct sockaddr_in*)&ifr.ifr_addr;
3631 				snprintf(buf, sizeof(buf), "%s",
3632 					 inet_ntoa(ipaddr->sin_addr));
3633 				owrt_ap_set_vap(dut, vap_id, "own_ip_addr",
3634 						buf);
3635 				snprintf(buf, sizeof(buf), "%s",
3636 					 dut->ap_dhcpserv_ipaddr);
3637 				owrt_ap_set_vap(dut, vap_id, "dhcp_server",
3638 						buf);
3639 				owrt_ap_set_vap(dut, vap_id,
3640 						"dhcp_rapid_commit_proxy", "1");
3641 				owrt_ap_set_vap(dut, vap_id,
3642 						"fils_hlp_wait_time", "300");
3643 			}
3644 
3645 			if (dut->ap_filsdscv == VALUE_ENABLED) {
3646 				owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3647 						"1");
3648 				owrt_ap_set_vap(dut, vap_id, "fils_fd_period",
3649 						"20");
3650 			}
3651 		}
3652 
3653 		if (dut->ap_filsdscv == VALUE_DISABLED) {
3654 			owrt_ap_set_vap(dut, vap_id, "ieee80211ai", "0");
3655 			owrt_ap_set_vap(dut, vap_id, "fils_fd_period", "0");
3656 		}
3657 
3658 		if (dut->ap_oce == VALUE_DISABLED &&
3659 		    get_driver_type(dut) == DRIVER_OPENWRT) {
3660 			owrt_ap_set_vap(dut, vap_id, "oce", "0");
3661 			owrt_ap_set_vap(dut, vap_id, "qbssload", "0");
3662 			owrt_ap_set_vap(dut, vap_id, "bpr_enable", "0");
3663 
3664 			if (dut->ap_filsdscv == VALUE_DISABLED) {
3665 				owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3666 						"0");
3667 				owrt_ap_set_vap(dut, vap_id, "fils_fd_period",
3668 						"0");
3669 			}
3670 
3671 			if (dut->device_type == AP_testbed)
3672 				owrt_ap_set_vap(dut, vap_id, "mbo", "1");
3673 		}
3674 
3675 		/* NAIRealm */
3676 		if (dut->ap_nairealm_int == 1) {
3677 			snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_nairealm);
3678 			owrt_ap_set_vap(dut, vap_id, "fils_realm", buf);
3679 			owrt_ap_set_vap(dut, vap_id, "erp_domain", buf);
3680 		}
3681 
3682 		/* SSID */
3683 		snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_ssid);
3684 		owrt_ap_set_vap(dut, vap_count, "ssid", buf);
3685 
3686 		/* Encryption */
3687 		switch (dut->ap_key_mgmt) {
3688 		case AP_OPEN:
3689 			if (dut->ap_cipher == AP_WEP) {
3690 				owrt_ap_set_vap(dut, vap_count, "encryption",
3691 						"wep-mixed");
3692 				owrt_ap_set_vap(dut, vap_count, "key",
3693 						dut->ap_wepkey);
3694 			} else {
3695 				owrt_ap_set_vap(dut, vap_count, "encryption",
3696 						"none");
3697 			}
3698 			if (dut->ap_key_mgmt == AP_OPEN &&
3699 			    dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3700 				/* OWE transition mode */
3701 				snprintf(ifname2, sizeof(ifname2), "%s1",
3702 					 ifname);
3703 				owrt_ap_set_vap(dut, vap_count,
3704 						"owe_transition_ifname",
3705 						ifname2);
3706 			}
3707 			break;
3708 		case AP_WPA2_PSK:
3709 		case AP_WPA2_PSK_MIXED:
3710 		case AP_WPA_PSK:
3711 		case AP_WPA2_SAE:
3712 		case AP_WPA2_PSK_SAE:
3713 			if (dut->ap_key_mgmt == AP_WPA2_PSK ||
3714 			    dut->ap_key_mgmt == AP_WPA2_PSK_SAE) {
3715 				snprintf(buf, sizeof(buf), "psk2");
3716 			} else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) {
3717 				snprintf(buf, sizeof(buf), "psk-mixed");
3718 			} else if (dut->ap_key_mgmt == AP_WPA2_SAE) {
3719 				snprintf(buf, sizeof(buf), "ccmp");
3720 			} else {
3721 				snprintf(buf, sizeof(buf), "psk");
3722 			}
3723 
3724 			if (dut->ap_key_mgmt != AP_WPA2_SAE) {
3725 				if (dut->ap_cipher == AP_CCMP_TKIP)
3726 					strlcat(buf, "+ccmp+tkip", sizeof(buf));
3727 				else if (dut->ap_cipher == AP_TKIP)
3728 					strlcat(buf, "+tkip", sizeof(buf));
3729 				else if (dut->ap_cipher == AP_GCMP_128)
3730 					strlcat(buf, "+gcmp", sizeof(buf));
3731 				else
3732 					strlcat(buf, "+ccmp", sizeof(buf));
3733 			}
3734 
3735 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3736 
3737 			if (!dut->ap_passphrase[0] && dut->ap_psk[0]) {
3738 				snprintf(buf, sizeof(buf), "\"%s\"",
3739 					 dut->ap_psk);
3740 				owrt_ap_set_vap(dut, vap_count, "key", buf);
3741 			} else {
3742 				snprintf(buf, sizeof(buf), "\"%s\"",
3743 					 dut->ap_passphrase);
3744 				owrt_ap_set_vap(dut, vap_count, "key", buf);
3745 			}
3746 
3747 			if (dut->ap_key_mgmt == AP_WPA2_SAE ||
3748 			    dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
3749 				owrt_ap_set_vap(dut, vap_count, "sae", "1");
3750 			else
3751 				owrt_ap_set_vap(dut, vap_count, "sae", "0");
3752 
3753 			if (dut->ap_key_mgmt == AP_WPA2_SAE) {
3754 				snprintf(buf, sizeof(buf), "%s",
3755 					 dut->ap_passphrase);
3756 				owrt_ap_set_vap(dut, vap_count, "sae_password",
3757 						buf);
3758 			} else {
3759 				snprintf(buf, sizeof(buf), "%s",
3760 					 dut->ap_passphrase);
3761 				owrt_ap_set_vap(dut, vap_count,
3762 						"wpa_passphrase", buf);
3763 			}
3764 			break;
3765 		case AP_WPA2_EAP:
3766 		case AP_WPA2_EAP_MIXED:
3767 		case AP_WPA_EAP:
3768 			if (dut->ap_key_mgmt == AP_WPA2_EAP) {
3769 				snprintf(buf, sizeof(buf), "wpa2");
3770 			} else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) {
3771 				snprintf(buf, sizeof(buf), "wpa-mixed");
3772 			} else {
3773 				snprintf(buf, sizeof(buf), "wpa");
3774 			}
3775 
3776 			if (dut->ap_cipher == AP_CCMP_TKIP)
3777 				strlcat(buf, "+ccmp+tkip", sizeof(buf));
3778 			else if (dut->ap_cipher == AP_TKIP)
3779 				strlcat(buf, "+tkip", sizeof(buf));
3780 			else
3781 				strlcat(buf, "+ccmp", sizeof(buf));
3782 
3783 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3784 			snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr);
3785 			owrt_ap_set_vap(dut, vap_count, "auth_server", buf);
3786 			snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port);
3787 			owrt_ap_set_vap(dut, vap_count, "auth_port", buf);
3788 			snprintf(buf, sizeof(buf), "%s",
3789 				 dut->ap_radius_password);
3790 			owrt_ap_set_vap(dut, vap_count, "auth_secret", buf);
3791 			break;
3792 		case AP_WPA2_EAP_OSEN:
3793 		case AP_OSEN:
3794 		case AP_WPA2_FT_EAP:
3795 		case AP_WPA2_FT_PSK:
3796 		case AP_WPA2_EAP_SHA256:
3797 		case AP_WPA2_PSK_SHA256:
3798 		case AP_WPA2_ENT_FT_EAP:
3799 			/* TODO */
3800 			break;
3801 		case AP_SUITEB:
3802 			owrt_ap_set_vap(dut, vap_count, "suite_b", "192");
3803 			snprintf(buf, sizeof(buf), "gcmp");
3804 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3805 			snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr);
3806 			owrt_ap_set_vap(dut, vap_count, "auth_server", buf);
3807 			snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port);
3808 			owrt_ap_set_vap(dut, vap_count, "auth_port", buf);
3809 			snprintf(buf, sizeof(buf), "%s",
3810 				 dut->ap_radius_password);
3811 			owrt_ap_set_vap(dut, vap_count, "auth_secret", buf);
3812 			snprintf(buf, sizeof(buf), "%d",
3813 				 dut->ap_group_mgmt_cipher);
3814 			owrt_ap_set_vap(dut, vap_count, "group_mgmt_cipher",
3815 					buf);
3816 			break;
3817 		case AP_WPA2_OWE:
3818 			owrt_ap_set_vap(dut, vap_count, "owe", "1");
3819 			snprintf(buf, sizeof(buf), "ccmp");
3820 			owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3821 			if (dut->ap_sae_groups) {
3822 				snprintf(buf, sizeof(buf), "\'%s\'",
3823 					 dut->ap_sae_groups);
3824 				owrt_ap_set_list_vap(dut, vap_count,
3825 						     "owe_groups", buf);
3826 				if (dut->owe_ptk_workaround)
3827 					owrt_ap_set_list_vap(
3828 						dut, vap_count,
3829 						"owe_ptk_workaround", "1");
3830 			}
3831 
3832 			if (dut->ap_key_mgmt == AP_WPA2_OWE &&
3833 			    dut->ap_tag_ssid[0][0] &&
3834 			    dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
3835 				/* OWE transition mode */
3836 				snprintf(ifname2, sizeof(ifname2), "%s1",
3837 					 ifname);
3838 				owrt_ap_set_vap(dut, vap_count,
3839 						"owe_transition_ifname",
3840 						ifname2);
3841 				owrt_ap_set_vap(dut, vap_count, "hidden", "1");
3842 			}
3843 			break;
3844 		}
3845 
3846 		if (!dut->ap_is_dual)
3847 			break;
3848 	}
3849 
3850 	if (dut->ap_is_dual)
3851 		return 1;
3852 
3853 	/* PMF */
3854 	snprintf(buf, sizeof(buf), "%d", dut->ap_pmf);
3855 	owrt_ap_set_vap(dut, vap_id, "ieee80211w", buf);
3856 
3857 	/* Add SHA256 */
3858 	snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha256);
3859 	owrt_ap_set_vap(dut, vap_id, "add_sha256", buf);
3860 
3861 	/* Add SHA384 for akmsuitetype 15 */
3862 	if (dut->ap_akm == 1) {
3863 		snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha384);
3864 		owrt_ap_set_vap(dut, vap_id, "add_sha384", buf);
3865 	}
3866 
3867 	/* Enable RSN preauthentication, if asked to */
3868 	snprintf(buf, sizeof(buf), "%d", dut->ap_rsn_preauth);
3869 	owrt_ap_set_vap(dut, vap_id, "rsn_preauth", buf);
3870 
3871 	/* Hotspot 2.0 */
3872 	if (dut->ap_hs2) {
3873 		int ret;
3874 
3875 		ret = owrt_ap_config_vap_hs2(dut, vap_id);
3876 		if (ret)
3877 			return ret;
3878 	}
3879 
3880 	/* Interworking */
3881 	if (dut->ap_interworking) {
3882 		snprintf(buf, sizeof(buf), "%d", dut->ap_access_net_type);
3883 		owrt_ap_set_vap(dut, vap_id, "access_network_type", buf);
3884 		snprintf(buf, sizeof(buf), "%d", dut->ap_internet);
3885 		owrt_ap_set_vap(dut, vap_id, "internet", buf);
3886 		snprintf(buf, sizeof(buf), "%d", dut->ap_venue_group);
3887 		owrt_ap_set_vap(dut, vap_id, "venue_group", buf);
3888 		snprintf(buf, sizeof(buf), "%d", dut->ap_venue_type);
3889 		owrt_ap_set_vap(dut, vap_id, "venue_type", buf);
3890 		snprintf(buf, sizeof(buf), "%s", dut->ap_hessid);
3891 		owrt_ap_set_vap(dut, vap_id, "hessid", buf);
3892 
3893 		if (dut->ap_gas_cb_delay > 0) {
3894 			snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay);
3895 			owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf);
3896 		}
3897 
3898 		if (dut->ap_roaming_cons[0]) {
3899 			char *rcons, *temp_ptr;
3900 
3901 			rcons = strdup(dut->ap_roaming_cons);
3902 			if (rcons == NULL)
3903 				return -1;
3904 
3905 			temp_ptr = strchr(rcons, ';');
3906 
3907 			if (temp_ptr)
3908 				*temp_ptr++ = '\0';
3909 
3910 			owrt_ap_set_list_vap(dut, vap_id, "roaming_consortium",
3911 					     rcons);
3912 
3913 			if (temp_ptr)
3914 				owrt_ap_set_list_vap(dut, vap_id,
3915 						     "roaming_consortium",
3916 						     temp_ptr);
3917 
3918 			free(rcons);
3919 		}
3920 	}
3921 
3922 	if (dut->ap_venue_name) {
3923 		owrt_ap_set_list_vap(dut, vap_id, "venue_name",
3924 				     "'P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"'");
3925 		owrt_ap_set_list_vap(dut, vap_id, "venue_name",
3926 				     "\'"ANQP_VENUE_NAME_1_CHI"\'");
3927 	}
3928 
3929 	if (dut->ap_net_auth_type == 1) {
3930 		owrt_ap_set_list_vap(dut, vap_id, "network_auth_type",
3931 				     "'00https://tandc-server.wi-fi.org'");
3932 	} else if (dut->ap_net_auth_type == 2) {
3933 		owrt_ap_set_list_vap(dut, vap_id, "network_auth_type", "'01'");
3934 	}
3935 
3936 	if (dut->ap_nai_realm_list == 1) {
3937 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3938 				     "'0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]'");
3939 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3940 				     "'0,wi-fi.org;example.com,13[5:6]'");
3941 
3942 	} else if (dut->ap_nai_realm_list == 2) {
3943 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3944 				     "'0,wi-fi.org,21[2:4][5:7]'");
3945 	} else if (dut->ap_nai_realm_list == 3) {
3946 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3947 				     "'0,cisco.com;wi-fi.org,21[2:4][5:7]'");
3948 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3949 				     "'0,wi-fi.org;example.com,13[5:6]'");
3950 	} else if (dut->ap_nai_realm_list == 4) {
3951 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3952 				     "'0,mail.example.com,21[2:4][5:7],13[5:6]'");
3953 	} else if (dut->ap_nai_realm_list == 5) {
3954 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3955 				     "'0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]'");
3956 	} else if (dut->ap_nai_realm_list == 6) {
3957 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3958 				     "'0,wi-fi.org;mail.example.com,21[2:4][5:7]'");
3959 	} else if (dut->ap_nai_realm_list == 7) {
3960 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3961 				     "'0,wi-fi.org,13[5:6]'");
3962 		owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
3963 				     "'0,wi-fi.org,21[2:4][5:7]'");
3964 	}
3965 
3966 	if (dut->ap_domain_name_list[0])
3967 		owrt_ap_set_list_vap(dut, vap_id, "domain_name",
3968 				     dut->ap_domain_name_list);
3969 
3970 	if (dut->ap_ip_addr_type_avail)
3971 		owrt_ap_set_vap(dut, vap_id, "ipaddr_type_availability",
3972 				"'0c'");
3973 
3974 	temp = buf;
3975 
3976 	*temp++ = '\'';
3977 
3978 	for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) {
3979 		if (i)
3980 			*temp++ = ';';
3981 
3982 		snprintf(temp,
3983 			 sizeof(dut->ap_plmn_mcc[i]) +
3984 			 sizeof(dut->ap_plmn_mnc[i]) + 1,
3985 			 "%s,%s",
3986 			 dut->ap_plmn_mcc[i],
3987 			 dut->ap_plmn_mnc[i]);
3988 
3989 		temp += strlen(dut->ap_plmn_mcc[i]) +
3990 			strlen(dut->ap_plmn_mnc[i]) + 1;
3991 	}
3992 
3993 	*temp++ = '\'';
3994 	*temp++ = '\0';
3995 
3996 	if (i)
3997 		owrt_ap_set_vap(dut, vap_id, "anqp_3gpp_cell_net", buf);
3998 
3999 	if (dut->ap_qos_map_set == 1)
4000 		owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_1);
4001 	else if (dut->ap_qos_map_set == 2)
4002 		owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_2);
4003 
4004 	/* Proxy-ARP */
4005 	snprintf(buf, sizeof(buf), "%d", dut->ap_proxy_arp);
4006 	owrt_ap_set_vap(dut, vap_id, "proxyarp", buf);
4007 
4008 	/* DGAF */
4009 	snprintf(buf, sizeof(buf), "%d", dut->ap_dgaf_disable);
4010 	/* parse to hostapd */
4011 	owrt_ap_set_vap(dut, vap_id, "disable_dgaf", buf);
4012 	/* parse to wifi driver */
4013 	owrt_ap_set_vap(dut, vap_id, "dgaf_disable", buf);
4014 
4015 	/* HCBSSLoad */
4016 	if (dut->ap_bss_load) {
4017 		unsigned int bssload = 0;
4018 
4019 		if (dut->ap_bss_load == 1) {
4020 			/* STA count: 1, CU: 50, AAC: 65535 */
4021 			bssload = 0x0132ffff;
4022 		} else if (dut->ap_bss_load == 2) {
4023 			/* STA count: 1, CU: 200, AAC: 65535 */
4024 			bssload = 0x01c8ffff;
4025 		} else if (dut->ap_bss_load == 3) {
4026 			/* STA count: 1, CU: 75, AAC: 65535 */
4027 			bssload = 0x014bffff;
4028 		}
4029 
4030 		snprintf(buf, sizeof(buf), "%d", bssload);
4031 		owrt_ap_set_vap(dut, vap_id, "hcbssload", buf);
4032 	}
4033 
4034 	/* L2TIF */
4035 	if  (dut->ap_l2tif)
4036 		owrt_ap_set_vap(dut, vap_id, "l2tif", "1");
4037 
4038 	if (dut->ap_disable_protection == 1)
4039 		owrt_ap_set_vap(dut, vap_id, "enablertscts", "0");
4040 
4041 	if (dut->ap_txBF) {
4042 		owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "1");
4043 		owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "1");
4044 		if (dut->program == PROGRAM_HE) {
4045 			owrt_ap_set_vap(dut, vap_id, "he_subfer", "1");
4046 			owrt_ap_set_vap(dut, vap_id, "cwmenable", "0");
4047 		}
4048 	} else {
4049 		owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0");
4050 		owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0");
4051 		if (dut->program == PROGRAM_HE)
4052 			owrt_ap_set_vap(dut, vap_id, "he_subfer", "0");
4053 	}
4054 
4055 	if (dut->ap_mu_txBF) {
4056 		owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "1");
4057 		if (dut->program == PROGRAM_HE) {
4058 			owrt_ap_set_vap(dut, vap_id, "he_mubfer", "1");
4059 			owrt_ap_set_vap(dut, vap_id, "he_mubfee", "1");
4060 		}
4061 	} else {
4062 		owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "0");
4063 		if (dut->program == PROGRAM_HE) {
4064 			owrt_ap_set_vap(dut, vap_id, "he_mubfer", "0");
4065 			owrt_ap_set_vap(dut, vap_id, "he_mubfee", "0");
4066 		}
4067 	}
4068 
4069 	if (dut->ap_tx_stbc) {
4070 		/* STBC and beamforming are mutually exclusive features */
4071 		owrt_ap_set_vap(dut, vap_id, "implicitbf", "0");
4072 	}
4073 
4074 	/* enable dfsmode */
4075 	snprintf(buf, sizeof(buf), "%d", dut->ap_dfs_mode);
4076 	owrt_ap_set_vap(dut, vap_id, "doth", buf);
4077 
4078 	if (dut->program == PROGRAM_LOC && dut->ap_interworking) {
4079 		char anqpval[1024];
4080 
4081 		owrt_ap_set_vap(dut, vap_id, "interworking", "1");
4082 
4083 		if (dut->ap_lci == 1 && strlen(dut->ap_tag_ssid[0]) == 0) {
4084 			snprintf(anqpval, sizeof(anqpval),
4085 				"'265:0010%s%s060101'",
4086 				dut->ap_val_lci, dut->ap_infoz);
4087 			owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4088 		}
4089 
4090 		if (dut->ap_lcr == 1) {
4091 			snprintf(anqpval, sizeof(anqpval),
4092 				"'266:0000b2555302ae%s'",
4093 				dut->ap_val_lcr);
4094 			owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4095 		}
4096 
4097 		if (dut->ap_fqdn_held == 1 && dut->ap_fqdn_supl == 1)
4098 			owrt_ap_set_list_vap(dut, vap_id, "anqp_elem",
4099 					     "'267:00110168656c642e6578616d706c652e636f6d0011027375706c2e6578616d706c652e636f6d'");
4100 	}
4101 
4102 	if (dut->program == PROGRAM_MBO) {
4103 		owrt_ap_set_vap(dut, vap_id, "interworking", "1");
4104 		owrt_ap_set_vap(dut, vap_id, "mbo", "1");
4105 		owrt_ap_set_vap(dut, vap_id, "rrm", "1");
4106 		owrt_ap_set_vap(dut, vap_id, "mbo_cell_conn_pref", "1");
4107 
4108 		owrt_ap_set_list_vap(dut, vap_id, "anqp_elem",
4109 				     "'272:34108cfdf0020df1f7000000733000030101'");
4110 		snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay);
4111 		owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf);
4112 	}
4113 
4114 	if (ap_ft_enabled(dut)) {
4115 		unsigned char self_mac[ETH_ALEN];
4116 		char mac_str[20];
4117 
4118 		owrt_ap_set_vap(dut, vap_id, "ft_over_ds",
4119 				dut->ap_ft_ds == VALUE_ENABLED ? "1" : "0");
4120 		owrt_ap_set_vap(dut, vap_id, "ieee80211r", "1");
4121 		if (get_hwaddr(sigma_radio_ifname[0], self_mac) < 0)
4122 			return -1;
4123 		snprintf(mac_str, sizeof(mac_str),
4124 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4125 			 self_mac[0], self_mac[1], self_mac[2],
4126 			 self_mac[3], self_mac[4], self_mac[5]);
4127 		owrt_ap_set_vap(dut, vap_id, "ap_macaddr", mac_str);
4128 		snprintf(mac_str, sizeof(mac_str),
4129 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4130 			 self_mac[0], self_mac[1], self_mac[2],
4131 			 self_mac[3], self_mac[4], self_mac[5]);
4132 		owrt_ap_set_vap(dut, vap_id, "r1_key_holder", mac_str);
4133 		owrt_ap_set_vap(dut, vap_id, "ft_psk_generate_local", "1");
4134 		owrt_ap_set_vap(dut, vap_id, "kh_key_hex",
4135 				"000102030405060708090a0b0c0d0e0f");
4136 		snprintf(mac_str, sizeof(mac_str),
4137 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4138 			 dut->ft_bss_mac_list[0][0],
4139 			 dut->ft_bss_mac_list[0][1],
4140 			 dut->ft_bss_mac_list[0][2],
4141 			 dut->ft_bss_mac_list[0][3],
4142 			 dut->ft_bss_mac_list[0][4],
4143 			 dut->ft_bss_mac_list[0][5]);
4144 		owrt_ap_set_vap(dut, vap_id, "ap2_macaddr", mac_str);
4145 		owrt_ap_set_vap(dut, vap_id, "mobility_domain",
4146 				dut->ap_mobility_domain);
4147 		owrt_ap_set_vap(dut, vap_id, "ap2_r1_key_holder", mac_str);
4148 	}
4149 
4150 	if ((ap_ft_enabled(dut) && dut->ap_name == 0) ||
4151 	    (ap_ft_enabled(dut) && dut->ap_name == 2)) {
4152 		owrt_ap_set_vap(dut, vap_id, "nasid2", "nas2.example.com");
4153 		owrt_ap_set_vap(dut, vap_id, "nasid", "nas1.example.com");
4154 	}
4155 
4156 	if (ap_ft_enabled(dut) && dut->ap_name == 1) {
4157 		owrt_ap_set_vap(dut, vap_id, "nasid2", "nas1.example.com");
4158 		owrt_ap_set_vap(dut, vap_id, "nasid", "nas2.example.com");
4159 	}
4160 
4161 	if (dut->ap_broadcast_ssid == VALUE_DISABLED)
4162 		owrt_ap_set_vap(dut, vap_id, "hidden", "1");
4163 
4164 	/* Enable/disable PMKSA caching, if asked to */
4165 	if (dut->ap_pmksa == 1) {
4166 		snprintf(buf, sizeof(buf), "%d", dut->ap_pmksa_caching);
4167 		owrt_ap_set_vap(dut, vap_id, "disable_pmksa_caching", buf);
4168 	}
4169 
4170 	if (dut->ap_beacon_prot)
4171 		owrt_ap_set_vap(dut, vap_id, "beacon_prot", "1");
4172 
4173 	if (dut->ap_transition_disable) {
4174 		snprintf(buf, sizeof(buf), "0x%02x",
4175 			 dut->ap_transition_disable);
4176 		owrt_ap_set_vap(dut, vap_id, "transition_disable", buf);
4177 	}
4178 
4179 	if (dut->rsne_override) {
4180 		snprintf(buf, sizeof(buf), "%s", dut->rsne_override);
4181 		owrt_ap_set_vap(dut, vap_count, "own_ie_override", buf);
4182 	}
4183 
4184 	if (dut->rsnxe_override_eapol)
4185 		owrt_ap_set_vap(dut, vap_count, "rsnxe_override_eapol",
4186 				dut->rsnxe_override_eapol);
4187 
4188 	if (dut->sae_commit_override) {
4189 		snprintf(buf, sizeof(buf), "%s", dut->sae_commit_override);
4190 		owrt_ap_set_vap(dut, vap_count, "sae_commit_override", buf);
4191 	}
4192 
4193 	if (dut->ap_sae_groups) {
4194 		snprintf(buf, sizeof(buf), "\'%s\'", dut->ap_sae_groups);
4195 		owrt_ap_set_list_vap(dut, vap_count, "sae_groups", buf);
4196 	}
4197 
4198 	if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) {
4199 		const char *sae_pwe = NULL;
4200 
4201 		if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut))
4202 			sae_pwe = "3";
4203 		else if (dut->sae_pwe == SAE_PWE_LOOP)
4204 			sae_pwe = "0";
4205 		else if (dut->sae_pwe == SAE_PWE_H2E)
4206 			sae_pwe = "1";
4207 		else if (dut->sae_h2e_default)
4208 			sae_pwe = "2";
4209 		if (sae_pwe)
4210 			owrt_ap_set_vap(dut, vap_count, "sae_pwe", sae_pwe);
4211 	}
4212 
4213 	if (dut->sae_anti_clogging_threshold >= 0) {
4214 		snprintf(buf, sizeof(buf), "%d",
4215 			 dut->sae_anti_clogging_threshold);
4216 		owrt_ap_set_vap(dut, vap_count, "sae_anti_clogging_threshold",
4217 				buf);
4218 	}
4219 
4220 	if (dut->sae_reflection)
4221 		owrt_ap_set_vap(dut, vap_count, "sae_reflection_attack", "1");
4222 	if (dut->sae_confirm_immediate)
4223 		owrt_ap_set_vap(dut, vap_count, "sae_confirm_immediate", "2");
4224 
4225 	if (dut->ap_he_dlofdma == VALUE_ENABLED && dut->ap_he_ppdu == PPDU_MU) {
4226 		dut->ap_txBF = 0;
4227 		dut->ap_mu_txBF = 0;
4228 		owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0");
4229 		owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0");
4230 		owrt_ap_set_vap(dut, vap_id, "he_subfer", "0");
4231 	}
4232 
4233 	if (dut->program == PROGRAM_HE &&
4234 	    (dut->ap_txBF || dut->ap_he_ulofdma == VALUE_ENABLED ||
4235 	     dut->ap_he_mimo == MIMO_DL)) {
4236 		switch (dut->ap_chwidth) {
4237 		case AP_20:
4238 			owrt_ap_set_vap(dut, vap_id, "chwidth", "0");
4239 			break;
4240 		case AP_40:
4241 			owrt_ap_set_vap(dut, vap_id, "chwidth", "1");
4242 			break;
4243 		case AP_80:
4244 			owrt_ap_set_vap(dut, vap_id, "chwidth", "2");
4245 			break;
4246 		case AP_160:
4247 			owrt_ap_set_vap(dut, vap_id, "chwidth", "3");
4248 			break;
4249 		case AP_80_80:
4250 			owrt_ap_set_vap(dut, vap_id, "chwidth", "3");
4251 			break;
4252 		case AP_AUTO:
4253 		default:
4254 			break;
4255 		}
4256 	}
4257 
4258 	return 1;
4259 }
4260 
4261 
4262 static int owrt_ap_config_vap_anqp(struct sigma_dut *dut)
4263 {
4264 	char anqpval[1024];
4265 	unsigned char addr[6];
4266 	unsigned char addr2[6];
4267 	struct ifreq ifr;
4268 	char *ifname;
4269 	int s;
4270 	int vap_id = 0;
4271 
4272 	s = socket(AF_INET, SOCK_DGRAM, 0);
4273 	if (s < 0) {
4274 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open socket");
4275 		return -1;
4276 	}
4277 
4278 	memset(&ifr, 0, sizeof(ifr));
4279 	ifname = "ath0";
4280 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
4281 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
4282 		perror("ioctl");
4283 		close(s);
4284 		return -1;
4285 	}
4286 	memcpy(addr, ifr.ifr_hwaddr.sa_data, 6);
4287 
4288 	memset(&ifr, 0, sizeof(ifr));
4289 	ifname = "ath01";
4290 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
4291 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
4292 		perror("ioctl");
4293 		close(s);
4294 		return -1;
4295 	}
4296 	close(s);
4297 	memcpy(addr2, ifr.ifr_hwaddr.sa_data, 6);
4298 
4299 	snprintf(anqpval, sizeof(anqpval),
4300 		 "'265:0010%s%s060101070d00%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'",
4301 		 dut->ap_val_lci, dut->ap_infoz,
4302 		 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
4303 		 addr2[0], addr2[1], addr2[2], addr2[3], addr2[4], addr2[5]);
4304 
4305 	owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4306 	return 0;
4307 }
4308 
4309 
4310 static int owrt_ap_post_config_commit(struct sigma_dut *dut,
4311 				      struct sigma_conn *conn,
4312 				      struct sigma_cmd *cmd)
4313 {
4314 	int ap_security = 0;
4315 	int i;
4316 
4317 	for (i = 0; i < MAX_WLAN_TAGS - 1; i++) {
4318 		if (dut->ap_tag_key_mgmt[i] != AP2_OPEN)
4319 			ap_security = 1;
4320 	}
4321 	if (dut->ap_key_mgmt != AP_OPEN)
4322 		ap_security = 1;
4323 	if (ap_security) {
4324 		/* allow some time for hostapd to start before returning
4325 		 * success */
4326 		usleep(500000);
4327 
4328 		if (run_hostapd_cli(dut, "ping") != 0) {
4329 			send_resp(dut, conn, SIGMA_ERROR,
4330 				  "errorCode,Failed to talk to hostapd");
4331 			return 0;
4332 		}
4333 	}
4334 
4335 	if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
4336 		ath_ap_set_params(dut);
4337 
4338 	/* Send response */
4339 	return 1;
4340 }
4341 
4342 
4343 static int cmd_owrt_ap_config_commit(struct sigma_dut *dut,
4344 				     struct sigma_conn *conn,
4345 				     struct sigma_cmd *cmd)
4346 {
4347 	if (dut->program == PROGRAM_DPP &&
4348 	    get_driver_type(dut) == DRIVER_OPENWRT) {
4349 		wpa_command(dut->hostapd_ifname, "DPP_BOOTSTRAP_REMOVE *");
4350 		wpa_command(dut->hostapd_ifname, "DPP_PKEX_REMOVE *");
4351 	}
4352 
4353 	/* Stop the AP */
4354 	run_system(dut, "wifi down");
4355 
4356 	/* Reset the wireless configuration */
4357 	run_system(dut, "rm -rf /etc/config/wireless");
4358 	switch (get_openwrt_driver_type()) {
4359 	case OPENWRT_DRIVER_ATHEROS:
4360 		run_system(dut, "wifi detect qcawifi > /etc/config/wireless");
4361 		break;
4362 	default:
4363 		run_system(dut, "wifi detect > /etc/config/wireless");
4364 		break;
4365 	}
4366 
4367 	/* Configure Radio & VAP, commit the config */
4368 	if (owrt_ap_config_radio(dut) < 0)
4369 		return ERROR_SEND_STATUS;
4370 	if (owrt_ap_config_vap(dut) < 0)
4371 		return ERROR_SEND_STATUS;
4372 	run_system(dut, "uci commit");
4373 
4374 	/* Start AP */
4375 	run_system(dut, "wifi up");
4376 	if (dut->program != PROGRAM_MBO &&
4377 	    dut->ap_lci == 1 && dut->ap_interworking &&
4378 	    strlen(dut->ap_tag_ssid[0]) > 0) {
4379 		/*
4380 		 * MBO has a different ANQP element value which is set in
4381 		 * owrt_ap_config_vap().
4382 		 */
4383 		owrt_ap_config_vap_anqp(dut);
4384 		run_system(dut, "uci commit");
4385 		run_system(dut, "wifi");
4386 	}
4387 
4388 	return owrt_ap_post_config_commit(dut, conn, cmd);
4389 }
4390 
4391 
4392 static void cmd_owrt_ap_hs2_reset(struct sigma_dut *dut)
4393 {
4394 	unsigned char bssid[6];
4395 	char buf[100];
4396 	char *ifname, *radio_name;
4397 	int vap_id = 0;
4398 
4399 	if (sigma_radio_ifname[0] &&
4400 	    strcmp(sigma_radio_ifname[0], "wifi2") == 0) {
4401 		ifname = "ath2";
4402 		radio_name = "wifi2";
4403 		vap_id = 2;
4404 	} else if (sigma_radio_ifname[0] &&
4405 		   strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
4406 		ifname = "ath1";
4407 		radio_name = "wifi1";
4408 		vap_id = 1;
4409 	} else {
4410 		ifname = "ath0";
4411 		radio_name = "wifi0";
4412 		vap_id = 0;
4413 	}
4414 
4415 	if (!get_hwaddr(ifname, bssid)) {
4416 		snprintf(buf, sizeof(buf), "%s", bssid);
4417 		owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4418 		snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4419 			 "%02x:%02x:%02x:%02x:%02x:%02x",
4420 			 bssid[0], bssid[1], bssid[2], bssid[3],
4421 			 bssid[4], bssid[5]);
4422 	} else {
4423 		if (!get_hwaddr(radio_name, bssid)) {
4424 			snprintf(buf, sizeof(buf), "%s", dut->ap_hessid);
4425 			owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4426 			snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4427 				 "%02x:%02x:%02x:%02x:%02x:%02x",
4428 				 bssid[0], bssid[1], bssid[2], bssid[3],
4429 				 bssid[4], bssid[5]);
4430 		} else {
4431 			/* Select & enable/disable radios */
4432 			if (sigma_radio_ifname[0] &&
4433 			    strcmp(sigma_radio_ifname[0], "wifi2") == 0) {
4434 				/* We want to use wifi2 */
4435 				owrt_ap_set_radio(dut, 0, "disabled", "1");
4436 				owrt_ap_set_radio(dut, 1, "disabled", "1");
4437 				owrt_ap_set_radio(dut, 2, "disabled", "0");
4438 				owrt_ap_set_vap(dut, vap_id, "device", "wifi2");
4439 			} else if (sigma_radio_ifname[0] &&
4440 				   strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
4441 				/* We want to use wifi1 */
4442 				owrt_ap_set_radio(dut, 0, "disabled", "1");
4443 				owrt_ap_set_radio(dut, 1, "disabled", "0");
4444 				owrt_ap_set_vap(dut, vap_id, "device", "wifi1");
4445 			} else {
4446 				/* We want to use wifi0 */
4447 				owrt_ap_set_radio(dut, 0, "disabled", "0");
4448 				owrt_ap_set_radio(dut, 1, "disabled", "1");
4449 				owrt_ap_set_vap(dut, vap_id, "device", "wifi0");
4450 			}
4451 
4452 			run_system(dut, "uci commit");
4453 			run_system(dut, "wifi up");
4454 
4455 			if (!get_hwaddr(radio_name, bssid)) {
4456 				snprintf(buf, sizeof(buf), "%s",
4457 					 dut->ap_hessid);
4458 				owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4459 				snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4460 					 "%02x:%02x:%02x:%02x:%02x:%02x",
4461 					 bssid[0], bssid[1], bssid[2], bssid[3],
4462 					 bssid[4], bssid[5]);
4463 			}
4464 		}
4465 	}
4466 }
4467 
4468 
4469 static enum sigma_cmd_result cmd_ap_reboot(struct sigma_dut *dut,
4470 					   struct sigma_conn *conn,
4471 					   struct sigma_cmd *cmd)
4472 {
4473 	switch (get_driver_type(dut)) {
4474 	case DRIVER_ATHEROS:
4475 		run_system(dut, "apdown");
4476 		sleep(1);
4477 		run_system(dut, "reboot");
4478 		break;
4479 	case DRIVER_OPENWRT:
4480 		run_system(dut, "wifi down");
4481 		sleep(1);
4482 		run_system(dut, "reboot");
4483 		break;
4484 	default:
4485 		sigma_dut_print(dut, DUT_MSG_INFO, "Ignore ap_reboot command");
4486 		break;
4487 	}
4488 
4489 	return 1;
4490 }
4491 
4492 
4493 int ascii2hexstr(const char *str, char *hex)
4494 {
4495 	int i, length;
4496 
4497 	length = strlen(str);
4498 
4499 	for (i = 0; i < length; i++)
4500 		snprintf(hex + i * 2, 3, "%X", str[i]);
4501 
4502 	hex[length * 2] = '\0';
4503 	return 1;
4504 }
4505 
4506 
4507 static int kill_process(struct sigma_dut *dut, char *proc_name,
4508 			unsigned char is_proc_instance_one, int sig)
4509 {
4510 #ifdef __linux__
4511 	struct dirent *dp, *dp_in;
4512 	const char *direc = "/proc/";
4513 	char buf[100];
4514 	DIR *dir = opendir(direc);
4515 	DIR *dir_in;
4516 	FILE *fp;
4517 	char *pid, *temp;
4518 	char *saveptr;
4519 	int ret = -1, res;
4520 
4521 	if (dir == NULL)
4522 		return ret;
4523 
4524 	while ((dp = readdir(dir)) != NULL) {
4525 		if (dp->d_type != DT_DIR)
4526 			continue;
4527 
4528 		res = snprintf(buf, sizeof(buf), "%s%s", direc, dp->d_name);
4529 		if (res < 0 || res >= sizeof(buf))
4530 			continue;
4531 		dir_in = opendir(buf);
4532 		if (dir_in == NULL)
4533 			continue;
4534 		dp_in = readdir(dir_in);
4535 		closedir(dir_in);
4536 		if (dp_in == NULL)
4537 			continue;
4538 		res = snprintf(buf, sizeof(buf), "%s%s/stat",
4539 			       direc, dp->d_name);
4540 		if (res < 0 || res >= sizeof(buf))
4541 			continue;
4542 		fp = fopen(buf, "r");
4543 		if (fp == NULL)
4544 			continue;
4545 		if (fgets(buf, 100, fp) == NULL)
4546 			buf[0] = '\0';
4547 		fclose(fp);
4548 		pid = strtok_r(buf, " ", &saveptr);
4549 		temp = strtok_r(NULL, " ", &saveptr);
4550 		if (pid && temp &&
4551 		    strncmp(temp, proc_name, strlen(proc_name)) == 0) {
4552 			sigma_dut_print(dut, DUT_MSG_INFO,
4553 					"killing %s process with PID %s",
4554 					proc_name, pid);
4555 			snprintf(buf, sizeof(buf), "kill -%d %d", sig,
4556 				 atoi(pid));
4557 			run_system(dut, buf);
4558 			ret = 0;
4559 			if (is_proc_instance_one)
4560 				break;
4561 		}
4562 	}
4563 
4564 	closedir(dir);
4565 
4566 	return ret;
4567 #else /* __linux__ */
4568 	return -1;
4569 #endif /* __linux__ */
4570 }
4571 
4572 
4573 static int run_ndc(struct sigma_dut *dut, char *buf)
4574 {
4575 	sigma_dut_print(dut, DUT_MSG_INFO, "CMD NDC:: %s", buf);
4576 	sleep(2);
4577 	return run_system(dut, buf);
4578 }
4579 
4580 
4581 static int sigma_write_cfg(struct sigma_dut *dut, const char *pfile,
4582 			   const char *field, const char *value)
4583 {
4584 	FILE *fcfg, *ftmp;
4585 	char buf[MAX_CONF_LINE_LEN + 1];
4586 	int len, found = 0, res;
4587 
4588 	/* Open the configuration file */
4589 	fcfg = fopen(pfile, "r");
4590 	if (!fcfg) {
4591 		sigma_dut_print(dut, DUT_MSG_ERROR,
4592 				"Failed to open hostapd conf file");
4593 		return -1;
4594 	}
4595 
4596 	snprintf(buf, sizeof(buf), "%s~", pfile);
4597 	/* Open a temporary file */
4598 	ftmp = fopen(buf, "w+");
4599 	if (!ftmp) {
4600 		fclose(fcfg);
4601 		sigma_dut_print(dut, DUT_MSG_ERROR,
4602 				"Failed to open temp buf");
4603 		return -1;
4604 	}
4605 
4606 	/* Read the values from the configuration file */
4607 	len = strlen(field);
4608 	while (fgets(buf, MAX_CONF_LINE_LEN, fcfg)) {
4609 		char *pline = buf;
4610 
4611 		/* commented line */
4612 		if (buf[0] == '#')
4613 			pline++;
4614 
4615 		/* Identify the configuration parameter to be updated */
4616 		if (!found && strncmp(pline, field, len) == 0 &&
4617 		    pline[len] == '=') {
4618 			snprintf(buf, sizeof(buf), "%s=%s\n", field, value);
4619 			found = 1;
4620 			sigma_dut_print(dut, DUT_MSG_INFO,
4621 					"Updated hostapd conf file");
4622 		}
4623 
4624 		fprintf(ftmp, "%s", buf);
4625 	}
4626 
4627 	if (!found) {
4628 		/* Configuration line not found */
4629 		/* Add the new line at the end of file */
4630 		fprintf(ftmp, "%s=%s\n", field, value);
4631 		sigma_dut_print(dut, DUT_MSG_INFO,
4632 				"Adding a new line in hostapd conf file");
4633 	}
4634 
4635 	fclose(fcfg);
4636 	fclose(ftmp);
4637 
4638 	snprintf(buf, sizeof(buf), "%s~", pfile);
4639 
4640 	/* Restore the updated configuration file */
4641 	res = rename(buf, pfile);
4642 
4643 	/* Remove the temporary file. Ignore the return value */
4644 	unlink(buf);
4645 
4646 	/* chmod is needed because open() may not set permissions properly
4647 	 * depending on the current umask */
4648 	if (chmod(pfile, 0660) < 0) {
4649 		unlink(pfile);
4650 		sigma_dut_print(dut, DUT_MSG_ERROR,
4651 				"Error changing permissions");
4652 		return -1;
4653 	}
4654 
4655 	if (res < 0) {
4656 		sigma_dut_print(dut, DUT_MSG_ERROR,
4657 				"Error restoring conf file");
4658 		return -1;
4659 	}
4660 
4661 	return 0;
4662 }
4663 
4664 
4665 static int cmd_wcn_ap_config_commit(struct sigma_dut *dut,
4666 				    struct sigma_conn *conn,
4667 				    struct sigma_cmd *cmd)
4668 {
4669 	char buf[100];
4670 	struct stat s;
4671 	int num_tries = 0, ret;
4672 
4673 	if (kill_process(dut, "(netd)", 1, SIGKILL) == 0 ||
4674 	    system("killall netd") == 0) {
4675 		/* Avoid Error: Error connecting (Connection refused)
4676 		 * Wait some time to allow netd to reinitialize.
4677 		 */
4678 		usleep(1500000);
4679 	}
4680 
4681 	while (num_tries < 10) {
4682 		ret = run_ndc(dut, "ndc softap stopap");
4683 		num_tries++;
4684 		if (WIFEXITED(ret))
4685 			ret = WEXITSTATUS(ret);
4686 		/* On success, NDC exits with 0 */
4687 		if (ret == 0)
4688 			break;
4689 		sigma_dut_print(dut, DUT_MSG_INFO,
4690 				"Try No. %d: ndc softap stopap failed, exit code %d",
4691 				num_tries, ret);
4692 	}
4693 
4694 	if (ret != 0)
4695 		sigma_dut_print(dut, DUT_MSG_ERROR,
4696 				"ndc softap stopap command failed for 10 times - giving up");
4697 
4698 #ifdef ANDROID
4699 	/* Unload/Load driver to cleanup the state of the driver */
4700 	system("rmmod -f wlan");
4701 	usleep(500000);
4702 	system("insmod /system/lib/modules/wlan.ko");
4703 #else /* ANDROID */
4704 	run_ndc(dut, "ndc softap qccmd set enable_softap=0");
4705 	run_ndc(dut, "ndc softap qccmd set enable_softap=1");
4706 #endif /* ANDROID */
4707 
4708 	switch (dut->ap_mode) {
4709 	case AP_11g:
4710 		run_ndc(dut, "ndc softap qccmd set hw_mode=g-only");
4711 		break;
4712 	case AP_11b:
4713 		run_ndc(dut, "ndc softap qccmd set hw_mode=b-only");
4714 		break;
4715 	case AP_11ng:
4716 		run_ndc(dut, "ndc softap qccmd set hw_mode=n");
4717 		break;
4718 	case AP_11a:
4719 		run_ndc(dut, "ndc softap qccmd set hw_mode=a-only");
4720 		break;
4721 	case AP_11na:
4722 		run_ndc(dut, "ndc softap qccmd set hw_mode=n");
4723 		break;
4724 	case AP_11ac:
4725 		run_ndc(dut, "ndc softap qccmd set hw_mode=ac");
4726 		break;
4727 	default:
4728 		break;
4729 	}
4730 
4731 	snprintf(buf, sizeof(buf), "ndc softap qccmd set channel=%d",
4732 		 dut->ap_channel);
4733 	run_ndc(dut, buf);
4734 
4735 	/*
4736 	 * ndc doesn't support double quotes as SSID string, so re-write
4737 	 * hostapd configuration file to update SSID.
4738 	 */
4739 	if (dut->ap_ssid[0] != '\0')
4740 		sigma_write_cfg(dut, ANDROID_CONFIG_FILE, "ssid", dut->ap_ssid);
4741 
4742 	switch (dut->ap_key_mgmt) {
4743 	case AP_OPEN:
4744 		if (dut->ap_cipher == AP_WEP) {
4745 			run_ndc(dut, "ndc softap qccmd set security_mode=1");
4746 			snprintf(buf, sizeof(buf),
4747 				 "ndc softap qccmd set wep_key0=%s",
4748 				 dut->ap_wepkey);
4749 			run_ndc(dut, buf);
4750 		} else {
4751 			run_ndc(dut, "ndc softap qccmd set security_mode=0");
4752 		}
4753 		break;
4754 	case AP_WPA2_PSK:
4755 	case AP_WPA2_PSK_MIXED:
4756 	case AP_WPA_PSK:
4757 		if (dut->ap_key_mgmt == AP_WPA2_PSK)
4758 			run_ndc(dut, "ndc softap qccmd set security_mode=3");
4759 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
4760 			run_ndc(dut, "ndc softap qccmd set security_mode=4");
4761 		else
4762 			run_ndc(dut, "ndc softap qccmd set security_mode=2");
4763 
4764 		/*
4765 		 * ndc doesn't support some special characters as passphrase,
4766 		 * so re-write hostapd configuration file to update Passphrase.
4767 		 */
4768 		if (dut->ap_passphrase[0] != '\0')
4769 			sigma_write_cfg(dut, ANDROID_CONFIG_FILE,
4770 					"wpa_passphrase", dut->ap_passphrase);
4771 
4772 		if (dut->ap_cipher == AP_CCMP_TKIP)
4773 			run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4774 				"TKIP CCMP");
4775 		else if (dut->ap_cipher == AP_TKIP)
4776 			run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4777 				"TKIP");
4778 		else
4779 			run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4780 				"CCMP &");
4781 		break;
4782 	case AP_WPA2_SAE:
4783 	case AP_WPA2_PSK_SAE:
4784 	case AP_WPA2_EAP:
4785 	case AP_WPA2_EAP_MIXED:
4786 	case AP_WPA_EAP:
4787 	case AP_SUITEB:
4788 	case AP_WPA2_OWE:
4789 	case AP_WPA2_EAP_OSEN:
4790 	case AP_OSEN:
4791 	case AP_WPA2_FT_EAP:
4792 	case AP_WPA2_FT_PSK:
4793 	case AP_WPA2_EAP_SHA256:
4794 	case AP_WPA2_PSK_SHA256:
4795 	case AP_WPA2_ENT_FT_EAP:
4796 		/* Not supported */
4797 		break;
4798 	}
4799 
4800 	switch (dut->ap_pmf) {
4801 	case AP_PMF_DISABLED:
4802 		run_ndc(dut, "ndc softap qccmd set ieee80211w=0");
4803 		break;
4804 	case AP_PMF_OPTIONAL:
4805 		run_ndc(dut, "ndc softap qccmd set ieee80211w=1");
4806 		if (dut->ap_add_sha256)
4807 			run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256");
4808 		else
4809 			run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK");
4810 		break;
4811 	case AP_PMF_REQUIRED:
4812 		run_ndc(dut, "ndc softap qccmd set ieee80211w=2");
4813 		run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK-SHA256");
4814 		break;
4815 	}
4816 
4817 	if (dut->ap_countrycode[0]) {
4818 		snprintf(buf, sizeof(buf),
4819 			 "ndc softap qccmd set country_code=%s",
4820 			 dut->ap_countrycode);
4821 		run_ndc(dut, buf);
4822 	}
4823 
4824 	if (dut->ap_regulatory_mode == AP_80211D_MODE_ENABLED)
4825 		run_ndc(dut, "ndc softap qccmd set ieee80211d=1");
4826 
4827 	if (dut->ap_dfs_mode == AP_DFS_MODE_ENABLED)
4828 		run_ndc(dut, "ndc softap qccmd set ieee80211h=1");
4829 
4830 	run_ndc(dut, "ndc softap startap");
4831 
4832 	snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl,
4833 		 get_main_ifname(dut));
4834 	num_tries = 0;
4835 	while (num_tries < 10 && (ret = stat(buf, &s) != 0)) {
4836 		run_ndc(dut, "ndc softap stopap");
4837 		run_ndc(dut, "ndc softap startap");
4838 		num_tries++;
4839 	}
4840 
4841 	if (num_tries == 10) {
4842 		sigma_dut_print(dut, DUT_MSG_INFO, "Tried 10 times with ctrl "
4843 				"iface %s :: reboot the APDUT", buf);
4844 		return ret;
4845 	}
4846 
4847 	sigma_dut_print(dut, DUT_MSG_INFO, "setting ip addr %s mask %s",
4848 			ap_inet_addr, ap_inet_mask);
4849 	snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up",
4850 		 get_main_ifname(dut), ap_inet_addr, ap_inet_mask);
4851 	if (system(buf) != 0) {
4852 		sigma_dut_print(dut, DUT_MSG_ERROR,
4853 				"Failed to intialize the interface");
4854 		return -1;
4855 	}
4856 
4857 	return 1;
4858 }
4859 
4860 
4861 static int append_hostapd_conf_hs2(struct sigma_dut *dut, FILE *f)
4862 {
4863 	fprintf(f, "hs20=1\nhs20_deauth_req_timeout=3\n"
4864 		"disable_dgaf=%d\n", dut->ap_dgaf_disable);
4865 
4866 	if (dut->ap_oper_name) {
4867 		fprintf(f, "hs20_oper_friendly_name=eng:Wi-Fi Alliance\n");
4868 		fprintf(f, "hs20_oper_friendly_name=chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f\n");
4869 	}
4870 
4871 	if (dut->ap_wan_metrics == 1)
4872 		fprintf(f, "hs20_wan_metrics=01:2500:384:0:0:10\n");
4873 	else if (dut->ap_wan_metrics == 2)
4874 		fprintf(f, "hs20_wan_metrics=01:1500:384:20:20:10\n");
4875 	else if (dut->ap_wan_metrics == 3)
4876 		fprintf(f, "hs20_wan_metrics=01:2000:1000:20:20:10\n");
4877 	else if (dut->ap_wan_metrics == 4)
4878 		fprintf(f, "hs20_wan_metrics=01:8000:1000:20:20:10\n");
4879 	else if (dut->ap_wan_metrics == 5)
4880 		fprintf(f, "hs20_wan_metrics=01:9000:5000:20:20:10\n");
4881 
4882 	if (dut->ap_conn_capab == 1) {
4883 		fprintf(f, "hs20_conn_capab=1:0:0\n");
4884 		fprintf(f, "hs20_conn_capab=6:20:1\n");
4885 		fprintf(f, "hs20_conn_capab=6:22:0\n");
4886 		fprintf(f, "hs20_conn_capab=6:80:1\n");
4887 		fprintf(f, "hs20_conn_capab=6:443:1\n");
4888 		fprintf(f, "hs20_conn_capab=6:1723:0\n");
4889 		fprintf(f, "hs20_conn_capab=6:5060:0\n");
4890 		fprintf(f, "hs20_conn_capab=17:500:1\n");
4891 		fprintf(f, "hs20_conn_capab=17:5060:0\n");
4892 		fprintf(f, "hs20_conn_capab=17:4500:1\n");
4893 		fprintf(f, "hs20_conn_capab=50:0:1\n");
4894 	} else if (dut->ap_conn_capab == 2) {
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=17:5060:1\n");
4898 		fprintf(f, "hs20_conn_capab=6:5060:1\n");
4899 	} else if (dut->ap_conn_capab == 3) {
4900 		fprintf(f, "hs20_conn_capab=6:80:1\n");
4901 		fprintf(f, "hs20_conn_capab=6:443:1\n");
4902 	} else if (dut->ap_conn_capab == 4) {
4903 		fprintf(f, "hs20_conn_capab=6:80:1\n");
4904 		fprintf(f, "hs20_conn_capab=6:443:1\n");
4905 		fprintf(f, "hs20_conn_capab=6:5060:1\n");
4906 		fprintf(f, "hs20_conn_capab=17:5060:1\n");
4907 	}
4908 
4909 	if (dut->ap_oper_class == 1)
4910 		fprintf(f, "hs20_operating_class=51\n");
4911 	else if (dut->ap_oper_class == 2)
4912 		fprintf(f, "hs20_operating_class=73\n");
4913 	else if (dut->ap_oper_class == 3)
4914 		fprintf(f, "hs20_operating_class=5173\n");
4915 
4916 	if (dut->ap_osu_provider_list) {
4917 		char *osu_friendly_name = NULL;
4918 		char *osu_icon = NULL;
4919 		char *osu_ssid = NULL;
4920 		char *osu_nai = NULL;
4921 		char *osu_nai2 = NULL;
4922 		char *osu_service_desc = NULL;
4923 		char *hs20_icon_filename = NULL;
4924 		char hs20_icon[150];
4925 		int osu_method;
4926 
4927 		hs20_icon_filename = "icon_red_zxx.png";
4928 		if (dut->ap_osu_icon_tag == 2)
4929 			hs20_icon_filename = "wifi-abgn-logo_270x73.png";
4930 		snprintf(hs20_icon, sizeof(hs20_icon),
4931 			 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s",
4932 			 hs20_icon_filename);
4933 		osu_icon = "icon_red_zxx.png";
4934 		osu_ssid = "OSU";
4935 		osu_friendly_name = "kor:SP 빨강 테스트 전용";
4936 		osu_service_desc = "kor:테스트 목적으로 무료 서비스";
4937 		osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0];
4938 
4939 		if (strlen(dut->ap_osu_server_uri[0]))
4940 			fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[0]);
4941 		else
4942 			fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
4943 
4944 		switch (dut->ap_osu_provider_list) {
4945 		case 1:
4946 		case 101:
4947 			fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
4948 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
4949 			hs20_icon_filename = "icon_red_eng.png";
4950 			if (dut->ap_osu_icon_tag == 2)
4951 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
4952 			fprintf(f, "hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s\n",
4953 				hs20_icon_filename);
4954 			fprintf(f, "osu_icon=icon_red_eng.png\n");
4955 			break;
4956 		case 2:
4957 		case 102:
4958 			fprintf(f, "osu_friendly_name=eng:Wireless Broadband Alliance\n");
4959 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
4960 			hs20_icon_filename = "icon_orange_zxx.png";
4961 			if (dut->ap_osu_icon_tag == 2)
4962 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
4963 			snprintf(hs20_icon, sizeof(hs20_icon),
4964 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
4965 				 hs20_icon_filename);
4966 			osu_icon = "icon_orange_zxx.png";
4967 			osu_friendly_name = "kor:와이어리스 브로드밴드 얼라이언스";
4968 			break;
4969 		case 3:
4970 		case 103:
4971 			osu_friendly_name = "spa:SP Red Test Only";
4972 			osu_service_desc = "spa:Free service for test purpose";
4973 			break;
4974 		case 4:
4975 		case 104:
4976 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
4977 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
4978 			hs20_icon_filename = "icon_orange_eng.png";
4979 			if (dut->ap_osu_icon_tag == 2)
4980 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
4981 			fprintf(f, "hs20_icon=160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s\n",
4982 				hs20_icon_filename);
4983 			fprintf(f, "osu_icon=icon_orange_eng.png\n");
4984 			osu_friendly_name = "kor:SP 오렌지 테스트 전용";
4985 
4986 			hs20_icon_filename = "icon_orange_zxx.png";
4987 			if (dut->ap_osu_icon_tag == 2)
4988 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
4989 			snprintf(hs20_icon, sizeof(hs20_icon),
4990 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
4991 				 hs20_icon_filename);
4992 			osu_icon = "icon_orange_zxx.png";
4993 			break;
4994 		case 5:
4995 		case 105:
4996 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
4997 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
4998 			osu_friendly_name = "kor:SP 오렌지 테스트 전용";
4999 			hs20_icon_filename = "icon_orange_zxx.png";
5000 			if (dut->ap_osu_icon_tag == 2)
5001 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5002 			snprintf(hs20_icon, sizeof(hs20_icon),
5003 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5004 				 hs20_icon_filename);
5005 			osu_icon = "icon_orange_zxx.png";
5006 			break;
5007 		case 6:
5008 		case 106:
5009 			fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n");
5010 			fprintf(f, "osu_friendly_name=kor:SP 초록 테스트 전용\n");
5011 			hs20_icon_filename = "icon_green_zxx.png";
5012 			if (dut->ap_osu_icon_tag == 2)
5013 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5014 			fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s\n",
5015 				hs20_icon_filename);
5016 			fprintf(f, "osu_icon=icon_green_zxx.png\n");
5017 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 : dut->ap_osu_method[0];
5018 			fprintf(f, "osu_method_list=%d\n", osu_method);
5019 
5020 			if (strlen(dut->ap_osu_server_uri[1]))
5021 				fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]);
5022 			else
5023 				fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
5024 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5025 			hs20_icon_filename = "icon_orange_zxx.png";
5026 			if (dut->ap_osu_icon_tag == 2)
5027 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5028 			snprintf(hs20_icon, sizeof(hs20_icon),
5029 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5030 				 hs20_icon_filename);
5031 			osu_icon = "icon_orange_zxx.png";
5032 			osu_friendly_name = "kor:SP 오렌지 테스트 전용";
5033 			osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 : dut->ap_osu_method[1];
5034 			osu_service_desc = NULL;
5035 			break;
5036 		case 7:
5037 		case 107:
5038 			fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n");
5039 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5040 			hs20_icon_filename = "icon_green_eng.png";
5041 			if (dut->ap_osu_icon_tag == 2)
5042 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5043 			fprintf(f, "hs20_icon=160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s\n",
5044 				hs20_icon_filename);
5045 			fprintf(f, "osu_icon=icon_green_eng.png\n");
5046 			osu_friendly_name = "kor:SP 초록 테스트 전용";
5047 
5048 			hs20_icon_filename = "icon_green_zxx.png";
5049 			if (dut->ap_osu_icon_tag == 2)
5050 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5051 			snprintf(hs20_icon, sizeof(hs20_icon),
5052 				 "128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s",
5053 				 hs20_icon_filename);
5054 			osu_icon = "icon_green_zxx.png";
5055 			break;
5056 		case 8:
5057 		case 108:
5058 			fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
5059 			fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5060 			osu_ssid = "OSU-Encrypted";
5061 			osu_nai = "anonymous@hotspot.net";
5062 			break;
5063 		case 9:
5064 		case 109:
5065 			osu_ssid = "OSU-OSEN";
5066 			osu_nai = "test-anonymous@wi-fi.org";
5067 			osu_friendly_name = "eng:SP Orange Test Only";
5068 			hs20_icon_filename = "icon_orange_zxx.png";
5069 			if (dut->ap_osu_icon_tag == 2)
5070 				hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5071 			snprintf(hs20_icon, sizeof(hs20_icon),
5072 				 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5073 				 hs20_icon_filename);
5074 			osu_icon = "icon_orange_zxx.png";
5075 			osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0];
5076 			osu_service_desc = NULL;
5077 			break;
5078 		case 10:
5079 		case 110:
5080 			/* OSU Provider #1 */
5081 			fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5082 			fprintf(f, "osu_friendly_name=kor:SP 오렌지 테스트 전용\n");
5083 			fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/icon_orange_zxx.png\n");
5084 			fprintf(f, "osu_icon=icon_orange_zxx.png\n");
5085 			osu_method = (dut->ap_osu_method[0] == 0xFF) ?
5086 				1 : dut->ap_osu_method[0];
5087 			fprintf(f, "osu_method_list=%d\n", osu_method);
5088 			fprintf(f, "osu_nai=test-anonymous@wi-fi.org\n");
5089 			switch (dut->ap_osu_provider_nai_list) {
5090 			case 3:
5091 				fprintf(f,
5092 					"osu_nai2=test-anonymous@wi-fi.org\n");
5093 				break;
5094 			case 4:
5095 				fprintf(f, "osu_nai2=random@hotspot.net\n");
5096 				break;
5097 			}
5098 
5099 			/* OSU Provider #2 */
5100 			/* SP Red from defaults */
5101 			if (strlen(dut->ap_osu_server_uri[1]))
5102 				fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]);
5103 			else
5104 				fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
5105 			fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
5106 			snprintf(hs20_icon, sizeof(hs20_icon),
5107 				 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/icon_red_zxx.png");
5108 			osu_method = (dut->ap_osu_method[1] == 0xFF) ?
5109 				1 : dut->ap_osu_method[1];
5110 			osu_service_desc = NULL;
5111 			osu_nai = "anonymous@hotspot.net";
5112 			break;
5113 		default:
5114 			break;
5115 		}
5116 
5117 		switch (dut->ap_osu_provider_nai_list) {
5118 		case 1:
5119 			osu_nai2 = "anonymous@hotspot.net";
5120 			break;
5121 		case 2:
5122 			osu_nai2 = "test-anonymous@wi-fi.org";
5123 			break;
5124 		case 3:
5125 			/* OSU Provider NAI #1 written above */
5126 			/* OSU Provider NAI #2 */
5127 			osu_nai2 = "anonymous@hotspot.net";
5128 			break;
5129 		case 4:
5130 			/* OSU Provider NAI #1 written above */
5131 			/* OSU Provider NAI #2 */
5132 			osu_nai2 = "anonymous@hotspot.net";
5133 			break;
5134 		}
5135 
5136 		if (strlen(dut->ap_osu_ssid)) {
5137 			if (dut->ap_tag_ssid[0][0] &&
5138 			    strcmp(dut->ap_tag_ssid[0], dut->ap_osu_ssid) &&
5139 			    strcmp(dut->ap_tag_ssid[0], osu_ssid)) {
5140 				sigma_dut_print(dut, DUT_MSG_ERROR,
5141 						"OSU_SSID and "
5142 						"WLAN_TAG2 SSID differ");
5143 				return -2;
5144 			}
5145 			fprintf(f, "osu_ssid=\"%s\"\n", dut->ap_osu_ssid);
5146 		} else
5147 			fprintf(f, "osu_ssid=\"%s\"\n", osu_ssid);
5148 
5149 
5150 		if (osu_friendly_name)
5151 			fprintf(f, "osu_friendly_name=%s\n", osu_friendly_name);
5152 
5153 		if (osu_service_desc)
5154 			fprintf(f, "osu_service_desc=%s\n", osu_service_desc);
5155 
5156 		if (osu_nai)
5157 			fprintf(f, "osu_nai=%s\n", osu_nai);
5158 		if (osu_nai2)
5159 			fprintf(f, "osu_nai2=%s\n", osu_nai2);
5160 
5161 		fprintf(f, "hs20_icon=%s\n", hs20_icon);
5162 
5163 		if (osu_icon)
5164 			fprintf(f, "osu_icon=%s\n", osu_icon);
5165 
5166 		if (dut->ap_osu_provider_list > 100)
5167 			fprintf(f, "osu_method_list=0\n");
5168 		else
5169 			fprintf(f, "osu_method_list=%d\n", osu_method);
5170 	}
5171 
5172 	switch (dut->ap_venue_url) {
5173 	case 1:
5174 		fprintf(f,
5175 			"venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5176 			"venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/directory/index.html\n");
5177 		break;
5178 	case 2:
5179 		fprintf(f,
5180 			"venue_url=1:https://the-great-mall.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5181 			"venue_url=2:https://abercrombie.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5182 			"venue_url=3:https://adidas.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5183 			"venue_url=4:https://aeropostale.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5184 			"venue_url=5:https://agaci.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5185 			"venue_url=6:https://aldo-shoes.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5186 			"venue_url=7:https://american-eagle-outfitters.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5187 			"venue_url=8:https://anderson-bakery.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5188 			"venue_url=9:https://banana-republic-factory-store.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5189 			"venue_url=10:https://bed-bath-and-beyond.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5190 			);
5191 		break;
5192 	}
5193 
5194 	switch (dut->ap_advice_of_charge) {
5195 	case 1:
5196 		fprintf(f, "anqp_elem=278:" ADV_OF_CHARGE_1 "\n");
5197 		break;
5198 	}
5199 
5200 	switch (dut->ap_oper_icon_metadata) {
5201 	case 1:
5202 		fprintf(f,
5203 			"hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/icon_red_eng.png\n"
5204 			"operator_icon=icon_red_eng.png\n");
5205 		break;
5206 	}
5207 
5208 	switch (dut->ap_tnc_file_name) {
5209 	case 1:
5210 		fprintf(f, "hs20_t_c_filename=tandc-id1-content.txt\n");
5211 		break;
5212 	}
5213 
5214 	if (dut->ap_tnc_time_stamp)
5215 		fprintf(f, "hs20_t_c_timestamp=%u\n", dut->ap_tnc_time_stamp);
5216 
5217 	return 0;
5218 }
5219 
5220 
5221 static void write_ap_roaming_cons(FILE *f, const char *list)
5222 {
5223 	char *buf, *pos, *end;
5224 
5225 	if (list == NULL || list[0] == '\0')
5226 		return;
5227 
5228 	buf = strdup(list);
5229 	if (buf == NULL)
5230 		return;
5231 
5232 	pos = buf;
5233 	while (pos && *pos) {
5234 		end = strchr(pos, ';');
5235 		if (end)
5236 			*end++ = '\0';
5237 		fprintf(f, "roaming_consortium=%s\n", pos);
5238 		pos = end;
5239 	}
5240 
5241 	free(buf);
5242 }
5243 
5244 
5245 static int append_hostapd_conf_interworking(struct sigma_dut *dut, FILE *f)
5246 {
5247 	int i;
5248 	char buf[100], *temp;
5249 
5250 	if (dut->ap_gas_cb_delay > 0)
5251 		fprintf(f, "gas_comeback_delay=%d\n",
5252 			dut->ap_gas_cb_delay);
5253 
5254 	fprintf(f, "interworking=1\n"
5255 		"access_network_type=%d\n"
5256 		"internet=%d\n"
5257 		"asra=0\n"
5258 		"esr=0\n"
5259 		"uesa=0\n"
5260 		"venue_group=%d\n"
5261 		"venue_type=%d\n",
5262 		dut->ap_access_net_type,
5263 		dut->ap_internet,
5264 		dut->ap_venue_group,
5265 		dut->ap_venue_type);
5266 	if (dut->ap_hessid[0])
5267 		fprintf(f, "hessid=%s\n", dut->ap_hessid);
5268 
5269 	write_ap_roaming_cons(f, dut->ap_roaming_cons);
5270 
5271 	if (dut->ap_venue_name) {
5272 		fprintf(f, "venue_name=P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"\n");
5273 		fprintf(f, "venue_name=%s\n", ANQP_VENUE_NAME_1_CHI);
5274 	}
5275 
5276 	if (dut->ap_net_auth_type == 1)
5277 		fprintf(f, "network_auth_type=00https://tandc-server.wi-fi.org\n");
5278 	else if (dut->ap_net_auth_type == 2)
5279 		fprintf(f, "network_auth_type=01\n");
5280 
5281 	if (dut->ap_nai_realm_list == 1) {
5282 		fprintf(f, "nai_realm=0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]\n");
5283 		fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n");
5284 	} else if (dut->ap_nai_realm_list == 2) {
5285 		fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n");
5286 	} else if (dut->ap_nai_realm_list == 3) {
5287 		fprintf(f, "nai_realm=0,cisco.com;wi-fi.org,21[2:4][5:7]\n");
5288 		fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n");
5289 	} else if (dut->ap_nai_realm_list == 4) {
5290 		fprintf(f, "nai_realm=0,mail.example.com,21[2:4][5:7],13[5:6]\n");
5291 	} else if (dut->ap_nai_realm_list == 5) {
5292 		fprintf(f, "nai_realm=0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]\n");
5293 	} else if (dut->ap_nai_realm_list == 6) {
5294 		fprintf(f, "nai_realm=0,wi-fi.org;mail.example.com,21[2:4][5:7]\n");
5295 	} else if (dut->ap_nai_realm_list == 7) {
5296 		fprintf(f, "nai_realm=0,wi-fi.org,13[5:6]\n");
5297 		fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n");
5298 	}
5299 
5300 	if (dut->ap_domain_name_list[0]) {
5301 		fprintf(f, "domain_name=%s\n",
5302 			dut->ap_domain_name_list);
5303 	}
5304 
5305 	if (dut->ap_ip_addr_type_avail == 1) {
5306 		fprintf(f, "ipaddr_type_availability=0c\n");
5307 	}
5308 
5309 	temp = buf;
5310 	for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0];
5311 	     i++) {
5312 		if (i)
5313 			*temp++ = ';';
5314 
5315 		snprintf(temp,
5316 			 sizeof(dut->ap_plmn_mcc[i]) +
5317 			 sizeof(dut->ap_plmn_mnc[i]) + 1,
5318 			 "%s,%s",
5319 			 dut->ap_plmn_mcc[i],
5320 			 dut->ap_plmn_mnc[i]);
5321 
5322 		temp += strlen(dut->ap_plmn_mcc[i]) +
5323 			strlen(dut->ap_plmn_mnc[i]) + 1;
5324 	}
5325 	if (i)
5326 		fprintf(f, "anqp_3gpp_cell_net=%s\n", buf);
5327 
5328 	if (dut->ap_qos_map_set == 1)
5329 		fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_1);
5330 	else if (dut->ap_qos_map_set == 2)
5331 		fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_2);
5332 
5333 	return 0;
5334 }
5335 
5336 
5337 static int ath_ap_append_hostapd_conf(struct sigma_dut *dut)
5338 {
5339 	FILE *f;
5340 
5341 	if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
5342 	    system("killall hostapd") == 0) {
5343 		int i;
5344 
5345 		/* Wait some time to allow hostapd to complete cleanup before
5346 		 * starting a new process */
5347 		for (i = 0; i < 10; i++) {
5348 			usleep(500000);
5349 			if (system("pidof hostapd") != 0)
5350 				break;
5351 		}
5352 	}
5353 
5354 	f = fopen("/tmp/secath0", "a");
5355 	if (f == NULL)
5356 		return -2;
5357 
5358 	if (dut->ap_hs2 && append_hostapd_conf_hs2(dut, f)) {
5359 		fclose(f);
5360 		return -2;
5361 	}
5362 
5363 	if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) {
5364 		fclose(f);
5365 		return -2;
5366 	}
5367 
5368 	fflush(f);
5369 	fclose(f);
5370 	return ath_ap_start_hostapd(dut);
5371 }
5372 
5373 
5374 static int ath_ap_start_hostapd(struct sigma_dut *dut)
5375 {
5376 	if (dut->ap_tag_key_mgmt[0] == AP2_OSEN)
5377 		run_system(dut, "hostapd -B /tmp/secath0 /tmp/secath1 -e /etc/wpa2/entropy");
5378 	else
5379 		run_system(dut, "hostapd -B /tmp/secath0 -e /etc/wpa2/entropy");
5380 
5381 	return 0;
5382 }
5383 
5384 
5385 #define LE16(a) ((((a) & 0xff) << 8) | (((a) >> 8) & 0xff))
5386 
5387 static int cmd_ath_ap_anqpserver_start(struct sigma_dut *dut)
5388 {
5389 	FILE *f;
5390 	int nai_realm = 0, domain_name = 0, oper_name = 0, venue_name = 0,
5391 		wan_metrics = 0, conn_cap = 0, ipaddr_avail = 0, cell_net = 0;
5392 	char buf[100];
5393 	int i;
5394 
5395 	f = fopen("/root/anqpserver.conf", "w");
5396 	if (f == NULL)
5397 		return -1;
5398 
5399 	if (dut->ap_nai_realm_list == 1) {
5400 		nai_realm = 1;
5401 		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");
5402 	} else if (dut->ap_nai_realm_list == 2) {
5403 		nai_realm = 1;
5404 		fprintf(f, "dyn_nai_home_realm=encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
5405 	} else if (dut->ap_nai_realm_list == 3) {
5406 		nai_realm = 1;
5407 		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");
5408 	} else if (dut->ap_nai_realm_list == 4) {
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=mail.example.com;eap_method=0Dauth_id=05auth_val=06\n");
5411 	} else
5412 		sigma_dut_print(dut, DUT_MSG_INFO, "not setting nai_realm");
5413 
5414 	if (dut->ap_domain_name_list[0]) {
5415 		char *next, *start, *dnbuf, *dn1, *anqp_dn;
5416 		int len, dn_len_max;
5417 		dnbuf = strdup(dut->ap_domain_name_list);
5418 		if (dnbuf == NULL) {
5419 			fclose(f);
5420 			return 0;
5421 		}
5422 
5423 		len = strlen(dnbuf);
5424 		dn_len_max = 50 + len*2;
5425 		anqp_dn = malloc(dn_len_max);
5426 		if (anqp_dn == NULL) {
5427 			free(dnbuf);
5428 			fclose(f);
5429 			return -1;
5430 		}
5431 		start = dnbuf;
5432 		dn1 = anqp_dn;
5433 		while (start && *start) {
5434 			char *hexstr;
5435 
5436 			next = strchr(start, ',');
5437 			if (next)
5438 				*next++ = '\0';
5439 
5440 			len = strlen(start);
5441 			hexstr = malloc(len * 2 + 1);
5442 			if (hexstr == NULL) {
5443 				free(dnbuf);
5444 				free(anqp_dn);
5445 				fclose(f);
5446 				return -1;
5447 			}
5448 			ascii2hexstr(start, hexstr);
5449 			snprintf(dn1, dn_len_max, "%02x%s", len, hexstr);
5450 			free(hexstr);
5451 			dn1 += 2 + len * 2;
5452 			dn_len_max -= 2 + len * 2;
5453 			start = next;
5454 		}
5455 		free(dnbuf);
5456 		if (dut->ap_gas_cb_delay) {
5457 			fprintf(f, "dyn_domain_name=0c01%04x%s",
5458 				LE16((unsigned int) strlen(anqp_dn)), anqp_dn);
5459 			domain_name = 1;
5460 		} else
5461 			fprintf(f, "domain_name=0c01%04x%s",
5462 				LE16((unsigned int) strlen(anqp_dn)), anqp_dn);
5463 		free(anqp_dn);
5464 	} else
5465 		sigma_dut_print(dut, DUT_MSG_INFO, "not setting domain_name");
5466 
5467 	sigma_dut_print(dut, DUT_MSG_INFO, "not setting roaming_consortium");
5468 
5469 	if (dut->ap_oper_name) {
5470 		if (dut->ap_gas_cb_delay) {
5471 			fprintf(f, "dyn_oper_friendly_name="
5472 				ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n");
5473 			oper_name = 1;
5474 		} else
5475 			fprintf(f, "oper_friendly_name="
5476 				ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n");
5477 	} else
5478 		sigma_dut_print(dut, DUT_MSG_INFO, "not setting oper_name");
5479 
5480 	if (dut->ap_venue_name) {
5481 		if (dut->ap_gas_cb_delay) {
5482 			fprintf(f, "dyn_venue_name=" ANQP_VENUE_NAME_1 "\n");
5483 			venue_name = 1;
5484 		} else
5485 			fprintf(f, "venue_name=" ANQP_VENUE_NAME_1 "\n");
5486 	} else
5487 		sigma_dut_print(dut, DUT_MSG_ERROR, "not setting venue_name");
5488 
5489 	if (dut->ap_wan_metrics) {
5490 		if (dut->ap_gas_cb_delay) {
5491 			fprintf(f, "dyn_wan_metrics=" ANQP_HS20_WAN_METRICS_1 "\n");
5492 			wan_metrics = 1;
5493 		} else
5494 			fprintf(f, "wan_metrics=" ANQP_HS20_WAN_METRICS_1
5495 				"\n");
5496 	} else
5497 		sigma_dut_print(dut, DUT_MSG_ERROR, "not setting wan_metrics");
5498 
5499 	if (dut->ap_conn_capab) {
5500 		if (dut->ap_gas_cb_delay) {
5501 			fprintf(f, "dyn_conn_capability="
5502 				ANQP_HS20_CONNECTION_CAPABILITY_1 "\n");
5503 			conn_cap = 1;
5504 		} else
5505 			fprintf(f, "conn_capability="
5506 				ANQP_HS20_CONNECTION_CAPABILITY_1 "\n");
5507 	} else
5508 		sigma_dut_print(dut, DUT_MSG_ERROR,
5509 				"not setting conn_capability");
5510 
5511 	if (dut->ap_ip_addr_type_avail) {
5512 		if (dut->ap_gas_cb_delay) {
5513 			fprintf(f, "dyn_ipaddr_type=" ANQP_IP_ADDR_TYPE_1
5514 				"\n");
5515 			ipaddr_avail = 1;
5516 		} else
5517 			fprintf(f, "ipaddr_type=" ANQP_IP_ADDR_TYPE_1 "\n");
5518 	} else
5519 		sigma_dut_print(dut, DUT_MSG_ERROR,
5520 				"not setting ipaddr_type_avail");
5521 
5522 	for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) {
5523 		snprintf(buf + i * 6, sizeof(buf) - i * 6, "%c%c%c%c%c%c",
5524 			 dut->ap_plmn_mcc[i][1],
5525 			 dut->ap_plmn_mcc[i][0],
5526 			 dut->ap_plmn_mnc[i][2] == '\0' ?
5527 			 'f' : dut->ap_plmn_mnc[i][2],
5528 			 dut->ap_plmn_mcc[i][2],
5529 			 dut->ap_plmn_mnc[i][1],
5530 			 dut->ap_plmn_mnc[i][0]);
5531 	}
5532 	if (i) {
5533 		uint16_t ie_len = (i * 3) + 5;
5534 		if (dut->ap_gas_cb_delay) {
5535 			fprintf(f, "dyn_cell_net=0801");
5536 			cell_net = 1;
5537 		} else
5538 			fprintf(f, "cell_net=0801");
5539 		fprintf(f, "%04x", LE16(ie_len));
5540 		fprintf(f, "00");                /* version */
5541 		fprintf(f, "%02x", (i * 3) + 3); /* user data hdr length */
5542 		fprintf(f, "00");                /* plmn list */
5543 		fprintf(f, "%02x", (i * 3) + 1); /* length of plmn list */
5544 		fprintf(f, "%02x", i);           /* number of plmns */
5545 		fprintf(f, "%s\n", buf);           /* plmns */
5546 	} else
5547 		sigma_dut_print(dut, DUT_MSG_ERROR,
5548 				"not setting 3gpp_cellular_network");
5549 
5550 	if (nai_realm || domain_name || oper_name || venue_name ||
5551 		wan_metrics || conn_cap || ipaddr_avail || cell_net) {
5552 		fprintf(f, "anqp_attach=");
5553 		if (venue_name)
5554 			fprintf(f, "00000104%4.4x", dut->ap_gas_cb_delay);
5555 		if (nai_realm)
5556 			fprintf(f, "00000107%4.4x", dut->ap_gas_cb_delay);
5557 		if (cell_net)
5558 			fprintf(f, "00000108%4.4x", dut->ap_gas_cb_delay);
5559 		if (domain_name)
5560 			fprintf(f, "0000010c%4.4x", dut->ap_gas_cb_delay);
5561 		if (oper_name)
5562 			fprintf(f, "00010003%4.4x", dut->ap_gas_cb_delay);
5563 		if (wan_metrics)
5564 			fprintf(f, "00010004%4.4x", dut->ap_gas_cb_delay);
5565 		if (conn_cap)
5566 			fprintf(f, "00010005%4.4x", dut->ap_gas_cb_delay);
5567 		fprintf(f, "00010006%4.4x", dut->ap_gas_cb_delay);
5568 		fprintf(f, "\n");
5569 	}
5570 
5571 	fclose(f);
5572 
5573 	run_system(dut, "anqpserver -i ath0 &");
5574 	if (!dut->ap_anqpserver_on)
5575 		run_system(dut, "killall anqpserver");
5576 
5577 	return 1;
5578 }
5579 
5580 
5581 static void cmd_ath_ap_radio_config(struct sigma_dut *dut)
5582 {
5583 	char buf[100];
5584 
5585 	run_system(dut, "cfg -a AP_STARTMODE=standard");
5586 
5587 	if (sigma_radio_ifname[0] &&
5588 	    strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
5589 		run_system(dut, "cfg -a AP_RADIO_ID=1");
5590 		switch (dut->ap_mode) {
5591 		case AP_11g:
5592 			run_system(dut, "cfg -a AP_CHMODE_2=11G");
5593 			break;
5594 		case AP_11b:
5595 			run_system(dut, "cfg -a AP_CHMODE_2=11B");
5596 			break;
5597 		case AP_11ng:
5598 			run_system(dut, "cfg -a AP_CHMODE_2=11NGHT20");
5599 			break;
5600 		case AP_11a:
5601 			run_system(dut, "cfg -a AP_CHMODE_2=11A");
5602 			break;
5603 		case AP_11na:
5604 			run_system(dut, "cfg -a AP_CHMODE_2=11NAHT20");
5605 			break;
5606 		case AP_11ac:
5607 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5608 			break;
5609 		default:
5610 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5611 			break;
5612 		}
5613 
5614 		switch (dut->ap_rx_streams) {
5615 		case 1:
5616 			run_system(dut, "cfg -a RX_CHAINMASK_2=1");
5617 			break;
5618 		case 2:
5619 			run_system(dut, "cfg -a RX_CHAINMASK_2=3");
5620 			break;
5621 		case 3:
5622 			run_system(dut, "cfg -a RX_CHAINMASK_2=7");
5623 			break;
5624 		}
5625 
5626 		switch (dut->ap_tx_streams) {
5627 		case 1:
5628 			run_system(dut, "cfg -a TX_CHAINMASK_2=1");
5629 			break;
5630 		case 2:
5631 			run_system(dut, "cfg -a TX_CHAINMASK_2=3");
5632 			break;
5633 		case 3:
5634 			run_system(dut, "cfg -a TX_CHAINMASK_2=7");
5635 			break;
5636 		}
5637 
5638 		switch (dut->ap_chwidth) {
5639 		case AP_20:
5640 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT20");
5641 			break;
5642 		case AP_40:
5643 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT40");
5644 			break;
5645 		case AP_80:
5646 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5647 			break;
5648 		case AP_160:
5649 		case AP_AUTO:
5650 		default:
5651 			run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5652 			break;
5653 		}
5654 
5655 		if (dut->ap_tx_stbc) {
5656 			run_system(dut, "cfg -a TX_STBC_2=1");
5657 		}
5658 
5659 		snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH_2=%d",
5660 			 dut->ap_channel);
5661 
5662 		if (dut->ap_is_dual) {
5663 			switch (dut->ap_mode_1) {
5664 			case AP_11g:
5665 				run_system(dut, "cfg -a AP_CHMODE=11G");
5666 				break;
5667 			case AP_11b:
5668 				run_system(dut, "cfg -a AP_CHMODE=11B");
5669 				break;
5670 			case AP_11ng:
5671 				run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5672 				break;
5673 			case AP_11a:
5674 				run_system(dut, "cfg -a AP_CHMODE=11A");
5675 				break;
5676 			case AP_11na:
5677 				run_system(dut, "cfg -a AP_CHMODE=11NAHT20");
5678 				break;
5679 			case AP_11ac:
5680 				run_system(dut, "cfg -a AP_CHMODE=11ACVHT80");
5681 				break;
5682 			default:
5683 				run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5684 				break;
5685 			}
5686 			snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d",
5687 				 dut->ap_channel_1);
5688 		}
5689 		run_system(dut, buf);
5690 	} else {
5691 		run_system(dut, "cfg -a AP_RADIO_ID=0");
5692 		switch (dut->ap_mode) {
5693 		case AP_11g:
5694 			run_system(dut, "cfg -a AP_CHMODE=11G");
5695 			break;
5696 		case AP_11b:
5697 			run_system(dut, "cfg -a AP_CHMODE=11B");
5698 			break;
5699 		case AP_11ng:
5700 			run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5701 			break;
5702 		case AP_11a:
5703 			run_system(dut, "cfg -a AP_CHMODE=11A");
5704 			break;
5705 		case AP_11na:
5706 			run_system(dut, "cfg -a AP_CHMODE=11NAHT20");
5707 			break;
5708 		case AP_11ac:
5709 			run_system(dut, "cfg -a AP_CHMODE=11ACVHT80");
5710 			break;
5711 		default:
5712 			run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5713 			break;
5714 		}
5715 		snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d",
5716 			 dut->ap_channel);
5717 		run_system(dut, buf);
5718 	}
5719 
5720 	if (dut->ap_sgi80 == 1) {
5721 		run_system(dut, "cfg -a SHORTGI=1");
5722 		run_system(dut, "cfg -a SHORTGI_2=1");
5723 	} else if (dut->ap_sgi80 == 0) {
5724 		run_system(dut, "cfg -a SHORTGI=0");
5725 		run_system(dut, "cfg -a SHORTGI_2=0");
5726 	}
5727 
5728 	if (dut->ap_ldpc == VALUE_ENABLED)
5729 		run_system(dut, "cfg -a LDPC=1");
5730 	else if (dut->ap_ldpc == VALUE_DISABLED)
5731 		run_system(dut, "cfg -a LDPC=0");
5732 }
5733 
5734 
5735 void ath_disable_txbf(struct sigma_dut *dut, const char *intf)
5736 {
5737 	run_iwpriv(dut, intf, "vhtsubfee 0");
5738 	run_iwpriv(dut, intf, "vhtsubfer 0");
5739 	run_iwpriv(dut, intf, "vhtmubfee 0");
5740 	run_iwpriv(dut, intf, "vhtmubfer 0");
5741 }
5742 
5743 
5744 static void ath_set_assoc_disallow(struct sigma_dut *dut, const char *ifname,
5745 				   const char *val)
5746 {
5747 	if (strcasecmp(val, "enable") == 0) {
5748 		run_iwpriv(dut, ifname, "mbo_asoc_dis 1");
5749 	} else if (strcasecmp(val, "disable") == 0) {
5750 		run_iwpriv(dut, ifname, "mbo_asoc_dis 0");
5751 	} else {
5752 		sigma_dut_print(dut, DUT_MSG_ERROR,
5753 				"Unsupported assoc_disallow");
5754 	}
5755 }
5756 
5757 
5758 static void apply_mbo_pref_ap_list(struct sigma_dut *dut)
5759 {
5760 	int i;
5761 	int least_pref = 1 << 8;
5762 	char ifname[20];
5763 	uint8_t self_mac[ETH_ALEN];
5764 	char buf[200];
5765 	int ap_ne_class, ap_ne_pref, ap_ne_op_ch;
5766 
5767 	get_if_name(dut, ifname, sizeof(ifname), 1);
5768 	get_hwaddr(ifname, self_mac);
5769 
5770 	/* Clear off */
5771 	snprintf(buf, sizeof(buf),
5772 		 "wifitool %s setbssidpref 00:00:00:00:00:00 0 0 0",
5773 		 ifname);
5774 	run_system(dut, buf);
5775 
5776 	/* Find the least preference number */
5777 	for (i = 0; i < dut->mbo_pref_ap_cnt; i++) {
5778 		unsigned char *mac_addr = dut->mbo_pref_aps[i].mac_addr;
5779 
5780 		ap_ne_class = 1;
5781 		ap_ne_pref = 255;
5782 		ap_ne_op_ch = 1;
5783 		if (dut->mbo_pref_aps[i].ap_ne_pref != -1)
5784 			ap_ne_pref = dut->mbo_pref_aps[i].ap_ne_pref;
5785 		if (dut->mbo_pref_aps[i].ap_ne_class != -1)
5786 			ap_ne_class = dut->mbo_pref_aps[i].ap_ne_class;
5787 		if (dut->mbo_pref_aps[i].ap_ne_op_ch != -1)
5788 			ap_ne_op_ch = dut->mbo_pref_aps[i].ap_ne_op_ch;
5789 
5790 		if (ap_ne_pref < least_pref)
5791 			least_pref = ap_ne_pref;
5792 		snprintf(buf, sizeof(buf),
5793 			 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d",
5794 			 ifname, mac_addr[0], mac_addr[1], mac_addr[2],
5795 			 mac_addr[3], mac_addr[4], mac_addr[5],
5796 			 ap_ne_pref, ap_ne_class, ap_ne_op_ch);
5797 		run_system(dut, buf);
5798 	}
5799 
5800 	/* Now add the self AP Address */
5801 	if (dut->mbo_self_ap_tuple.ap_ne_class == -1) {
5802 		if (dut->ap_channel <= 11)
5803 			ap_ne_class = 81;
5804 		else
5805 			ap_ne_class = 115;
5806 	} else {
5807 		ap_ne_class = dut->mbo_self_ap_tuple.ap_ne_class;
5808 	}
5809 
5810 	if (dut->mbo_self_ap_tuple.ap_ne_op_ch == -1)
5811 		ap_ne_op_ch = dut->ap_channel;
5812 	else
5813 		ap_ne_op_ch = dut->mbo_self_ap_tuple.ap_ne_op_ch;
5814 
5815 	if (dut->mbo_self_ap_tuple.ap_ne_pref == -1)
5816 		ap_ne_pref = least_pref - 1;
5817 	else
5818 		ap_ne_pref = dut->mbo_self_ap_tuple.ap_ne_pref;
5819 
5820 	snprintf(buf, sizeof(buf),
5821 		 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d",
5822 		 ifname, self_mac[0], self_mac[1], self_mac[2],
5823 		 self_mac[3], self_mac[4], self_mac[5],
5824 		 ap_ne_pref,
5825 		 ap_ne_class,
5826 		 ap_ne_op_ch);
5827 	run_system(dut, buf);
5828 }
5829 
5830 
5831 static void mubrp_commands(struct sigma_dut *dut, const char *ifname)
5832 {
5833 	run_iwpriv(dut, ifname, "he_subfer 1");
5834 	run_iwpriv(dut, ifname, "he_mubfer 1");
5835 	/* To enable MU_AX with MU_BRP trigger */
5836 	run_iwpriv(dut, ifname, "he_sounding_mode 13");
5837 	/* Sets g_force_1x1_peer to 1 which should be reset to zero for non MU
5838 	 * test cases */
5839 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 118 1",
5840 			   ifname);
5841 	/* Disable DL OFDMA */
5842 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 11 0",
5843 			   ifname);
5844 }
5845 
5846 
5847 static void ath_ap_set_params(struct sigma_dut *dut)
5848 {
5849 	const char *basedev = "wifi0";
5850 	const char *basedev_radio = "wifi1";
5851 	const char *ifname = get_main_ifname(dut);
5852 	char *ifname_dual = NULL;
5853 	int i;
5854 	char buf[300];
5855 	unsigned int he_mcsnssmap = dut->he_mcsnssmap;
5856 
5857 	if (sigma_radio_ifname[0])
5858 		basedev = sigma_radio_ifname[0];
5859 
5860 	if (dut->ap_is_dual == 1) {
5861 		basedev = sigma_radio_ifname[0];
5862 		basedev_radio = sigma_radio_ifname[1];
5863 		if (sigma_radio_ifname[0] &&
5864 		    strcmp(sigma_radio_ifname[0], "wifi0") == 0) {
5865 			ifname = "ath0";
5866 			ifname_dual = "ath1";
5867 		} else {
5868 			ifname = "ath1";
5869 			ifname_dual = "ath0";
5870 		}
5871 	}
5872 
5873 	if (dut->ap_countrycode[0]) {
5874 		run_iwpriv(dut, basedev, "setCountry %s", dut->ap_countrycode);
5875 		sigma_dut_print(dut, DUT_MSG_INFO, "Set countrycode");
5876 	}
5877 
5878 	for (i = 0; i < NUM_AP_AC; i++) {
5879 		if (dut->ap_qos[i].ac) {
5880 			run_iwpriv(dut, ifname, "cwmin %d 0 %d", i,
5881 				   dut->ap_qos[i].cwmin);
5882 			run_iwpriv(dut, ifname, "cwmax %d 0 %d", i,
5883 				   dut->ap_qos[i].cwmax);
5884 			run_iwpriv(dut, ifname, "aifs %d 0 %d", i,
5885 				   dut->ap_qos[i].aifs);
5886 			run_iwpriv(dut, ifname, "txoplimit %d 0 %d", i,
5887 				   dut->ap_qos[i].txop);
5888 			run_iwpriv(dut, ifname, "acm %d 0 %d", i,
5889 				   dut->ap_qos[i].acm);
5890 		}
5891 	}
5892 
5893 	for (i = 0; i < NUM_AP_AC; i++) {
5894 		if (dut->ap_sta_qos[i].ac) {
5895 			run_iwpriv(dut, ifname, "cwmin %d 1 %d", i,
5896 				   dut->ap_sta_qos[i].cwmin);
5897 			run_iwpriv(dut, ifname, "cwmax %d 1 %d", i,
5898 				   dut->ap_sta_qos[i].cwmax);
5899 			run_iwpriv(dut, ifname, "aifs %d 1 %d", i,
5900 				   dut->ap_sta_qos[i].aifs);
5901 			run_iwpriv(dut, ifname, "txoplimit %d 1 %d", i,
5902 				   dut->ap_sta_qos[i].txop);
5903 			run_iwpriv(dut, ifname, "acm %d 1 %d", i,
5904 				   dut->ap_sta_qos[i].acm);
5905 		}
5906 	}
5907 
5908 	if (dut->ap_disable_protection == 1) {
5909 		run_iwpriv(dut, ifname, "enablertscts 0");
5910 		sigma_dut_print(dut, DUT_MSG_INFO, "Disabled rtscts");
5911 	}
5912 
5913 	if (dut->ap_ldpc == VALUE_ENABLED)
5914 		run_iwpriv(dut, ifname, "ldpc 3");
5915 	else if (dut->ap_ldpc == VALUE_DISABLED)
5916 		run_iwpriv(dut, ifname, "ldpc 0");
5917 
5918 	if (dut->ap_ampdu == VALUE_ENABLED) {
5919 		run_iwpriv(dut, ifname, "ampdu 1");
5920 	} else if (dut->ap_ampdu == VALUE_DISABLED) {
5921 		run_iwpriv(dut, ifname, "ampdu 0");
5922 		if (dut->program == PROGRAM_HE) {
5923 			run_iwpriv(dut, ifname, "setaddbaoper 1");
5924 			run_system_wrapper(dut, "wifitool %s refusealladdbas 1",
5925 					   ifname);
5926 			if (dut->ap_amsdu == VALUE_ENABLED) {
5927 				/* disable the limit for A-MSDU */
5928 				run_system_wrapper(dut,
5929 						   "wifitool %s setUnitTestCmd 0x48 2 46 1",
5930 						   ifname);
5931 			}
5932 		}
5933 	}
5934 
5935 	if (dut->ap_ampdu_exp) {
5936 		if (dut->program == PROGRAM_VHT) {
5937 			run_iwpriv(dut, ifname, "vhtmaxampdu %d",
5938 				   dut->ap_ampdu_exp);
5939 		} else {
5940 			/* 11N */
5941 			run_iwpriv(dut, ifname, "maxampdu %d",
5942 				   dut->ap_ampdu_exp);
5943 		}
5944 	}
5945 
5946 	if (dut->ap_noack == VALUE_ENABLED) {
5947 		run_iwpriv(dut, ifname, "noackpolicy 0 0 1");
5948 		run_iwpriv(dut, ifname, "noackpolicy 1 0 1");
5949 		run_iwpriv(dut, ifname, "noackpolicy 2 0 1");
5950 		run_iwpriv(dut, ifname, "noackpolicy 3 0 1");
5951 	} else if (dut->ap_noack == VALUE_DISABLED) {
5952 		run_iwpriv(dut, ifname, "noackpolicy 0 0 0");
5953 		run_iwpriv(dut, ifname, "noackpolicy 1 0 0");
5954 		run_iwpriv(dut, ifname, "noackpolicy 2 0 0");
5955 		run_iwpriv(dut, ifname, "noackpolicy 3 0 0");
5956 	}
5957 
5958 	if (dut->device_type == AP_testbed && dut->ap_vhtmcs_map)
5959 		run_iwpriv(dut, ifname, "vht_mcsmap 0x%04x",
5960 			   dut->ap_vhtmcs_map);
5961 
5962 	if (dut->ap_amsdu == VALUE_ENABLED)
5963 		run_iwpriv(dut, ifname, "amsdu 2");
5964 	else if (dut->ap_amsdu == VALUE_DISABLED)
5965 		run_iwpriv(dut, ifname, "amsdu 1");
5966 
5967 	if (dut->ap_rx_amsdu == VALUE_ENABLED)
5968 		run_iwpriv(dut, basedev_radio, "rx_amsdu 1");
5969 	else if (dut->ap_rx_amsdu == VALUE_DISABLED)
5970 		run_iwpriv(dut, basedev_radio, "rx_amsdu 0");
5971 
5972 	/* Command sequence to generate single VHT AMSDU and MPDU */
5973 	if (dut->ap_addba_reject != VALUE_NOT_SET &&
5974 	    dut->ap_ampdu == VALUE_DISABLED &&
5975 	    dut->ap_amsdu == VALUE_ENABLED) {
5976 		run_iwpriv(dut, ifname, "setaddbaoper 1");
5977 
5978 		snprintf(buf, sizeof(buf),
5979 			 "wifitool %s senddelba 1 0 1 4", ifname);
5980 		if (system(buf) != 0) {
5981 			sigma_dut_print(dut, DUT_MSG_ERROR,
5982 					"wifitool senddelba failed");
5983 		}
5984 
5985 		snprintf(buf, sizeof(buf), "wifitool %s sendsingleamsdu 1 0",
5986 			 ifname);
5987 		if (system(buf) != 0) {
5988 			sigma_dut_print(dut, DUT_MSG_ERROR,
5989 					"wifitool sendsingleamsdu failed");
5990 		}
5991 
5992 		run_iwpriv(dut, ifname, "amsdu 10");
5993 	}
5994 
5995 	if (dut->ap_mode == AP_11ac) {
5996 		int chwidth, nss;
5997 
5998 		switch (dut->ap_chwidth) {
5999 		case AP_20:
6000 			chwidth = 0;
6001 			break;
6002 		case AP_40:
6003 			chwidth = 1;
6004 			break;
6005 		case AP_80:
6006 			chwidth = 2;
6007 			break;
6008 		case AP_160:
6009 			chwidth = 3;
6010 			break;
6011 		case AP_80_80:
6012 			chwidth = 3;
6013 			break;
6014 		default:
6015 			chwidth = 0;
6016 			break;
6017 		}
6018 
6019 		switch (dut->ap_tx_streams) {
6020 		case 1:
6021 			nss = 1;
6022 			break;
6023 		case 2:
6024 			nss = 2;
6025 			break;
6026 		case 3:
6027 			nss = 3;
6028 			break;
6029 		case 4:
6030 			nss = 4;
6031 			break;
6032 		default:
6033 			nss = 3;
6034 			break;
6035 		}
6036 
6037 		if (dut->ap_fixed_rate) {
6038 			if (nss == 4)
6039 				ath_disable_txbf(dut, ifname);
6040 
6041 			/* Set the nss */
6042 			run_iwpriv(dut, ifname, "nss %d", nss);
6043 
6044 			/* Set the channel width */
6045 			run_iwpriv(dut, ifname, "chwidth %d", chwidth);
6046 
6047 			/* Set the VHT MCS */
6048 			run_iwpriv(dut, ifname, "vhtmcs %d", dut->ap_mcs);
6049 		}
6050 	}
6051 
6052 	if (dut->ap_dyn_bw_sig == VALUE_ENABLED)
6053 		run_iwpriv(dut, ifname, "cwmenable 1");
6054 	else if (dut->ap_dyn_bw_sig == VALUE_DISABLED)
6055 		run_iwpriv(dut, ifname, "cwmenable 0");
6056 
6057 	if (dut->ap_sig_rts == VALUE_ENABLED) {
6058 		snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname);
6059 		if (system(buf) != 0) {
6060 			sigma_dut_print(dut, DUT_MSG_ERROR,
6061 					"iwconfig rts 64 failed");
6062 		}
6063 	} else if (dut->ap_sig_rts == VALUE_DISABLED) {
6064 		snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname);
6065 		if (system(buf) != 0) {
6066 			sigma_dut_print(dut, DUT_MSG_ERROR,
6067 					"iwconfig rts 2347 failed");
6068 		}
6069 	}
6070 
6071 	if (dut->ap_hs2) {
6072 		run_iwpriv(dut, ifname, "qbssload 1");
6073 		sigma_dut_print(dut, DUT_MSG_INFO, "Enabled qbssload");
6074 	}
6075 
6076 	if (dut->ap_bss_load && dut->ap_bss_load != -1) {
6077 		unsigned int bssload = 0;
6078 
6079 		if (dut->ap_bss_load == 1) {
6080 			/* STA count: 1, CU: 50, AAC: 65535 */
6081 			bssload = 0x0132ffff;
6082 		} else if (dut->ap_bss_load == 2) {
6083 			/* STA count: 1, CU: 200, AAC: 65535 */
6084 			bssload = 0x01c8ffff;
6085 		} else if (dut->ap_bss_load == 3) {
6086 			/* STA count: 1, CU: 75, AAC: 65535 */
6087 			bssload = 0x014bffff;
6088 		}
6089 
6090 		run_iwpriv(dut, ifname, "hcbssload %u", bssload);
6091 	} else if (dut->ap_bss_load == 0) {
6092 		run_iwpriv(dut, ifname, "qbssload 0");
6093 		sigma_dut_print(dut, DUT_MSG_INFO, "Disabled qbssload");
6094 	}
6095 
6096 	if (dut->ap_dgaf_disable) {
6097 		run_iwpriv(dut, ifname, "dgaf_disable 1");
6098 		sigma_dut_print(dut, DUT_MSG_INFO, "Enabled dgaf_disable");
6099 	}
6100 
6101 	if (dut->ap_l2tif) {
6102 		run_iwpriv(dut, ifname, "l2tif 1");
6103 		snprintf(buf, sizeof(buf),
6104 			"echo 1 > /sys/class/net/br0/brif/ath0/hotspot_l2tif");
6105 		if (system(buf) != 0)
6106 			sigma_dut_print(dut, DUT_MSG_ERROR,
6107 				"l2tif br failed");
6108 
6109 		snprintf(buf, sizeof(buf),
6110 			"echo 1 > /sys/class/net/br0/brif/eth0/hotspot_wan");
6111 		if (system(buf) != 0)
6112 			sigma_dut_print(dut, DUT_MSG_ERROR,
6113 				"l2tif brif failed");
6114 		sigma_dut_print(dut, DUT_MSG_INFO, "Enabled l2tif");
6115 	}
6116 
6117 	if (dut->ap_ndpa_frame == 0) {
6118 		snprintf(buf, sizeof(buf),
6119 			 "wifitool %s beeliner_fw_test 117 192", ifname);
6120 		if (system(buf) != 0) {
6121 			sigma_dut_print(dut, DUT_MSG_ERROR,
6122 					"wifitool beeliner_fw_test 117 192 failed");
6123 		}
6124 		snprintf(buf, sizeof(buf),
6125 			 "wifitool %s beeliner_fw_test 118 192", ifname);
6126 		if (system(buf) != 0) {
6127 			sigma_dut_print(dut, DUT_MSG_ERROR,
6128 					"wifitool beeliner_fw_test 117 192 failed");
6129 		}
6130 	} else if (dut->ap_ndpa_frame == 1) {
6131 		/* Driver default - no changes needed */
6132 	} else if (dut->ap_ndpa_frame == 2) {
6133 		snprintf(buf, sizeof(buf),
6134 			 "wifitool %s beeliner_fw_test 115 1", ifname);
6135 		if (system(buf) != 0) {
6136 			sigma_dut_print(dut, DUT_MSG_ERROR,
6137 					"wifitool beeliner_fw_test 117 192 failed");
6138 		}
6139 		snprintf(buf, sizeof(buf),
6140 			 "wifitool %s beeliner_fw_test 116 1", ifname);
6141 		if (system(buf) != 0) {
6142 			sigma_dut_print(dut, DUT_MSG_ERROR,
6143 					"wifitool beeliner_fw_test 117 192 failed");
6144 		}
6145 	}
6146 
6147 	if (dut->ap_rtt == 1)
6148 		run_iwpriv(dut, ifname, "enable_rtt 1");
6149 
6150 	if (dut->ap_lci == 1)
6151 		run_iwpriv(dut, ifname, "enable_lci 1");
6152 
6153 	if (dut->ap_lcr == 1)
6154 		run_iwpriv(dut, ifname, "enable_lcr 1");
6155 
6156 	if (dut->ap_rrm == 1)
6157 		run_iwpriv(dut, ifname, "enable_rmm 1");
6158 
6159 	if (dut->ap_lci == 1 || dut->ap_lcr == 1) {
6160 		run_system(dut, "wpc -l /tmp/lci_cfg.txt");
6161 	}
6162 
6163 	if (dut->ap_neighap >= 1 && dut->ap_lci == 0) {
6164 		FILE *f;
6165 
6166 		f = fopen("/tmp/nbr_report.txt", "w");
6167 		if (!f) {
6168 			sigma_dut_print(dut, DUT_MSG_ERROR,
6169 					"Failed to open /tmp/nbr_report.txt");
6170 			return;
6171 		}
6172 
6173 		fprintf(f,
6174 			"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",
6175 			dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1],
6176 			dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3],
6177 			dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5],
6178 			dut->ap_val_opchannel[0]);
6179 		fclose(f);
6180 
6181 		f = fopen("/tmp/ftmrr.txt", "w");
6182 		if (!f) {
6183 			sigma_dut_print(dut, DUT_MSG_ERROR,
6184 					"Failed to open /tmp/ftmrr.txt");
6185 			return;
6186 		}
6187 
6188 		fprintf(f,
6189 			"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",
6190 			dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1],
6191 			dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3],
6192 			dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5],
6193 			dut->ap_val_opchannel[0]);
6194 		fclose(f);
6195 	}
6196 
6197 	if (dut->ap_neighap >= 2 && dut->ap_lci == 0) {
6198 		FILE *f;
6199 
6200 		f = fopen("/tmp/nbr_report.txt", "a");
6201 		if (!f) {
6202 			sigma_dut_print(dut, DUT_MSG_ERROR,
6203 					"Failed to open /tmp/nbr_report.txt");
6204 			return;
6205 		}
6206 		fprintf(f,
6207 			"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",
6208 			dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1],
6209 			dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3],
6210 			dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5],
6211 			dut->ap_val_opchannel[1]);
6212 		fclose(f);
6213 
6214 		f = fopen("/tmp/ftmrr.txt", "a");
6215 		if (!f) {
6216 			sigma_dut_print(dut, DUT_MSG_ERROR,
6217 					"Failed to open /tmp/ftmrr.txt");
6218 			return;
6219 		}
6220 		fprintf(f,
6221 			"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",
6222 			dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1],
6223 			dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3],
6224 			dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5],
6225 			dut->ap_val_opchannel[1]);
6226 		fclose(f);
6227 	}
6228 
6229 	if (dut->ap_neighap >= 3 && dut->ap_lci == 0) {
6230 		FILE *f;
6231 
6232 		f = fopen("/tmp/nbr_report.txt", "a");
6233 		if (!f) {
6234 			sigma_dut_print(dut, DUT_MSG_ERROR,
6235 					"Failed to open /tmp/nbr_report.txt");
6236 			return;
6237 		}
6238 
6239 		fprintf(f,
6240 			"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",
6241 			dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1],
6242 			dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3],
6243 			dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5],
6244 			dut->ap_val_opchannel[2]);
6245 		fclose(f);
6246 
6247 		f = fopen("/tmp/ftmrr.txt", "a");
6248 		if (!f) {
6249 			sigma_dut_print(dut, DUT_MSG_ERROR,
6250 					"Failed to open /tmp/ftmrr.txt");
6251 			return;
6252 		}
6253 
6254 		fprintf(f,
6255 			"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",
6256 			dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1],
6257 			dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3],
6258 			dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5],
6259 			dut->ap_val_opchannel[2]);
6260 		fclose(f);
6261 	}
6262 
6263 	if (dut->ap_neighap) {
6264 		run_iwpriv(dut, ifname, "enable_rtt 1");
6265 		run_iwpriv(dut, ifname, "enable_lci 1");
6266 		run_iwpriv(dut, ifname, "enable_lcr 1");
6267 		run_iwpriv(dut, ifname, "enable_rrm 1");
6268 	}
6269 
6270 	if (dut->ap_scan == 1) {
6271 		run_iwpriv(dut, ifname, "scanentryage 600");
6272 		snprintf(buf, sizeof(buf), "iwlist %s scan", ifname);
6273 		run_system(dut, buf);
6274 	}
6275 
6276 	if (dut->ap_set_bssidpref) {
6277 		snprintf(buf, sizeof(buf),
6278 			 "wifitool %s setbssidpref 00:00:00:00:00:00 0 00 00",
6279 			 ifname);
6280 		if (system(buf) != 0) {
6281 			sigma_dut_print(dut, DUT_MSG_ERROR,
6282 					"wifitool clear bssidpref failed");
6283 		}
6284 	}
6285 
6286 	if (dut->wnm_bss_max_feature != VALUE_NOT_SET) {
6287 		int feature_enable;
6288 
6289 		feature_enable = dut->wnm_bss_max_feature == VALUE_ENABLED;
6290 		run_iwpriv(dut, ifname, "wnm %d", feature_enable);
6291 		run_iwpriv(dut, ifname, "wnm_bss %d", feature_enable);
6292 		if (feature_enable) {
6293 			const char *extra = "";
6294 
6295 			if (dut->wnm_bss_max_protection != VALUE_NOT_SET) {
6296 				if (dut->wnm_bss_max_protection ==
6297 				    VALUE_ENABLED)
6298 					extra = " 1";
6299 				else
6300 					extra = " 0";
6301 			}
6302 			snprintf(buf, sizeof(buf),
6303 				 "wlanconfig %s wnm setbssmax %d%s",
6304 				 ifname, dut->wnm_bss_max_idle_time, extra);
6305 			run_system(dut, buf);
6306 		}
6307 	}
6308 
6309 	if (dut->program == PROGRAM_MBO) {
6310 		apply_mbo_pref_ap_list(dut);
6311 		run_iwpriv(dut, ifname, "mbo_cel_pref %d",
6312 			   dut->ap_cell_cap_pref);
6313 		run_iwpriv(dut, ifname, "mbocap 0x40");
6314 		ath_set_assoc_disallow(dut, ifname, "disable");
6315 	}
6316 
6317 	if (dut->ap_oce == VALUE_ENABLED)
6318 		run_iwpriv(dut, ifname, "set_bpr_enable 1");
6319 
6320 	if (dut->ap_oce == VALUE_ENABLED && dut->ap_channel <= 11) {
6321 		run_iwpriv(dut, ifname, "prb_rate 5500");
6322 		run_iwpriv(dut, ifname, "set_bcn_rate 5500");
6323 	}
6324 
6325 	if (dut->ap_oce == VALUE_DISABLED)
6326 		run_iwpriv(dut, ifname, "set_bpr_enable 0");
6327 
6328 	if (dut->ap_oce == VALUE_DISABLED && dut->ap_channel <= 11) {
6329 		run_iwpriv(dut, ifname, "mgmt_rate 1000");
6330 		run_iwpriv(dut, ifname, "set_bcn_rate 1000");
6331 	}
6332 
6333 	if (dut->ap_bcnint)
6334 		run_iwpriv(dut, ifname, "bintval %d", dut->ap_bcnint);
6335 
6336 	if (dut->ap_filsdscv == VALUE_DISABLED)
6337 		run_iwpriv(dut, ifname, "enable_fils 0 0");
6338 
6339 	if (dut->ap_filshlp == VALUE_ENABLED)
6340 		run_iwpriv(dut, ifname, "oce_hlp 1");
6341 	else if (dut->ap_filshlp == VALUE_DISABLED)
6342 		run_iwpriv(dut, ifname, "oce_hlp 0");
6343 
6344 	/*  When RNR is enabled, also enable apchannelreport, background scan */
6345 	if (dut->ap_rnr == VALUE_ENABLED) {
6346 		run_iwpriv(dut, ifname, "rnr 1");
6347 		run_iwpriv(dut, ifname, "rnr_tbtt 1");
6348 		run_iwpriv(dut, ifname, "apchanrpt 1");
6349 		run_iwpriv(dut, basedev, "acs_ctrlflags 0x4");
6350 		run_iwpriv(dut, basedev, "acs_scanintvl 60");
6351 		run_iwpriv(dut, basedev, "acs_bkscanen 1");
6352 		if (dut->ap_is_dual == 1) {
6353 			run_iwpriv(dut, ifname_dual, "rnr 1");
6354 			run_iwpriv(dut, ifname_dual, "rnr_tbtt 1");
6355 			run_iwpriv(dut, ifname_dual, "apchanrpt 1");
6356 			run_iwpriv(dut, basedev_radio, "acs_ctrlflags 0x4");
6357 			run_iwpriv(dut, basedev_radio, "acs_scanintvl 60");
6358 			run_iwpriv(dut, basedev_radio, "acs_bkscanen 1");
6359 		}
6360 	}
6361 
6362 	if (dut->ap_blechanutil || dut->ap_ble_admit_cap || dut->ap_blestacnt) {
6363 		run_iwpriv(dut, ifname, "qbssload 0");
6364 		snprintf(buf, sizeof(buf),
6365 			 "wlanconfig %s addie ftype 0 len 7 data 0b05%02x%02x%02x%02x%02x ",
6366 			 ifname, dut->ap_blestacnt & 0xFF,
6367 			 dut->ap_blestacnt >> 8, dut->ap_blechanutil,
6368 			 dut->ap_ble_admit_cap & 0xFF,
6369 			 dut->ap_ble_admit_cap >> 8);
6370 		run_system(dut, buf);
6371 		snprintf(buf, sizeof(buf),
6372 			 "wlanconfig %s addie ftype 2 len 7 data 0b05%02x%02x%02x%02x%02x ",
6373 			 ifname, dut->ap_blestacnt & 0xFF,
6374 			 dut->ap_blestacnt >> 8, dut->ap_blechanutil,
6375 			 dut->ap_ble_admit_cap & 0xFF,
6376 			 dut->ap_ble_admit_cap >> 8);
6377 		run_system(dut, buf);
6378 	}
6379 
6380 	if (dut->ap_esp == VALUE_ENABLED)
6381 		run_iwpriv(dut, basedev, "esp_period 5");
6382 	else if (dut->ap_esp == VALUE_DISABLED)
6383 		run_iwpriv(dut, basedev, "esp_period 0");
6384 
6385 	if (dut->ap_datappdudura)
6386 		run_iwpriv(dut, basedev, "esp_ppdu_dur %d",
6387 			   dut->ap_datappdudura);
6388 
6389 	if (dut->ap_airtimefract)
6390 		run_iwpriv(dut, basedev, "esp_airtime %d",
6391 			   dut->ap_airtimefract);
6392 
6393 	if (dut->ap_dhcp_stop) {
6394 		snprintf(buf, sizeof(buf), "/etc/init.d/dnsmasq stop");
6395 		run_system(dut, buf);
6396 	}
6397 
6398 	if (dut->ap_bawinsize)
6399 		run_iwpriv(dut, basedev, "esp_ba_window %d", dut->ap_bawinsize);
6400 
6401 	if (dut->program == PROGRAM_DPP) {
6402 		if (dut->ap_interface_2g == 1) {
6403 			run_iwpriv(dut, ifname, "set_bcn_rate 5500");
6404 			run_iwpriv(dut, ifname, "prb_rate 5500");
6405 			run_iwpriv(dut, ifname, "mgmt_rate 5500");
6406 		}
6407 
6408 		run_iwpriv(dut, basedev, "set_rxfilter 0xffffffff");
6409 		dut->hostapd_running = 1;
6410 	}
6411 
6412 	if (dut->program == PROGRAM_HE) {
6413 		/* disable sending basic triggers */
6414 		run_system_wrapper(dut,
6415 				   "wifitool %s setUnitTestCmd 0x47 2 42 0",
6416 				   ifname);
6417 		/* disable MU BAR */
6418 		run_system_wrapper(dut,
6419 				   "wifitool %s setUnitTestCmd 0x47 2 64 1",
6420 				   ifname);
6421 		/* disable PSD Boost */
6422 		run_system_wrapper(dut,
6423 				   "wifitool %s setUnitTestCmd 0x48 2 142 1",
6424 				   ifname);
6425 		/* Enable mix bw */
6426 		run_system_wrapper(dut,
6427 				   "wifitool %s setUnitTestCmd 0x47 2 141 1",
6428 				   ifname);
6429 		/* Disable preferred AC */
6430 		run_system_wrapper(dut,
6431 				   "wifitool %s setUnitTestCmd 0x48 2 186 0",
6432 				   ifname);
6433 		run_iwpriv(dut, basedev, "he_muedca_mode 0");
6434 		run_iwpriv(dut, ifname, "he_ul_ofdma 0");
6435 		run_iwpriv(dut, ifname, "he_dl_ofdma 0");
6436 		if (dut->he_set_sta_1x1 == VALUE_ENABLED) {
6437 			/* sets g_force_1x1_peer to 1 */
6438 			run_system_wrapper(dut,
6439 					   "wifitool %s setUnitTestCmd 0x48 2 118 1",
6440 					    ifname);
6441 		}
6442 		if (dut->ap_txBF) {
6443 			/* Enable SU_AX sounding */
6444 			run_iwpriv(dut, ifname, "he_sounding_mode 1");
6445 			/* Ignore TBTT for NDP */
6446 			run_system_wrapper(dut,
6447 					   "wifitool %s setUnitTestCmd 0x48 2 2 1",
6448 					   ifname);
6449 			/* g_cv_query_enable=1, i.e., cv query enable */
6450 			run_system_wrapper(dut,
6451 					   "wifitool %s setUnitTestCmd 0x47 2 7 1",
6452 					   ifname);
6453 			/* Override TPC calculations and set TxBF flag to True
6454  */
6455 			run_system_wrapper(dut,
6456 					   "wifitool %s setUnitTestCmd 0x47 2 47 1",
6457 					   ifname);
6458 		}
6459 		if (dut->device_type == AP_testbed) {
6460 			run_iwpriv(dut, ifname, "tx_stbc 0");
6461 			run_iwpriv(dut, ifname, "he_txmcsmap 0x0");
6462 			run_iwpriv(dut, ifname, "he_rxmcsmap 0x0");
6463 			run_iwpriv(dut, ifname, "he_amsdu_in_ampdu_supp 0");
6464 			run_iwpriv(dut, ifname, "he_bfee_sts_supp 0 0");
6465 			run_iwpriv(dut, ifname, "he_4xltf_800nsgi_rx 0");
6466 			run_iwpriv(dut, ifname, "he_1xltf_800nsgi_rx 0");
6467 			run_iwpriv(dut, ifname, "he_max_nc 0");
6468 			run_iwpriv(dut, ifname, "he_bsr_supp 0");
6469 			run_iwpriv(dut, ifname, "rx_stbc 0");
6470 			if (dut->ap_he_dlofdma == VALUE_DISABLED)
6471 				run_iwpriv(dut, ifname, "he_dlofdma 0");
6472 			if (dut->ap_channel <= 11) {
6473 				dut->ap_bcc = VALUE_ENABLED;
6474 				run_iwpriv(dut, ifname, "vht_11ng 0");
6475 			}
6476 			if (!dut->ap_txBF) {
6477 				run_iwpriv(dut, ifname, "he_subfer 0");
6478 				run_iwpriv(dut, ifname, "he_subfee 0");
6479 			}
6480 			if (!dut->ap_mu_txBF) {
6481 				run_iwpriv(dut, ifname, "he_mubfer 0");
6482 				run_iwpriv(dut, ifname, "he_mubfee 0");
6483 			}
6484 			if (dut->ap_cipher == AP_WEP ||
6485 			    dut->ap_cipher == AP_TKIP)
6486 				run_iwpriv(dut, ifname, "htweptkip 1");
6487 			if (dut->ap_rx_streams || dut->ap_tx_streams)
6488 				run_iwpriv(dut, ifname, "nss %d",
6489 					   dut->ap_rx_streams);
6490 		}
6491 	}
6492 
6493 	if (dut->ap_he_ulofdma == VALUE_ENABLED) {
6494 		run_iwpriv(dut, ifname, "he_ul_ofdma 1");
6495 		run_iwpriv(dut, ifname, "he_mu_edca 1");
6496 
6497 		/* Disable sounding for UL OFDMA */
6498 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0",
6499 				   ifname);
6500 
6501 		if ((dut->ap_rx_streams || dut->ap_tx_streams) &&
6502 		    dut->device_type == AP_testbed) {
6503 			unsigned int txchainmask = 0x00;
6504 
6505 			switch (dut->ap_rx_streams) {
6506 			case 1:
6507 				txchainmask = 0x01;
6508 				break;
6509 			case 2:
6510 				txchainmask = 0x03;
6511 				break;
6512 			case 3:
6513 				txchainmask = 0x07;
6514 				break;
6515 			case 4:
6516 				txchainmask = 0x0f;
6517 				break;
6518 			case 5:
6519 				txchainmask = 0x1f;
6520 				break;
6521 			case 6:
6522 				txchainmask = 0x3f;
6523 				break;
6524 			case 7:
6525 				txchainmask = 0x7f;
6526 				break;
6527 			case 8:
6528 				txchainmask = 0xff;
6529 				break;
6530 			}
6531 
6532 			run_iwpriv(dut, ifname, "he_ul_nss %d",
6533 				   dut->ap_rx_streams);
6534 			run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
6535 			run_iwpriv(dut, basedev, "rxchainmask %d", txchainmask);
6536 		}
6537 
6538 		if (dut->ap_channel == 100 && dut->device_type == AP_testbed)
6539 			run_system_wrapper(dut, "iwpriv %s inact 1000", ifname);
6540 
6541 		if (dut->he_ul_mcs)
6542 			run_iwpriv(dut, ifname, "he_ul_mcs %d", dut->he_ul_mcs);
6543 
6544 		run_iwpriv(dut, ifname, "he_ul_ltf 3");
6545 		run_iwpriv(dut, ifname, "he_ul_shortgi 3");
6546 		run_iwpriv(dut, basedev, "he_ul_trig_int 2");
6547 
6548 		/* Disable efficiency check for UL OFDMA. We do not send TBPPDU
6549 		 * for one user. With this command, we would send UL OFDMA even
6550 		 * for one user to allow testing to be done without requiring
6551 		 * more than one station. */
6552 		run_system_wrapper(dut,
6553 				   "wifitool %s setUnitTestCmd 0x47 2 131 0",
6554 				   ifname);
6555 		/* Set random RU allocation */
6556 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 9 1",
6557 				   ifname);
6558 		/* To set TBTT PPDU duration (us) */
6559 		run_system_wrapper(dut,
6560 				   "wifitool %s setUnitTestCmd 0x48 2 63 1908",
6561 				   ifname);
6562 	}
6563 
6564 	if (dut->ap_he_dlofdma == VALUE_ENABLED) {
6565 		run_iwpriv(dut, ifname, "he_dl_ofdma 1", ifname);
6566 
6567 		/* For fixed MCS */
6568 		novap_reset(dut, ifname, 0);
6569 		run_iwpriv(dut, ifname,
6570 			   "cfg80211tool %s setratemask 3 0x80f80f80 0x0f80f80f 0xf80f80f8");
6571 	}
6572 
6573 	if (dut->ap_he_ppdu == PPDU_MU && dut->ap_he_dlofdma == VALUE_ENABLED) {
6574 		/* Increase the min TX time limit for MU MIMO to disable MU MIMO
6575 		 * scheduling */
6576 		run_system_wrapper(dut,
6577 				   "wifitool %s setUnitTestCmd 0x47 2 11 1000000",
6578 				   ifname);
6579 		/* Increase the max TX time limit for DL OFDMA to enable OFDMA
6580 		 * scheduling */
6581 		run_system_wrapper(dut,
6582 				   "wifitool %s setUnitTestCmd 0x47 2 17 1000000",
6583 				   ifname);
6584 		/* Disable 'force SU schedule' to enable MU sch */
6585 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 8 0",
6586 				   ifname);
6587 		/* Enable MU 11ax support in sch algo */
6588 		run_system_wrapper(dut,
6589 				   "wifitool %s setUnitTestCmd 0x47 2 29 0",
6590 				   ifname);
6591 		/* Enable to sort RU allocation */
6592 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x4b 2 2 1",
6593 				   ifname);
6594 	}
6595 
6596 	if (dut->ap_numsounddim) {
6597 		unsigned int txchainmask = 0;
6598 
6599 		switch (dut->ap_numsounddim) {
6600 		case 1:
6601 			txchainmask = 0x01;
6602 			break;
6603 		case 2:
6604 			txchainmask = 0x03;
6605 			break;
6606 		case 3:
6607 			txchainmask = 0x07;
6608 			break;
6609 		case 4:
6610 			txchainmask = 0x0f;
6611 			break;
6612 		case 5:
6613 			txchainmask = 0x1f;
6614 			break;
6615 		case 6:
6616 			txchainmask = 0x3f;
6617 			break;
6618 		case 7:
6619 			txchainmask = 0x7f;
6620 			break;
6621 		case 8:
6622 			txchainmask = 0xff;
6623 			break;
6624 		}
6625 		run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
6626 	}
6627 
6628 	if (dut->ap_numsounddim && dut->device_type == AP_testbed) {
6629 		/* Sets g_force_1x1_peer to 1 which should be reset to zero
6630 		 * for non-MU test cases */
6631 		run_system_wrapper(dut,
6632 				   "wifitool %s setUnitTestCmd 0x48 2 118 1",
6633 				   ifname);
6634 		if (dut->ap_mu_txBF) {
6635 			/* Disable DL OFDMA */
6636 			run_system_wrapper(dut,
6637 					   "wifitool %s setUnitTestCmd 0x47 2 11 0",
6638 					   ifname);
6639 		}
6640 	}
6641 
6642 	if (dut->ap_bcc == VALUE_ENABLED) {
6643 		run_iwpriv(dut, ifname, "mode 11AHE20");
6644 		run_iwpriv(dut, ifname, "nss 2");
6645 		run_iwpriv(dut, ifname, "he_txmcsmap 0x0");
6646 		run_iwpriv(dut, ifname, "he_rxmcsmap 0x0");
6647 	}
6648 
6649 	if (dut->ap_he_frag == VALUE_ENABLED)
6650 		run_iwpriv(dut, ifname, "he_frag 1");
6651 	else if (dut->ap_he_frag == VALUE_DISABLED)
6652 		run_iwpriv(dut, ifname, "he_frag 0");
6653 
6654 	if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) {
6655 		if (dut->ap_ba_bufsize == BA_BUFSIZE_64)
6656 			run_iwpriv(dut, ifname, "ba_bufsize 0");
6657 		else
6658 			run_iwpriv(dut, ifname, "ba_bufsize 1");
6659 	}
6660 
6661 	if (dut->ap_mu_edca == VALUE_ENABLED)
6662 		run_iwpriv(dut, ifname, "he_mu_edca 1");
6663 
6664 	if (dut->ap_he_mimo == MIMO_DL) {
6665 		mubrp_commands(dut, ifname);
6666 		if (dut->device_type != AP_testbed)
6667 			run_system_wrapper(
6668 				dut, "wifitool %s setUnitTestCmd 0x48 2 100 2",
6669 				ifname);
6670 	}
6671 
6672 	if (dut->ap_he_mimo == MIMO_UL)
6673 		run_iwpriv(dut, ifname, "he_mubfee 1");
6674 
6675 	if (dut->ap_he_rtsthrshld == VALUE_ENABLED)
6676 		run_iwpriv(dut, ifname, "he_rtsthrshld 512");
6677 	else if (dut->ap_he_rtsthrshld == VALUE_DISABLED)
6678 		run_iwpriv(dut, ifname, "he_rtsthrshld 1024");
6679 
6680 	if (dut->ap_mbssid == VALUE_ENABLED &&
6681 	    (dut->ap_rx_streams || dut->ap_tx_streams) &&
6682 	    dut->device_type == AP_testbed) {
6683 		const char *ifname_1;
6684 
6685 		ifname_1= dut->ap_channel >= 36 ? "ath01" : "ath11";
6686 
6687 		/* NSS is not set in Secondary VAP for MBSSID case,
6688 		 * hence it is explicitly set here. For primary VAP
6689 		 * NSS is set during AP configuration */
6690 		run_iwpriv(dut, ifname_1, "nss %d", dut->ap_rx_streams);
6691 	}
6692 
6693 	if (dut->ap_twtresp == VALUE_ENABLED)
6694 		run_iwpriv(dut, ifname, "twt_responder 1");
6695 	else if (dut->ap_twtresp == VALUE_DISABLED)
6696 		run_iwpriv(dut, ifname, "twt_responder 0");
6697 
6698 	if (dut->program == PROGRAM_HE && dut->ap_fixed_rate) {
6699 		int nss = 0, mcs = 0;
6700 		uint16_t mcsnssmap = 0;
6701 
6702 		/* MCS 7 is used - set only nss and he_mcs.
6703 		 * Do not set mcsnssmap unless MCS is 9 or 11. */
6704 		if (dut->ap_mcs >= 9) {
6705 			if (dut->ap_mcs == 9) {
6706 				if (dut->ap_tx_streams == 1) {
6707 					nss = 1;
6708 					mcs = dut->ap_mcs;
6709 				} else if (dut->ap_tx_streams == 2) {
6710 					nss = 2;
6711 					mcs = dut->ap_mcs;
6712 				}
6713 			} else if (dut->ap_mcs == 11) {
6714 				if (dut->ap_tx_streams == 1) {
6715 					nss = 1;
6716 					mcs = dut->ap_mcs;
6717 				} else if (dut->ap_tx_streams == 2) {
6718 					nss = 2;
6719 					mcs = dut->ap_mcs;
6720 				}
6721 			}
6722 
6723 			get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs);
6724 			he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap;
6725 		}
6726 
6727 		run_iwpriv(dut, ifname, "nss %d", dut->ap_tx_streams);
6728 		run_iwpriv(dut, ifname, "he_mcs %d", dut->ap_mcs);
6729 	}
6730 
6731 	if (he_mcsnssmap) {
6732 		run_iwpriv(dut, ifname, "he_rxmcsmap %lu", he_mcsnssmap);
6733 		run_iwpriv(dut, ifname, "he_txmcsmap %lu", he_mcsnssmap);
6734 	}
6735 
6736 	if (dut->he_sounding == VALUE_ENABLED)
6737 		run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0",
6738 				   ifname);
6739 
6740 	if (dut->he_mmss)
6741 		run_iwpriv(dut, ifname, "ampduden_ovrd %d", dut->he_mmss);
6742 
6743 	if (dut->he_srctrl_allow == 0) {
6744 		/* This is a special testbed AP case to enable SR for protocol
6745 		 * testing when SRCtrl_SRValue15Allowed is specified.
6746 		 */
6747 		run_iwpriv(dut, ifname, "he_sr_enable 1");
6748 	}
6749 }
6750 
6751 
6752 static int cmd_ath_ap_config_commit(struct sigma_dut *dut,
6753 				    struct sigma_conn *conn,
6754 				    struct sigma_cmd *cmd)
6755 {
6756 	/* const char *name = get_param(cmd, "NAME"); */
6757 	char buf[100];
6758 	struct stat s;
6759 	const char *ifname = dut->ap_is_dual ? "ath1" : "ath0";
6760 	int res;
6761 
6762 	if (stat("/proc/athversion", &s) == 0) {
6763 		sigma_dut_print(dut, DUT_MSG_INFO, "Run apdown");
6764 		run_system(dut, "apdown");
6765 	}
6766 
6767 	cmd_ath_ap_radio_config(dut);
6768 
6769 	snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID=%s'", dut->ap_ssid);
6770 	run_system(dut, buf);
6771 
6772 	switch (dut->ap_key_mgmt) {
6773 	case AP_OPEN:
6774 		if (dut->ap_cipher == AP_WEP) {
6775 			run_system(dut, "cfg -a AP_SECMODE=WEP");
6776 			run_system(dut, "cfg -a AP_SECFILE=NONE");
6777 			/* shared auth mode not supported */
6778 			run_system(dut, "cfg -a AP_WEP_MODE_0=1");
6779 			run_system(dut, "cfg -a AP_WEP_MODE_1=1");
6780 			snprintf(buf, sizeof(buf),
6781 				 "cfg -a WEP_RADIO_NUM0_KEY_1=%s",
6782 				 dut->ap_wepkey);
6783 			run_system(dut, buf);
6784 			snprintf(buf, sizeof(buf),
6785 				 "cfg -a WEP_RADIO_NUM1_KEY_1=%s",
6786 				 dut->ap_wepkey);
6787 			run_system(dut, buf);
6788 		} else {
6789 			run_system(dut, "cfg -a AP_SECMODE=None");
6790 		}
6791 		break;
6792 	case AP_WPA2_PSK:
6793 	case AP_WPA2_PSK_MIXED:
6794 	case AP_WPA_PSK:
6795 		case AP_WPA2_SAE:
6796 		case AP_WPA2_PSK_SAE:
6797 		if (dut->ap_key_mgmt == AP_WPA2_PSK ||
6798 		    dut->ap_key_mgmt == AP_WPA2_SAE ||
6799 		    dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
6800 			run_system(dut, "cfg -a AP_WPA=2");
6801 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
6802 			run_system(dut, "cfg -a AP_WPA=3");
6803 		else
6804 			run_system(dut, "cfg -a AP_WPA=1");
6805 		/* TODO: SAE configuration */
6806 		run_system(dut, "cfg -a AP_SECMODE=WPA");
6807 		run_system(dut, "cfg -a AP_SECFILE=PSK");
6808 		res = snprintf(buf, sizeof(buf), "cfg -a 'PSK_KEY=%s'",
6809 			       dut->ap_passphrase);
6810 		if (res < 0 || res >= sizeof(buf))
6811 			return ERROR_SEND_STATUS;
6812 		run_system(dut, buf);
6813 		if (dut->ap_cipher == AP_CCMP_TKIP)
6814 			run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\"");
6815 		else if (dut->ap_cipher == AP_TKIP)
6816 			run_system(dut, "cfg -a AP_CYPHER=TKIP");
6817 		else
6818 			run_system(dut, "cfg -a AP_CYPHER=CCMP");
6819 		break;
6820 	case AP_WPA2_EAP:
6821 	case AP_WPA2_EAP_MIXED:
6822 	case AP_WPA_EAP:
6823 		if (dut->ap_key_mgmt == AP_WPA2_EAP)
6824 			run_system(dut, "cfg -a AP_WPA=2");
6825 		else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
6826 			run_system(dut, "cfg -a AP_WPA=3");
6827 		else
6828 			run_system(dut, "cfg -a AP_WPA=1");
6829 		run_system(dut, "cfg -a AP_SECMODE=WPA");
6830 		run_system(dut, "cfg -a AP_SECFILE=EAP");
6831 		if (dut->ap_cipher == AP_CCMP_TKIP)
6832 			run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\"");
6833 		else if (dut->ap_cipher == AP_TKIP)
6834 			run_system(dut, "cfg -a AP_CYPHER=TKIP");
6835 		else
6836 			run_system(dut, "cfg -a AP_CYPHER=CCMP");
6837 		snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER=%s",
6838 			 dut->ap_radius_ipaddr);
6839 		run_system(dut, buf);
6840 		snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT=%d",
6841 			 dut->ap_radius_port);
6842 		run_system(dut, buf);
6843 		res = snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SECRET=%s",
6844 			       dut->ap_radius_password);
6845 		if (res < 0 || res >= sizeof(buf))
6846 			return ERROR_SEND_STATUS;
6847 		run_system(dut, buf);
6848 		break;
6849 	case AP_WPA2_EAP_OSEN:
6850 		/* TODO */
6851 		sigma_dut_print(dut, DUT_MSG_ERROR, "EAP+OSEN not supported");
6852 		break;
6853 	case AP_SUITEB:
6854 		/* TODO */
6855 		sigma_dut_print(dut, DUT_MSG_ERROR, "SuiteB not supported");
6856 		break;
6857 	case AP_WPA2_OWE:
6858 		/* TODO */
6859 		sigma_dut_print(dut, DUT_MSG_ERROR, "OWE not supported");
6860 		break;
6861 	case AP_WPA2_FT_EAP:
6862 	case AP_WPA2_FT_PSK:
6863 	case AP_WPA2_EAP_SHA256:
6864 	case AP_WPA2_PSK_SHA256:
6865 	case AP_WPA2_ENT_FT_EAP:
6866 	case AP_OSEN:
6867 		/* TODO */
6868 		send_resp(dut, conn, SIGMA_ERROR,
6869 			  "errorCode,Unsupported KeyMgnt value");
6870 		return 0;
6871 	}
6872 
6873 	if (dut->ap_is_dual) {
6874 		/* ath1 settings in case of dual */
6875 		snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID_2=%s'",
6876 			 dut->ap_ssid);
6877 		run_system(dut, buf);
6878 
6879 		switch (dut->ap_key_mgmt) {
6880 		case AP_OPEN:
6881 			if (dut->ap_cipher == AP_WEP) {
6882 				run_system(dut, "cfg -a AP_SECMODE_2=WEP");
6883 				run_system(dut, "cfg -a AP_SECFILE_2=NONE");
6884 				/* shared auth mode not supported */
6885 				run_system(dut, "cfg -a AP_WEP_MODE_0=1");
6886 				run_system(dut, "cfg -a AP_WEP_MODE_1=1");
6887 				snprintf(buf, sizeof(buf),
6888 					 "cfg -a WEP_RADIO_NUM0_KEY_1=%s",
6889 					 dut->ap_wepkey);
6890 				run_system(dut, buf);
6891 				snprintf(buf, sizeof(buf),
6892 					 "cfg -a WEP_RADIO_NUM1_KEY_1=%s",
6893 					 dut->ap_wepkey);
6894 				run_system(dut, buf);
6895 			} else {
6896 				run_system(dut, "cfg -a AP_SECMODE_2=None");
6897 			}
6898 			break;
6899 		case AP_WPA2_PSK:
6900 		case AP_WPA2_PSK_MIXED:
6901 		case AP_WPA_PSK:
6902 		case AP_WPA2_SAE:
6903 		case AP_WPA2_PSK_SAE:
6904 			if (dut->ap_key_mgmt == AP_WPA2_PSK ||
6905 			    dut->ap_key_mgmt == AP_WPA2_SAE ||
6906 			    dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
6907 				run_system(dut, "cfg -a AP_WPA_2=2");
6908 			else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
6909 				run_system(dut, "cfg -a AP_WPA_2=3");
6910 			else
6911 				run_system(dut, "cfg -a AP_WPA_2=1");
6912 			// run_system(dut, "cfg -a AP_WPA_2=2");
6913 			/* TODO: SAE configuration */
6914 			run_system(dut, "cfg -a AP_SECMODE_2=WPA");
6915 			run_system(dut, "cfg -a AP_SECFILE_2=PSK");
6916 			res = snprintf(buf, sizeof(buf),
6917 				       "cfg -a 'PSK_KEY_2=%s'",
6918 				       dut->ap_passphrase);
6919 			if (res < 0 || res >= sizeof(buf))
6920 				return ERROR_SEND_STATUS;
6921 			run_system(dut, buf);
6922 			if (dut->ap_cipher == AP_CCMP_TKIP)
6923 				run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\"");
6924 			else if (dut->ap_cipher == AP_TKIP)
6925 				run_system(dut, "cfg -a AP_CYPHER_2=TKIP");
6926 			else
6927 				run_system(dut, "cfg -a AP_CYPHER_2=CCMP");
6928 			break;
6929 		case AP_WPA2_EAP:
6930 		case AP_WPA2_EAP_MIXED:
6931 		case AP_WPA_EAP:
6932 			if (dut->ap_key_mgmt == AP_WPA2_EAP)
6933 				run_system(dut, "cfg -a AP_WPA_2=2");
6934 			else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
6935 				run_system(dut, "cfg -a AP_WPA_2=3");
6936 			else
6937 				run_system(dut, "cfg -a AP_WPA_2=1");
6938 			run_system(dut, "cfg -a AP_SECMODE_2=WPA");
6939 			run_system(dut, "cfg -a AP_SECFILE_2=EAP");
6940 			if (dut->ap_cipher == AP_CCMP_TKIP)
6941 				run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\"");
6942 			else if (dut->ap_cipher == AP_TKIP)
6943 				run_system(dut, "cfg -a AP_CYPHER_2=TKIP");
6944 			else
6945 				run_system(dut, "cfg -a AP_CYPHER_2=CCMP");
6946 
6947 			snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER_2=%s",
6948 				 dut->ap_radius_ipaddr);
6949 			run_system(dut, buf);
6950 			snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT_2=%d",
6951 				 dut->ap_radius_port);
6952 			run_system(dut, buf);
6953 			res = snprintf(buf, sizeof(buf),
6954 				       "cfg -a AP_AUTH_SECRET_2=%s",
6955 				       dut->ap_radius_password);
6956 			if (res < 0 || res >= sizeof(buf))
6957 				return ERROR_SEND_STATUS;
6958 			run_system(dut, buf);
6959 			break;
6960 		case AP_WPA2_EAP_OSEN:
6961 			/* TODO */
6962 			sigma_dut_print(dut, DUT_MSG_ERROR,
6963 					"EAP+OSEN not supported");
6964 			break;
6965 		case AP_SUITEB:
6966 			/* TODO */
6967 			sigma_dut_print(dut, DUT_MSG_ERROR,
6968 					"SuiteB not supported");
6969 			break;
6970 		case AP_WPA2_OWE:
6971 			/* TODO */
6972 			sigma_dut_print(dut, DUT_MSG_ERROR,
6973 					"OWE not supported");
6974 			break;
6975 		case AP_WPA2_FT_EAP:
6976 		case AP_WPA2_FT_PSK:
6977 		case AP_WPA2_EAP_SHA256:
6978 		case AP_WPA2_PSK_SHA256:
6979 		case AP_WPA2_ENT_FT_EAP:
6980 		case AP_OSEN:
6981 			/* TODO */
6982 			send_resp(dut, conn, SIGMA_ERROR,
6983 				  "errorCode,Unsupported KeyMgnt value");
6984 			return 0;
6985 		}
6986 
6987 		/* wifi0 settings in case of dual */
6988 		run_system(dut, "cfg -a AP_RADIO_ID=0");
6989 		run_system(dut, "cfg -a AP_PRIMARY_CH=6");
6990 		run_system(dut, "cfg -a AP_STARTMODE=dual");
6991 		run_system(dut, "cfg -a AP_CHMODE=11NGHT40PLUS");
6992 		run_system(dut, "cfg -a TX_CHAINMASK=7");
6993 		run_system(dut, "cfg -a RX_CHAINMASK=7");
6994 	}
6995 
6996 	switch (dut->ap_pmf) {
6997 	case AP_PMF_DISABLED:
6998 		snprintf(buf, sizeof(buf), "cfg -a AP_PMF=0");
6999 		run_system(dut, buf);
7000 		break;
7001 	case AP_PMF_OPTIONAL:
7002 		snprintf(buf, sizeof(buf), "cfg -a AP_PMF=1");
7003 		run_system(dut, buf);
7004 		break;
7005 	case AP_PMF_REQUIRED:
7006 		snprintf(buf, sizeof(buf), "cfg -a AP_PMF=2");
7007 		run_system(dut, buf);
7008 		break;
7009 	}
7010 	if (dut->ap_add_sha256) {
7011 		snprintf(buf, sizeof(buf), "cfg -a AP_WPA_SHA256=1");
7012 		run_system(dut, buf);
7013 	} else {
7014 		snprintf(buf, sizeof(buf), "cfg -r AP_WPA_SHA256");
7015 		run_system(dut, buf);
7016 	}
7017 
7018 	if (dut->ap_hs2)
7019 		run_system(dut, "cfg -a AP_HOTSPOT=1");
7020 	else
7021 		run_system(dut, "cfg -r AP_HOTSPOT");
7022 
7023 	if (dut->ap_interworking) {
7024 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_ANT=%d",
7025 			 dut->ap_access_net_type);
7026 		run_system(dut, buf);
7027 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_INTERNET=%d",
7028 			 dut->ap_internet);
7029 		run_system(dut, buf);
7030 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUEGROUP=%d",
7031 			 dut->ap_venue_group);
7032 		run_system(dut, buf);
7033 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUETYPE=%d",
7034 			 dut->ap_venue_type);
7035 		run_system(dut, buf);
7036 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=%s",
7037 			 dut->ap_hessid);
7038 		run_system(dut, buf);
7039 
7040 		if (dut->ap_roaming_cons[0]) {
7041 			char *second, *rc;
7042 			rc = strdup(dut->ap_roaming_cons);
7043 			if (rc == NULL)
7044 				return 0;
7045 
7046 			second = strchr(rc, ';');
7047 			if (second)
7048 				*second++ = '\0';
7049 
7050 			snprintf(buf, sizeof(buf),
7051 				 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=%s", rc);
7052 			run_system(dut, buf);
7053 
7054 			if (second) {
7055 				snprintf(buf, sizeof(buf),
7056 					 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2"
7057 					 "=%s", second);
7058 				run_system(dut, buf);
7059 			}
7060 			free(rc);
7061 		} else {
7062 			run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM");
7063 			run_system(dut,
7064 				   "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2");
7065 		}
7066 	} else {
7067 		run_system(dut, "cfg -r AP_HOTSPOT_ANT");
7068 		run_system(dut, "cfg -r AP_HOTSPOT_INTERNET");
7069 		run_system(dut, "cfg -r AP_HOTSPOT_VENUEGROUP");
7070 		run_system(dut, "cfg -r AP_HOTSPOT_VENUETYPE");
7071 		run_system(dut, "cfg -r AP_HOTSPOT_HESSID");
7072 		run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM");
7073 		run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2");
7074 	}
7075 
7076 	if (dut->ap_proxy_arp)
7077 		run_system(dut, "cfg -a IEEE80211V_PROXYARP=1");
7078 	else
7079 		run_system(dut, "cfg -a IEEE80211V_PROXYARP=0");
7080 	if (dut->ap_dgaf_disable)
7081 		run_system(dut, "cfg -a AP_HOTSPOT_DISABLE_DGAF=1");
7082 	else
7083 		run_system(dut, "cfg -r AP_HOTSPOT_DISABLE_DGAF");
7084 
7085 	if (strlen(dut->ap_tag_ssid[0])) {
7086 		snprintf(buf, sizeof(buf),
7087 			 "cfg -a AP_SSID_2=%s", dut->ap_tag_ssid[0]);
7088 		run_system(dut, buf);
7089 
7090 		if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) {
7091 			run_system(dut, "cfg -a AP_SECMODE_2=WPA");
7092 			run_system(dut, "cfg -a AP_SECFILE_2=OSEN");
7093 
7094 			res = snprintf(buf, sizeof(buf),
7095 				       "cfg -a AP_AUTH_SERVER_2=%s",
7096 				       dut->ap2_radius_ipaddr);
7097 			if (res < 0 || res >= sizeof(buf))
7098 				return ERROR_SEND_STATUS;
7099 			run_system(dut, buf);
7100 
7101 			res = snprintf(buf, sizeof(buf),
7102 				       "cfg -a AP_AUTH_PORT_2=%d",
7103 				       dut->ap2_radius_port);
7104 			if (res < 0 || res >= sizeof(buf))
7105 				return ERROR_SEND_STATUS;
7106 			run_system(dut, buf);
7107 
7108 			res = snprintf(buf, sizeof(buf),
7109 				       "cfg -a AP_AUTH_SECRET_2=%s",
7110 				       dut->ap2_radius_password);
7111 			if (res < 0 || res >= sizeof(buf))
7112 				return ERROR_SEND_STATUS;
7113 			run_system(dut, buf);
7114 		} else {
7115 			run_system(dut, "cfg -a AP_SECMODE_2=None");
7116 			run_system(dut, "cfg -r AP_AUTH_SERVER_2");
7117 			run_system(dut, "cfg -r AP_AUTH_PORT_2");
7118 			run_system(dut, "cfg -r AP_AUTH_SECRET_2");
7119 		}
7120 
7121 		run_system(dut, "cfg -a AP_STARTMODE=multi");
7122 	}
7123 
7124 	run_system(dut, "cfg -c");
7125 
7126 	sigma_dut_print(dut, DUT_MSG_INFO, "Starting AP");
7127 	if (system("apup") != 0) {
7128 		/* to be debugged why apup returns error
7129 		send_resp(dut, conn, SIGMA_ERROR,
7130 			  "errorCode,apup failed");
7131 		return 0;
7132 		*/
7133 	}
7134 	sigma_dut_print(dut, DUT_MSG_INFO, "AP started");
7135 
7136 	if (dut->ap_key_mgmt != AP_OPEN) {
7137 		int res;
7138 		/* allow some time for hostapd to start before returning
7139 		 * success */
7140 		usleep(500000);
7141 		if (run_hostapd_cli(dut, "ping") != 0) {
7142 			send_resp(dut, conn, SIGMA_ERROR,
7143 				  "errorCode,Failed to talk to hostapd");
7144 			return 0;
7145 		}
7146 
7147 		if (dut->ap_hs2 && !dut->ap_anqpserver) {
7148 			/* the cfg app doesn't like ";" in the variables */
7149 			res = ath_ap_append_hostapd_conf(dut);
7150 			if (res < 0)
7151 				return res;
7152 
7153 			/* wait for hostapd to be ready */
7154 			usleep(500000);
7155 			if (run_hostapd_cli(dut, "ping") != 0) {
7156 				send_resp(dut, conn, SIGMA_ERROR,
7157 					  "errorCode,Failed to talk to "
7158 					  "hostapd");
7159 				return 0;
7160 			}
7161 		}
7162 	}
7163 
7164 	ath_ap_set_params(dut);
7165 
7166 	if (dut->ap_anqpserver)
7167 		return cmd_ath_ap_anqpserver_start(dut);
7168 
7169 	if (dut->ap2_proxy_arp)
7170 		run_iwpriv(dut, ifname, "proxy_arp 1");
7171 
7172 	if (dut->ap_allow_vht_wep || dut->ap_allow_vht_tkip)
7173 		run_iwpriv(dut, ifname, "htweptkip 1");
7174 
7175 	return 1;
7176 }
7177 
7178 
7179 static int set_ebtables_proxy_arp(struct sigma_dut *dut, const char *chain,
7180 				  const char *ifname)
7181 {
7182 	char buf[200];
7183 
7184 	if (!chain || !ifname)
7185 		return -2;
7186 
7187 	snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain);
7188 	if (system(buf) != 0) {
7189 		sigma_dut_print(dut, DUT_MSG_ERROR,
7190 				"Failed to set ebtables rules, RULE-1, %s",
7191 				chain);
7192 		return -2;
7193 	}
7194 
7195 	snprintf(buf, sizeof(buf),
7196 		 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP",
7197 		 chain, ifname);
7198 	if (system(buf) != 0) {
7199 		sigma_dut_print(dut, DUT_MSG_ERROR,
7200 				"Failed to set ebtables rules, RULE-2, %s",
7201 				chain);
7202 		return -2;
7203 	}
7204 
7205 	snprintf(buf, sizeof(buf),
7206 		 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-solicitation -o %s -j DROP",
7207 		 chain, ifname);
7208 	if (system(buf) != 0) {
7209 		sigma_dut_print(dut, DUT_MSG_ERROR,
7210 				"Failed to set ebtables rules, RULE-3, %s",
7211 				chain);
7212 		return -2;
7213 	}
7214 
7215 	snprintf(buf, sizeof(buf),
7216 		 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-advertisement -o %s -j DROP",
7217 		 chain, ifname);
7218 	if (system(buf) != 0) {
7219 		sigma_dut_print(dut, DUT_MSG_ERROR,
7220 				"Failed to set ebtables rules, RULE-4, %s",
7221 				chain);
7222 		return -2;
7223 	}
7224 
7225 	return 0;
7226 }
7227 
7228 
7229 static int set_ebtables_disable_dgaf(struct sigma_dut *dut,
7230 				     const char *chain,
7231 				     const char *ifname)
7232 {
7233 	char buf[200];
7234 
7235 	if (!chain || !ifname)
7236 		return -2;
7237 
7238 	snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain);
7239 	if (system(buf) != 0) {
7240 		sigma_dut_print(dut, DUT_MSG_ERROR,
7241 				"Failed to set ebtables rules, RULE-5, %s",
7242 				chain);
7243 		return -2;
7244 	}
7245 
7246 	snprintf(buf, sizeof(buf),
7247 		 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP",
7248 		 chain, ifname);
7249 	if (system(buf) != 0) {
7250 		sigma_dut_print(dut, DUT_MSG_ERROR,
7251 				"Failed to set ebtables rules, RULE-6, %s",
7252 				chain);
7253 		return -2;
7254 	}
7255 
7256 	snprintf(buf, sizeof(buf),
7257 		 "ebtables -A %s -p IPv4 -d Multicast -o %s -j DROP",
7258 		 chain, ifname);
7259 	if (system(buf) != 0) {
7260 		sigma_dut_print(dut, DUT_MSG_ERROR,
7261 				"Failed to set ebtables rules, RULE-7, %s",
7262 				chain);
7263 		return -2;
7264 	}
7265 
7266 	snprintf(buf, sizeof(buf),
7267 		 "ebtables -A %s -p IPv6 -d Multicast -o %s -j DROP",
7268 		 chain, ifname);
7269 	if (system(buf) != 0) {
7270 		sigma_dut_print(dut, DUT_MSG_ERROR,
7271 				"Failed to set ebtables rules, RULE-8, %s",
7272 				chain);
7273 		return -2;
7274 	}
7275 
7276 	return 0;
7277 }
7278 
7279 
7280 static void set_ebtables_forward_drop(struct sigma_dut *dut,
7281 				      const char *ifname, const char *ifname2)
7282 {
7283 	char buf[128];
7284 
7285 	snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP",
7286 		 ifname, ifname2);
7287 	if (system(buf) != 0)
7288 		sigma_dut_print(dut, DUT_MSG_ERROR,
7289 				"Failed to set ebtables rule");
7290 
7291 	snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP",
7292 		 ifname2, ifname);
7293 	if (system(buf) != 0)
7294 		sigma_dut_print(dut, DUT_MSG_ERROR,
7295 				"Failed to set ebtables rule");
7296 }
7297 
7298 
7299 static int check_channel(int channel)
7300 {
7301 	int channel_list[] = { 36, 40, 44, 48, 52, 60, 64, 100, 104, 108, 112,
7302 			       116, 120, 124, 128, 132, 140, 144, 149, 153, 157,
7303 			       161, 165 };
7304 	int num_chan = sizeof(channel_list) / sizeof(int);
7305 	int i;
7306 
7307 	for (i = 0; i < num_chan; i++) {
7308 		if (channel == channel_list[i])
7309 			return i;
7310 	}
7311 
7312 	return -1;
7313 }
7314 
7315 
7316 static int get_oper_centr_freq_seq_idx(int chwidth, int channel)
7317 {
7318 	int ch_base;
7319 	int period;
7320 
7321 	if (check_channel(channel) < 0)
7322 		return -1;
7323 
7324 	if (channel >= 36 && channel <= 64)
7325 		ch_base = 36;
7326 	else if (channel >= 100 && channel <= 144)
7327 		ch_base = 100;
7328 	else
7329 		ch_base = 149;
7330 
7331 	period = channel % ch_base * 5 / chwidth;
7332 	return ch_base + period * chwidth / 5 + (chwidth - 20) / 10;
7333 }
7334 
7335 
7336 static int is_ht40plus_chan(int chan)
7337 {
7338 	return chan == 36 || chan == 44 || chan == 52 || chan == 60 ||
7339 		chan == 100 || chan == 108 || chan == 116 || chan == 124 ||
7340 		chan == 132 || chan == 149 || chan == 157;
7341 }
7342 
7343 
7344 static int is_ht40minus_chan(int chan)
7345 {
7346 	return chan == 40 || chan == 48 || chan == 56 || chan == 64 ||
7347 		chan == 104 || chan == 112 || chan == 120 || chan == 128 ||
7348 		chan == 136 || chan == 144 || chan == 153 || chan == 161;
7349 }
7350 
7351 
7352 static int get_5g_channel_freq(int chan)
7353 {
7354 	return 5000 + chan * 5;
7355 }
7356 
7357 
7358 static const char * hostapd_cipher_name(enum ap_cipher cipher)
7359 {
7360 	switch (cipher) {
7361 	case AP_CCMP:
7362 		return "CCMP";
7363 	case AP_TKIP:
7364 		return "TKIP";
7365 	case AP_CCMP_TKIP:
7366 		return "CCMP TKIP";
7367 	case AP_GCMP_256:
7368 		return "GCMP-256";
7369 	case AP_GCMP_128:
7370 		return "GCMP";
7371 	case AP_CCMP_256:
7372 		return "CCMP-256";
7373 	case AP_CCMP_128_GCMP_256:
7374 		return "CCMP GCMP-256";
7375 	default:
7376 		return "UNKNOWN";
7377 	}
7378 }
7379 
7380 
7381 static const char *
7382 hostapd_group_mgmt_cipher_name(enum ap_group_mgmt_cipher cipher)
7383 {
7384 	switch (cipher) {
7385 	case AP_BIP_GMAC_256:
7386 		return "BIP-GMAC-256";
7387 	case AP_BIP_CMAC_256:
7388 		return "BIP-CMAC-256";
7389 	case AP_BIP_GMAC_128:
7390 		return "BIP-GMAC-128";
7391 	case AP_BIP_CMAC_128:
7392 		return "AES-128-CMAC";
7393 	default:
7394 		return "UNKNOWN";
7395 	}
7396 }
7397 
7398 
7399 static int ap_set_60g_ese(struct sigma_dut *dut, int count,
7400 			  struct sigma_ese_alloc *allocs)
7401 {
7402 	switch (get_driver_type(dut)) {
7403 #ifdef __linux__
7404 	case DRIVER_WIL6210:
7405 		return wil6210_set_ese(dut, count, allocs);
7406 #endif /* __linux__ */
7407 	default:
7408 		sigma_dut_print(dut, DUT_MSG_ERROR,
7409 				"Unsupported ap_set_60g_ese with the current driver");
7410 		return -1;
7411 	}
7412 }
7413 
7414 
7415 static int ap_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7416 {
7417 	switch (get_driver_type(dut)) {
7418 #ifdef __linux__
7419 	case DRIVER_WIL6210:
7420 		return wil6210_set_force_mcs(dut, force, mcs);
7421 #endif /* __linux__ */
7422 	default:
7423 		sigma_dut_print(dut, DUT_MSG_ERROR,
7424 				"Unsupported ap_set_force_mcs with the current driver");
7425 		return -1;
7426 	}
7427 }
7428 
7429 
7430 enum sigma_cmd_result cmd_ap_config_commit(struct sigma_dut *dut,
7431 					   struct sigma_conn *conn,
7432 					   struct sigma_cmd *cmd)
7433 {
7434 	/* const char *name = get_param(cmd, "NAME"); */
7435 	FILE *f;
7436 	const char *ifname;
7437 	char buf[500];
7438 	char path[100];
7439 	char ap_conf_path[100];
7440 	enum driver_type drv;
7441 	const char *key_mgmt;
7442 #ifdef ANDROID
7443 	struct group *gr;
7444 #endif /* ANDROID */
7445 
7446 	drv = get_driver_type(dut);
7447 
7448 	if (dut->mode == SIGMA_MODE_STATION) {
7449 		stop_sta_mode(dut);
7450 		sleep(1);
7451 	}
7452 
7453 	if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) {
7454 		snprintf(buf, sizeof(buf), "ifconfig %s down",
7455 			 dut->sniffer_ifname);
7456 		if (system(buf) != 0) {
7457 			sigma_dut_print(dut, DUT_MSG_INFO,
7458 					"Failed to run '%s'", buf);
7459 		}
7460 		snprintf(buf, sizeof(buf), "iw dev %s set type station",
7461 			 dut->sniffer_ifname);
7462 		if (system(buf) != 0) {
7463 			sigma_dut_print(dut, DUT_MSG_INFO,
7464 					"Failed to run '%s'", buf);
7465 		}
7466 	}
7467 
7468 	dut->mode = SIGMA_MODE_AP;
7469 
7470 	if (drv == DRIVER_ATHEROS)
7471 		return cmd_ath_ap_config_commit(dut, conn, cmd);
7472 	if (drv == DRIVER_WCN)
7473 		return cmd_wcn_ap_config_commit(dut, conn, cmd);
7474 	if (drv == DRIVER_OPENWRT)
7475 		return cmd_owrt_ap_config_commit(dut, conn, cmd);
7476 
7477 	concat_sigma_tmpdir(dut, "/sigma_dut-ap.conf", ap_conf_path,
7478 			    sizeof(ap_conf_path));
7479 	f = fopen(ap_conf_path, "w");
7480 	if (f == NULL) {
7481 		sigma_dut_print(dut, DUT_MSG_ERROR,
7482 				"%s: Failed to open sigma_dut-ap.conf",
7483 				__func__);
7484 		return -2;
7485 	}
7486 
7487 	ifname = get_hostapd_ifname(dut);
7488 
7489 	switch (dut->ap_mode) {
7490 	case AP_11g:
7491 	case AP_11b:
7492 	case AP_11ng:
7493 		fprintf(f, "hw_mode=g\n");
7494 		break;
7495 	case AP_11a:
7496 	case AP_11na:
7497 	case AP_11ac:
7498 		fprintf(f, "hw_mode=a\n");
7499 		break;
7500 	case AP_11ad:
7501 		fprintf(f, "hw_mode=ad\n");
7502 		break;
7503 	case AP_11ax:
7504 		if (dut->use_5g)
7505 			fprintf(f, "hw_mode=a\n");
7506 		else
7507 			fprintf(f, "hw_mode=g\n");
7508 		break;
7509 	default:
7510 		fclose(f);
7511 		return -1;
7512 	}
7513 
7514 	if (drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN)
7515 		fprintf(f, "driver=nl80211\n");
7516 
7517 	if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7518 	     drv == DRIVER_LINUX_WCN) &&
7519 	    (dut->ap_mode == AP_11ng || dut->ap_mode == AP_11na ||
7520 	     (dut->ap_mode == AP_11ax && !dut->use_5g))) {
7521 		int ht40plus = 0, ht40minus = 0, tx_stbc = 0;
7522 
7523 		fprintf(f, "ieee80211n=1\n");
7524 		if (dut->ap_mode == AP_11ax)
7525 			fprintf(f, "ieee80211ax=1\n");
7526 		if (dut->ap_mode == AP_11ng &&
7527 		    (dut->ap_chwidth == AP_40 ||
7528 		     (dut->ap_chwidth == AP_AUTO &&
7529 		      dut->default_11ng_ap_chwidth == AP_40))) {
7530 			if (dut->ap_channel >= 1 && dut->ap_channel <= 7)
7531 				ht40plus = 1;
7532 			else if (dut->ap_channel >= 8 && dut->ap_channel <= 11)
7533 				ht40minus = 1;
7534 			fprintf(f, "obss_interval=300\n");
7535 		}
7536 
7537 		/* configure ht_capab based on channel width */
7538 		if (dut->ap_mode == AP_11na &&
7539 		    (dut->ap_chwidth == AP_40 ||
7540 		     (dut->ap_chwidth == AP_AUTO &&
7541 		      dut->default_11na_ap_chwidth == AP_40))) {
7542 			if (is_ht40plus_chan(dut->ap_channel))
7543 				ht40plus = 1;
7544 			else if (is_ht40minus_chan(dut->ap_channel))
7545 				ht40minus = 1;
7546 		}
7547 
7548 		if (dut->ap_tx_stbc)
7549 			tx_stbc = 1;
7550 
7551 		/* Overwrite the ht_capab with offset value if configured */
7552 		if (dut->ap_chwidth == AP_40 &&
7553 		    dut->ap_chwidth_offset == SEC_CH_40ABOVE) {
7554 			ht40plus = 1;
7555 			ht40minus = 0;
7556 		} else if (dut->ap_chwidth == AP_40 &&
7557 			   dut->ap_chwidth_offset == SEC_CH_40BELOW) {
7558 			ht40minus = 1;
7559 			ht40plus = 0;
7560 		}
7561 
7562 		fprintf(f, "ht_capab=%s%s%s\n",
7563 			ht40plus ? "[HT40+]" : "",
7564 			ht40minus ? "[HT40-]" : "",
7565 			tx_stbc ? "[TX-STBC]" : "");
7566 	}
7567 
7568 	if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7569 	     drv == DRIVER_LINUX_WCN) &&
7570 	    (dut->ap_mode == AP_11ac ||
7571 	    (dut->ap_mode == AP_11ax && dut->use_5g))) {
7572 		int ht40plus = 0, ht40minus = 0;
7573 
7574 		fprintf(f, "ieee80211ac=1\n"
7575 			"ieee80211n=1\n");
7576 		if (dut->ap_mode == AP_11ax)
7577 			fprintf(f, "ieee80211ax=1\n");
7578 
7579 		/* configure ht_capab based on channel width */
7580 		if (dut->ap_chwidth != AP_20) {
7581 			if (is_ht40plus_chan(dut->ap_channel))
7582 				ht40plus = 1;
7583 			else if (is_ht40minus_chan(dut->ap_channel))
7584 				ht40minus = 1;
7585 
7586 			fprintf(f, "ht_capab=%s%s\n",
7587 				ht40plus ? "[HT40+]" : "",
7588 				ht40minus ? "[HT40-]" : "");
7589 		}
7590 	}
7591 
7592 	if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7593 	     drv == DRIVER_LINUX_WCN) &&
7594 	    (dut->ap_mode == AP_11ac || dut->ap_mode == AP_11na)) {
7595 		if (dut->ap_countrycode[0]) {
7596 			fprintf(f, "country_code=%s\n", dut->ap_countrycode);
7597 			fprintf(f, "ieee80211d=1\n");
7598 			fprintf(f, "ieee80211h=1\n");
7599 		}
7600 	}
7601 
7602 	if (drv == DRIVER_LINUX_WCN && dut->ap_mode == AP_11ax) {
7603 		if (dut->ap_txBF) {
7604 			fprintf(f, "he_su_beamformer=1\n");
7605 			fprintf(f, "he_su_beamformee=1\n");
7606 			if (dut->ap_mu_txBF)
7607 				fprintf(f, "he_mu_beamformer=1\n");
7608 		} else {
7609 			fprintf(f, "he_su_beamformer=0\n");
7610 			fprintf(f, "he_su_beamformee=0\n");
7611 			fprintf(f, "he_mu_beamformer=0\n");
7612 		}
7613 	}
7614 
7615 	fprintf(f, "interface=%s\n", ifname);
7616 	if (dut->bridge)
7617 		fprintf(f, "bridge=%s\n", dut->bridge);
7618 	fprintf(f, "channel=%d\n", dut->ap_channel);
7619 
7620 	if (sigma_hapd_ctrl)
7621 		fprintf(f, "ctrl_interface=%s\n", sigma_hapd_ctrl);
7622 	else
7623 		fprintf(f, "ctrl_interface=/var/run/hostapd\n");
7624 
7625 	if (dut->ap_ssid[0])
7626 		fprintf(f, "ssid=%s\n", dut->ap_ssid);
7627 	else
7628 		fprintf(f, "ssid=QCA AP OOB\n");
7629 	if (dut->ap_bcnint)
7630 		fprintf(f, "beacon_int=%d\n", dut->ap_bcnint);
7631 	if (dut->ap_start_disabled)
7632 		fprintf(f, "start_disabled=1\n");
7633 
7634 	if (dut->ap_akm_values) {
7635 		struct {
7636 			int akm;
7637 			const char *str;
7638 		} akms[] = {
7639 			{ AKM_WPA_EAP, "WPA-EAP" },
7640 			{ AKM_WPA_PSK, "WPA-PSK" },
7641 			{ AKM_FT_EAP, "FT-EAP" },
7642 			{ AKM_FT_PSK, "FT-PSK" },
7643 			{ AKM_EAP_SHA256, "WPA-EAP-SHA256" },
7644 			{ AKM_PSK_SHA256, "WPA-PSK-SHA256" },
7645 			{ AKM_SAE, "SAE" },
7646 			{ AKM_FT_SAE, "FT-SAE" },
7647 			{ AKM_SUITE_B, "WPA-EAP-SUITE-B-192" },
7648 			{ AKM_FT_SUITE_B, "FT-EAP-SHA384" },
7649 			{ AKM_FILS_SHA256, "FILS-SHA256" },
7650 			{ AKM_FILS_SHA384, "FILS-SHA384" },
7651 			{ AKM_FT_FILS_SHA256, "FT-FILS-SHA256" },
7652 			{ AKM_FT_FILS_SHA384, "FT-FILS-SHA384" },
7653 		};
7654 		int first = 1;
7655 		unsigned int i;
7656 
7657 		fprintf(f, "wpa_key_mgmt=");
7658 		for (i = 0; i < ARRAY_SIZE(akms); i++) {
7659 			if (dut->ap_akm_values & (1 << akms[i].akm)) {
7660 				fprintf(f, "%s%s", first ? "" : " ",
7661 					akms[i].str);
7662 				first = 0;
7663 			}
7664 		}
7665 		fprintf(f, "\n");
7666 		/* TODO: mixed mode and WPAv1 only */
7667 		fprintf(f, "wpa=2\n");
7668 		fprintf(f, "wpa_pairwise=%s\n",
7669 			hostapd_cipher_name(dut->ap_cipher));
7670 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7671 			fprintf(f, "group_cipher=%s\n",
7672 				hostapd_cipher_name(dut->ap_group_cipher));
7673 		if ((dut->ap_akm_values &
7674 		     ((1 << AKM_SAE) | (1 << AKM_FT_SAE))) &&
7675 		    !(dut->ap_akm_values &
7676 		      ((1 << AKM_WPA_PSK) | (1 << AKM_FT_PSK))) &&
7677 		    dut->ap_passphrase[0])
7678 			fprintf(f, "sae_password=%s\n", dut->ap_passphrase);
7679 		else if (!dut->ap_passphrase[0] && dut->ap_psk[0])
7680 			fprintf(f, "wpa_psk=%s", dut->ap_psk);
7681 		else if (dut->ap_passphrase[0])
7682 			fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase);
7683 		if (dut->ap_akm_values & ((1 << AKM_WPA_EAP) |
7684 					  (1 << AKM_FT_EAP) |
7685 					  (1 << AKM_EAP_SHA256) |
7686 					  (1 << AKM_SUITE_B) |
7687 					  (1 << AKM_FT_SUITE_B) |
7688 					  (1 << AKM_FILS_SHA256) |
7689 					  (1 << AKM_FILS_SHA384) |
7690 					  (1 << AKM_FT_FILS_SHA256) |
7691 					  (1 << AKM_FT_FILS_SHA384))) {
7692 			fprintf(f, "ieee8021x=1\n");
7693 			fprintf(f, "auth_server_addr=%s\n",
7694 				dut->ap_radius_ipaddr);
7695 			if (dut->ap_radius_port)
7696 				fprintf(f, "auth_server_port=%d\n",
7697 					dut->ap_radius_port);
7698 			fprintf(f, "auth_server_shared_secret=%s\n",
7699 				dut->ap_radius_password);
7700 		}
7701 		goto skip_key_mgmt;
7702 	}
7703 
7704 	switch (dut->ap_key_mgmt) {
7705 	case AP_OPEN:
7706 		if (dut->ap_cipher == AP_WEP)
7707 			fprintf(f, "wep_key0=%s\n", dut->ap_wepkey);
7708 		break;
7709 	case AP_WPA2_PSK:
7710 	case AP_WPA2_PSK_MIXED:
7711 	case AP_WPA_PSK:
7712 	case AP_WPA2_SAE:
7713 	case AP_WPA2_PSK_SAE:
7714 	case AP_WPA2_PSK_SHA256:
7715 	case AP_WPA2_FT_PSK:
7716 		if (dut->ap_key_mgmt == AP_WPA2_PSK ||
7717 		    dut->ap_key_mgmt == AP_WPA2_SAE ||
7718 		    dut->ap_key_mgmt == AP_WPA2_PSK_SAE ||
7719 		    dut->ap_key_mgmt == AP_WPA2_PSK_SHA256 ||
7720 		    dut->ap_key_mgmt == AP_WPA2_FT_PSK)
7721 			fprintf(f, "wpa=2\n");
7722 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
7723 			fprintf(f, "wpa=3\n");
7724 		else
7725 			fprintf(f, "wpa=1\n");
7726 		if (dut->ap_key_mgmt == AP_WPA2_SAE)
7727 			key_mgmt = "SAE";
7728 		else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
7729 			key_mgmt = "WPA-PSK SAE";
7730 		else
7731 			key_mgmt = "WPA-PSK";
7732 		switch (dut->ap_pmf) {
7733 		case AP_PMF_DISABLED:
7734 			fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt,
7735 				dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
7736 			break;
7737 		case AP_PMF_OPTIONAL:
7738 			fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt,
7739 				dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
7740 			break;
7741 		case AP_PMF_REQUIRED:
7742 			if (dut->ap_key_mgmt == AP_WPA2_SAE)
7743 				key_mgmt = "SAE";
7744 			else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
7745 				key_mgmt = "WPA-PSK-SHA256 SAE";
7746 			else
7747 				key_mgmt = "WPA-PSK-SHA256";
7748 			fprintf(f, "wpa_key_mgmt=%s\n", key_mgmt);
7749 			break;
7750 		}
7751 		if (dut->ap_key_mgmt == AP_WPA2_PSK_SHA256)
7752 			fprintf(f, "wpa_key_mgmt=WPA-PSK-SHA256\n");
7753 		else if (dut->ap_key_mgmt == AP_WPA2_FT_PSK)
7754 			fprintf(f, "wpa_key_mgmt=FT-PSK\n");
7755 		fprintf(f, "wpa_pairwise=%s\n",
7756 			hostapd_cipher_name(dut->ap_cipher));
7757 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7758 			fprintf(f, "group_cipher=%s\n",
7759 				hostapd_cipher_name(dut->ap_group_cipher));
7760 		if (dut->ap_key_mgmt == AP_WPA2_SAE)
7761 			fprintf(f, "sae_password=%s\n", dut->ap_passphrase);
7762 		else if (!dut->ap_passphrase[0] && dut->ap_psk[0])
7763 			fprintf(f, "wpa_psk=%s", dut->ap_psk);
7764 		else
7765 			fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase);
7766 		break;
7767 	case AP_WPA2_EAP:
7768 	case AP_WPA2_EAP_MIXED:
7769 	case AP_WPA_EAP:
7770 	case AP_WPA2_EAP_OSEN:
7771 	case AP_WPA2_EAP_SHA256:
7772 	case AP_WPA2_FT_EAP:
7773 	case AP_WPA2_ENT_FT_EAP:
7774 		fprintf(f, "ieee8021x=1\n");
7775 		if (dut->ap_key_mgmt == AP_WPA2_EAP ||
7776 		    dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ||
7777 		    dut->ap_key_mgmt == AP_WPA2_EAP_SHA256 ||
7778 		    dut->ap_key_mgmt == AP_WPA2_FT_EAP ||
7779 		    dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP)
7780 			fprintf(f, "wpa=2\n");
7781 		else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
7782 			fprintf(f, "wpa=3\n");
7783 		else
7784 			fprintf(f, "wpa=1\n");
7785 		switch (dut->ap_pmf) {
7786 		case AP_PMF_DISABLED:
7787 			fprintf(f, "wpa_key_mgmt=WPA-EAP%s\n",
7788 				dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "");
7789 			break;
7790 		case AP_PMF_OPTIONAL:
7791 			fprintf(f, "wpa_key_mgmt=WPA-EAP%s%s\n",
7792 				dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "",
7793 				dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" :
7794 				"");
7795 			break;
7796 		case AP_PMF_REQUIRED:
7797 			fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256%s\n",
7798 				dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" :
7799 				"");
7800 			break;
7801 		}
7802 		if (dut->ap_key_mgmt == AP_WPA2_EAP_SHA256)
7803 			fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256\n");
7804 		else if (dut->ap_key_mgmt == AP_WPA2_FT_EAP)
7805 			fprintf(f, "wpa_key_mgmt=FT-EAP\n");
7806 		else if (dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP)
7807 			fprintf(f, "wpa_key_mgmt=FT-EAP WPA-EAP\n");
7808 		fprintf(f, "wpa_pairwise=%s\n",
7809 			hostapd_cipher_name(dut->ap_cipher));
7810 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7811 			fprintf(f, "group_cipher=%s\n",
7812 				hostapd_cipher_name(dut->ap_group_cipher));
7813 		fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
7814 		if (dut->ap_radius_port)
7815 			fprintf(f, "auth_server_port=%d\n",
7816 				dut->ap_radius_port);
7817 		fprintf(f, "auth_server_shared_secret=%s\n",
7818 			dut->ap_radius_password);
7819 		if (dut->program == PROGRAM_HS2_R3) {
7820 			fprintf(f, "radius_das_port=3799\n");
7821 			fprintf(f, "radius_das_client=0.0.0.0 %s\n",
7822 				dut->ap_radius_password);
7823 			fprintf(f, "radius_das_require_event_timestamp=1\n");
7824 		}
7825 		break;
7826 	case AP_SUITEB:
7827 		fprintf(f, "ieee8021x=1\n");
7828 		fprintf(f, "wpa=2\n");
7829 		fprintf(f, "wpa_key_mgmt=WPA-EAP-SUITE-B-192\n");
7830 		fprintf(f, "wpa_pairwise=%s\n",
7831 			hostapd_cipher_name(dut->ap_cipher));
7832 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7833 			fprintf(f, "group_cipher=%s\n",
7834 				hostapd_cipher_name(dut->ap_group_cipher));
7835 		if (dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET)
7836 			fprintf(f, "group_mgmt_cipher=%s\n",
7837 				hostapd_group_mgmt_cipher_name(
7838 					dut->ap_group_mgmt_cipher));
7839 		fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
7840 		if (dut->ap_radius_port)
7841 			fprintf(f, "auth_server_port=%d\n",
7842 				dut->ap_radius_port);
7843 		fprintf(f, "auth_server_shared_secret=%s\n",
7844 			dut->ap_radius_password);
7845 		break;
7846 	case AP_WPA2_OWE:
7847 		fprintf(f, "wpa=2\n");
7848 		fprintf(f, "wpa_key_mgmt=OWE\n");
7849 		fprintf(f, "rsn_pairwise=%s\n",
7850 			hostapd_cipher_name(dut->ap_cipher));
7851 		if (dut->ap_sae_groups) {
7852 			fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups);
7853 			if (dut->owe_ptk_workaround)
7854 				fprintf(f, "owe_ptk_workaround=1\n");
7855 		}
7856 		break;
7857 	case AP_OSEN:
7858 		fprintf(f, "osen=1\n");
7859 		fprintf(f, "disable_dgaf=1\n");
7860 		fprintf(f, "wpa_pairwise=%s\n",
7861 			hostapd_cipher_name(dut->ap_cipher));
7862 		if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7863 			fprintf(f, "group_cipher=%s\n",
7864 				hostapd_cipher_name(dut->ap_group_cipher));
7865 		fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
7866 		if (dut->ap_radius_port)
7867 			fprintf(f, "auth_server_port=%d\n",
7868 				dut->ap_radius_port);
7869 		fprintf(f, "auth_server_shared_secret=%s\n",
7870 			dut->ap_radius_password);
7871 		break;
7872 	}
7873 skip_key_mgmt:
7874 
7875 	if (dut->ap_sae_passwords) {
7876 		char *tmp, *pos, *end, *id;
7877 
7878 		tmp = strdup(dut->ap_sae_passwords);
7879 		if (!tmp) {
7880 			fclose(f);
7881 			return ERROR_SEND_STATUS;
7882 		}
7883 
7884 		pos = tmp;
7885 		while (*pos) {
7886 			end = strchr(pos, ';');
7887 			if (end)
7888 				*end = '\0';
7889 			id = strchr(pos, ':');
7890 			if (id)
7891 				*id++ = '\0';
7892 
7893 			fprintf(f, "sae_password=%s%s%s\n",
7894 				pos, id ? "|id=" : "", id ? id : "");
7895 			if (!end)
7896 				break;
7897 			pos = end + 1;
7898 		}
7899 
7900 		free(tmp);
7901 	}
7902 
7903 	if (dut->ap_rsn_preauth)
7904 		fprintf(f, "rsn_preauth=1\n");
7905 
7906 	if (dut->ap_pmksa && dut->ap_pmksa_caching)
7907 		fprintf(f, "disable_pmksa_caching=1\n");
7908 
7909 	if (dut->ap_beacon_prot)
7910 		fprintf(f, "beacon_prot=1\n");
7911 
7912 	if (dut->ap_transition_disable)
7913 		fprintf(f, "transition_disable=0x%02x\n",
7914 			dut->ap_transition_disable);
7915 
7916 	switch (dut->ap_pmf) {
7917 	case AP_PMF_DISABLED:
7918 		break;
7919 	case AP_PMF_OPTIONAL:
7920 		fprintf(f, "ieee80211w=1\n");
7921 		if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE ||
7922 		    (dut->ap_akm_values & (AKM_SAE | AKM_WPA_PSK)) ==
7923 		    (AKM_SAE | AKM_WPA_PSK))
7924 			fprintf(f, "sae_require_mfp=1\n");
7925 		break;
7926 	case AP_PMF_REQUIRED:
7927 		fprintf(f, "ieee80211w=2\n");
7928 		break;
7929 	}
7930 
7931 	if (dut->ap_pmf != AP_PMF_DISABLED &&
7932 	    dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET)
7933 		fprintf(f, "group_mgmt_cipher=%s\n",
7934 			hostapd_group_mgmt_cipher_name(
7935 				dut->ap_group_mgmt_cipher));
7936 
7937 	if (ap_ft_enabled(dut)) {
7938 		unsigned char own_addr[ETH_ALEN];
7939 
7940 		fprintf(f, "mobility_domain=%s\n", dut->ap_mobility_domain);
7941 		fprintf(f, "ft_over_ds=%d\n", dut->ap_ft_ds == VALUE_ENABLED);
7942 		if (get_hwaddr(ifname, own_addr) < 0) {
7943 			memset(own_addr, 0, ETH_ALEN);
7944 			own_addr[0] = 0x02;
7945 		}
7946 		fprintf(f,
7947 			"nas_identifier=%02x%02x%02x%02x%02x%02x.nas.example.com\n",
7948 			own_addr[0], own_addr[1], own_addr[2],
7949 			own_addr[3], own_addr[4], own_addr[5]);
7950 		fprintf(f, "r1_key_holder=%02x%02x%02x%02x%02x%02x\n",
7951 			own_addr[0], own_addr[1], own_addr[2],
7952 			own_addr[3], own_addr[4], own_addr[5]);
7953 		fprintf(f, "ft_psk_generate_local=1\n");
7954 		fprintf(f, "pmk_r1_push=0\n");
7955 		fprintf(f,
7956 			"r0kh=ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n");
7957 		fprintf(f,
7958 			"r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n");
7959 	}
7960 
7961 	if (dut->rsne_override)
7962 		fprintf(f, "own_ie_override=%s\n", dut->rsne_override);
7963 	if (dut->rsnxe_override_eapol)
7964 		fprintf(f, "rsnxe_override_eapol=%s\n",
7965 			dut->rsnxe_override_eapol);
7966 
7967 	if (dut->sae_commit_override)
7968 		fprintf(f, "sae_commit_override=%s\n",
7969 			dut->sae_commit_override);
7970 
7971 	if (dut->ap_sae_groups)
7972 		fprintf(f, "sae_groups=%s\n", dut->ap_sae_groups);
7973 
7974 	if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) {
7975 		const char *sae_pwe = NULL;
7976 
7977 		if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut))
7978 			sae_pwe = "3";
7979 		else if (dut->sae_pwe == SAE_PWE_LOOP)
7980 			sae_pwe = "0";
7981 		else if (dut->sae_pwe == SAE_PWE_H2E)
7982 			sae_pwe = "1";
7983 		else if (dut->sae_h2e_default)
7984 			sae_pwe = "2";
7985 		if (sae_pwe)
7986 			fprintf(f, "sae_pwe=%s\n", sae_pwe);
7987 	}
7988 
7989 	if (dut->sae_anti_clogging_threshold >= 0)
7990 		fprintf(f, "sae_anti_clogging_threshold=%d\n",
7991 			dut->sae_anti_clogging_threshold);
7992 	if (dut->sae_reflection)
7993 		fprintf(f, "sae_reflection_attack=1\n");
7994 	if (dut->sae_confirm_immediate)
7995 		fprintf(f, "sae_confirm_immediate=2\n");
7996 
7997 	if (dut->ap_p2p_mgmt)
7998 		fprintf(f, "manage_p2p=1\n");
7999 
8000 	if (dut->ap_tdls_prohibit || dut->ap_l2tif)
8001 		fprintf(f, "tdls_prohibit=1\n");
8002 	if (dut->ap_tdls_prohibit_chswitch || dut->ap_l2tif)
8003 		fprintf(f, "tdls_prohibit_chan_switch=1\n");
8004 	if (dut->ap_p2p_cross_connect >= 0) {
8005 		fprintf(f, "manage_p2p=1\n"
8006 			"allow_cross_connection=%d\n",
8007 			dut->ap_p2p_cross_connect);
8008 	}
8009 
8010 	if (dut->ap_l2tif || dut->ap_proxy_arp ||
8011 	    dut->ap_key_mgmt == AP_WPA2_EAP_OSEN) {
8012 		if (!dut->bridge) {
8013 			sigma_dut_print(dut, DUT_MSG_ERROR,
8014 					"Bridge must be configured. Run with -b <brname>.");
8015 			fclose(f);
8016 			return -2;
8017 		}
8018 		fprintf(f, "ap_isolate=1\n");
8019 	}
8020 
8021 	if (dut->ap_proxy_arp)
8022 		fprintf(f, "proxy_arp=1\n");
8023 
8024 	if (dut->ap_wme)
8025 		fprintf(f, "wmm_enabled=1\n");
8026 
8027 	if (dut->ap_wmmps == AP_WMMPS_ON)
8028 		fprintf(f, "uapsd_advertisement_enabled=1\n");
8029 
8030 	if (dut->ap_hs2) {
8031 		if (dut->ap_bss_load) {
8032 			char *bss_load;
8033 
8034 			switch (dut->ap_bss_load) {
8035 			case -1:
8036 				bss_load = "bss_load_update_period=10";
8037 				break;
8038 			case 1:
8039 				/* STA count: 1, CU: 50, AAC: 65535 */
8040 				bss_load = "bss_load_test=1:50:65535";
8041 				break;
8042 			case 2:
8043 				/* STA count: 1, CU: 200, AAC: 65535 */
8044 				bss_load = "bss_load_test=1:200:65535";
8045 				break;
8046 			case 3:
8047 				/* STA count: 1, CU: 75, AAC: 65535 */
8048 				bss_load = "bss_load_test=1:75:65535";
8049 				break;
8050 			default:
8051 				bss_load = NULL;
8052 				break;
8053 			}
8054 
8055 			if (!bss_load) {
8056 				fclose(f);
8057 				return -2;
8058 			}
8059 			fprintf(f, "%s\n", bss_load);
8060 		}
8061 
8062 		if (append_hostapd_conf_hs2(dut, f)) {
8063 			fclose(f);
8064 			return -2;
8065 		}
8066 	}
8067 
8068 	if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) {
8069 		fclose(f);
8070 		return -2;
8071 	}
8072 
8073 	if (dut->ap_hs2 && strlen(dut->ap_tag_ssid[0])) {
8074 		unsigned char bssid[6];
8075 		char ifname2[50];
8076 
8077 		if (get_hwaddr(ifname, bssid)) {
8078 			fclose(f);
8079 			return -2;
8080 		}
8081 		if (bssid[0] & 0x02)
8082 			bssid[5] ^= 0x01;
8083 		else
8084 			bssid[0] |= 0x02;
8085 
8086 		snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8087 		fprintf(f, "bss=%s\n", ifname2);
8088 		fprintf(f, "ssid=%s\n", dut->ap_tag_ssid[0]);
8089 		if (dut->bridge)
8090 			fprintf(f, "bridge=%s\n", dut->bridge);
8091 
8092 		if (drv == DRIVER_LINUX_WCN)
8093 			fprintf(f, "use_driver_iface_addr=1\n");
8094 		else
8095 			fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8096 				bssid[0], bssid[1], bssid[2], bssid[3],
8097 				bssid[4], bssid[5]);
8098 
8099 		if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) {
8100 			fprintf(f, "osen=1\n");
8101 			/* Disable DGAF for OSEN BSS */
8102 			fprintf(f, "disable_dgaf=1\n");
8103 			fprintf(f, "ap_isolate=1\n");
8104 			if (strlen(dut->ap2_radius_ipaddr))
8105 				fprintf(f, "auth_server_addr=%s\n",
8106 					dut->ap2_radius_ipaddr);
8107 			if (dut->ap2_radius_port)
8108 				fprintf(f, "auth_server_port=%d\n",
8109 					dut->ap2_radius_port);
8110 			if (strlen(dut->ap2_radius_password))
8111 				fprintf(f, "auth_server_shared_secret=%s\n",
8112 					dut->ap2_radius_password);
8113 
8114 			set_ebtables_forward_drop(dut, ifname, ifname2);
8115 		} else if (dut->ap2_osu) {
8116 			fprintf(f, "ap_isolate=1\n");
8117 			set_ebtables_forward_drop(dut, ifname, ifname2);
8118 		}
8119 
8120 		if (dut->ap2_proxy_arp) {
8121 			if (!dut->bridge) {
8122 				sigma_dut_print(dut, DUT_MSG_ERROR,
8123 						"Bridge must be configured. Run with -b <brname>.");
8124 				fclose(f);
8125 				return -2;
8126 			}
8127 			fprintf(f, "ap_isolate=1\n");
8128 			fprintf(f, "proxy_arp=1\n");
8129 
8130 			if (set_ebtables_proxy_arp(dut, "FORWARD", ifname2) ||
8131 			    set_ebtables_proxy_arp(dut, "OUTPUT", ifname2)) {
8132 				fclose(f);
8133 				return -2;
8134 			}
8135 
8136 		}
8137 	}
8138 
8139 	if (dut->program == PROGRAM_WPS) {
8140 		/* 60G WPS tests requires wps_state of 2 (configured) */
8141 		int wps_state = is_60g_sigma_dut(dut) ? 2 : 1;
8142 
8143 		fprintf(f, "eap_server=1\n"
8144 			"wps_state=%d\n"
8145 			"device_name=QCA AP\n"
8146 			"manufacturer=QCA\n"
8147 			"device_type=6-0050F204-1\n"
8148 			"config_methods=label virtual_display %s"
8149 			"virtual_push_button keypad%s\n"
8150 			"ap_pin=12345670\n"
8151 			"friendly_name=QCA Access Point\n"
8152 			"upnp_iface=%s\n",
8153 			wps_state,
8154 			is_60g_sigma_dut(dut) ? "physical_display " : "",
8155 			dut->ap_wpsnfc ? " nfc_interface ext_nfc_token" : "",
8156 			dut->bridge ? dut->bridge : ifname);
8157 		if (dut->wsc_fragment) {
8158 			fprintf(f, "device_name=%s\n"
8159 				"manufacturer=%s\n"
8160 				"model_name=%s\n"
8161 				"model_number=%s\n"
8162 				"serial_number=%s\n",
8163 				WPS_LONG_DEVICE_NAME,
8164 				WPS_LONG_MANUFACTURER,
8165 				WPS_LONG_MODEL_NAME,
8166 				WPS_LONG_MODEL_NUMBER,
8167 				WPS_LONG_SERIAL_NUMBER);
8168 		} else {
8169 			fprintf(f, "device_name=QCA AP\n"
8170 				"manufacturer=QCA\n");
8171 		}
8172 		if (dut->eap_fragment)
8173 			fprintf(f, "fragment_size=128\n");
8174 	}
8175 
8176 	if (dut->ap_dpp_conf_addr && dut->ap_dpp_conf_pkhash)
8177 		fprintf(f, "dpp_controller=ipaddr=%s pkhash=%s\n",
8178 			dut->ap_dpp_conf_addr, dut->ap_dpp_conf_pkhash);
8179 
8180 	if (dut->ap_he_rtsthrshld == VALUE_ENABLED)
8181 		fprintf(f, "he_rts_threshold=512\n");
8182 	else if (dut->ap_he_rtsthrshld == VALUE_DISABLED)
8183 		fprintf(f, "he_rts_threshold=1024\n");
8184 
8185 	if ((dut->program == PROGRAM_VHT) ||
8186 	    (dut->program == PROGRAM_HE && dut->use_5g)) {
8187 		int vht_oper_centr_freq_idx;
8188 
8189 		if (check_channel(dut->ap_channel) < 0) {
8190 			send_resp(dut, conn, SIGMA_INVALID,
8191 				  "errorCode,Invalid channel");
8192 			fclose(f);
8193 			return 0;
8194 		}
8195 
8196 		switch (dut->ap_chwidth) {
8197 		case AP_20:
8198 			dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH;
8199 			vht_oper_centr_freq_idx =
8200 				get_oper_centr_freq_seq_idx(20,
8201 							    dut->ap_channel);
8202 			break;
8203 		case AP_40:
8204 			dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH;
8205 			vht_oper_centr_freq_idx =
8206 				get_oper_centr_freq_seq_idx(40,
8207 							    dut->ap_channel);
8208 			break;
8209 		case AP_80:
8210 			dut->ap_vht_chwidth = AP_80_VHT_OPER_CHWIDTH;
8211 			vht_oper_centr_freq_idx =
8212 				get_oper_centr_freq_seq_idx(80,
8213 							    dut->ap_channel);
8214 			break;
8215 		case AP_160:
8216 			dut->ap_vht_chwidth = AP_160_VHT_OPER_CHWIDTH;
8217 			vht_oper_centr_freq_idx =
8218 				get_oper_centr_freq_seq_idx(160,
8219 							    dut->ap_channel);
8220 			break;
8221 		default:
8222 			dut->ap_vht_chwidth = VHT_DEFAULT_OPER_CHWIDTH;
8223 			vht_oper_centr_freq_idx =
8224 				get_oper_centr_freq_seq_idx(80,
8225 							    dut->ap_channel);
8226 			break;
8227 		}
8228 		fprintf(f, "vht_oper_centr_freq_seg0_idx=%d\n",
8229 			vht_oper_centr_freq_idx);
8230 		fprintf(f, "vht_oper_chwidth=%d\n", dut->ap_vht_chwidth);
8231 		if (dut->ap_mode == AP_11ax) {
8232 			fprintf(f, "he_oper_chwidth=%d\n", dut->ap_vht_chwidth);
8233 			fprintf(f, "he_oper_centr_freq_seg0_idx=%d\n",
8234 				vht_oper_centr_freq_idx);
8235 		}
8236 
8237 		if (dut->ap_sgi80 || dut->ap_txBF ||
8238 		    dut->ap_ldpc != VALUE_NOT_SET ||
8239 		    dut->ap_tx_stbc || dut->ap_mu_txBF) {
8240 			fprintf(f, "vht_capab=%s%s%s%s%s\n",
8241 				dut->ap_sgi80 ? "[SHORT-GI-80]" : "",
8242 				dut->ap_txBF ?
8243 				"[SU-BEAMFORMER][SU-BEAMFORMEE][BF-ANTENNA-2][SOUNDING-DIMENSION-2]" : "",
8244 				(dut->ap_ldpc == VALUE_ENABLED) ?
8245 				"[RXLDPC]" : "",
8246 				dut->ap_tx_stbc ? "[TX-STBC-2BY1]" : "",
8247 				dut->ap_mu_txBF ? "[MU-BEAMFORMER]" : "");
8248 		}
8249 	}
8250 
8251 	if (dut->ap_key_mgmt == AP_WPA2_OWE && dut->ap_tag_ssid[0][0] &&
8252 	    dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
8253 		/* OWE transition mode */
8254 		unsigned char bssid[6];
8255 		char ifname2[50];
8256 		unsigned long val;
8257 		FILE *f2;
8258 
8259 		snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8260 
8261 		fprintf(f, "owe_transition_ifname=%s\n", ifname2);
8262 		val = 0x12345678; /* default to something */
8263 		f2 = fopen("/dev/urandom", "r");
8264 		if (f2) {
8265 			if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) {
8266 				sigma_dut_print(dut, DUT_MSG_ERROR,
8267 						"Could not read /dev/urandom");
8268 			}
8269 			fclose(f2);
8270 		}
8271 		fprintf(f, "ssid=owe-%lx\n", val);
8272 		fprintf(f, "ignore_broadcast_ssid=1\n");
8273 
8274 		if (get_hwaddr(ifname, bssid)) {
8275 			fclose(f);
8276 			return -2;
8277 		}
8278 		if (bssid[0] & 0x02)
8279 			bssid[5] ^= 0x01;
8280 		else
8281 			bssid[0] |= 0x02;
8282 
8283 		fprintf(f, "bss=%s\n", ifname2);
8284 		fprintf(f, "ssid=%s\n", dut->ap_ssid);
8285 		if (dut->bridge)
8286 			fprintf(f, "bridge=%s\n", dut->bridge);
8287 		if (drv == DRIVER_LINUX_WCN)
8288 			fprintf(f, "use_driver_iface_addr=1\n");
8289 		else
8290 			fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8291 				bssid[0], bssid[1], bssid[2], bssid[3],
8292 				bssid[4], bssid[5]);
8293 		fprintf(f, "owe_transition_ifname=%s\n", ifname);
8294 	}
8295 
8296 	if (dut->ap_key_mgmt == AP_OPEN &&
8297 	    dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
8298 		/* OWE transition mode */
8299 		unsigned char bssid[6];
8300 		char ifname2[50];
8301 		unsigned long val;
8302 		FILE *f2;
8303 
8304 		snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8305 
8306 		fprintf(f, "owe_transition_ifname=%s\n", ifname2);
8307 		fprintf(f, "ssid=%s\n", dut->ap_ssid);
8308 
8309 		if (get_hwaddr(ifname, bssid)) {
8310 			fclose(f);
8311 			return -2;
8312 		}
8313 		if (bssid[0] & 0x02)
8314 			bssid[5] ^= 0x01;
8315 		else
8316 			bssid[0] |= 0x02;
8317 
8318 		fprintf(f, "bss=%s\n", ifname2);
8319 		val = 0x12345678; /* default to something */
8320 		f2 = fopen("/dev/urandom", "r");
8321 		if (f2) {
8322 			if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) {
8323 				sigma_dut_print(dut, DUT_MSG_ERROR,
8324 						"Could not read /dev/urandom");
8325 			}
8326 			fclose(f2);
8327 		}
8328 		fprintf(f, "ssid=owe-%lx\n", val);
8329 		if (dut->bridge)
8330 			fprintf(f, "bridge=%s\n", dut->bridge);
8331 		if (drv == DRIVER_LINUX_WCN)
8332 			fprintf(f, "use_driver_iface_addr=1\n");
8333 		else
8334 			fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8335 				bssid[0], bssid[1], bssid[2], bssid[3],
8336 				bssid[4], bssid[5]);
8337 		fprintf(f, "owe_transition_ifname=%s\n", ifname);
8338 		fprintf(f, "wpa=2\n");
8339 		fprintf(f, "wpa_key_mgmt=OWE\n");
8340 		fprintf(f, "rsn_pairwise=CCMP\n");
8341 		fprintf(f, "ieee80211w=2\n");
8342 		fprintf(f, "ignore_broadcast_ssid=1\n");
8343 		if (dut->ap_sae_groups) {
8344 			fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups);
8345 			if (dut->owe_ptk_workaround)
8346 				fprintf(f, "owe_ptk_workaround=1\n");
8347 		}
8348 	}
8349 
8350 	if (dut->program == PROGRAM_OCE) {
8351 		fprintf(f, "oce=%d\n",
8352 			dut->dev_role == DEVROLE_STA_CFON ? 2 : 1);
8353 	}
8354 	fclose(f);
8355 	if (dut->use_hostapd_pid_file)
8356 		kill_hostapd_process_pid(dut);
8357 #ifdef __QNXNTO__
8358 	if (system("slay hostapd") == 0)
8359 #else /* __QNXNTO__ */
8360 	if (!dut->use_hostapd_pid_file &&
8361 	    (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
8362 	     system("killall hostapd") == 0))
8363 #endif /* __QNXNTO__ */
8364 	{
8365 		int i;
8366 		/* Wait some time to allow hostapd to complete cleanup before
8367 		 * starting a new process */
8368 		for (i = 0; i < 10; i++) {
8369 			usleep(500000);
8370 #ifdef __QNXNTO__
8371 			if (system("pidin | grep hostapd") != 0)
8372 				break;
8373 #else /* __QNXNTO__ */
8374 			if (system("pidof hostapd") != 0)
8375 				break;
8376 #endif /* __QNXNTO__ */
8377 		}
8378 	}
8379 	dut->hostapd_running = 0;
8380 
8381 #ifdef ANDROID
8382 	/* Set proper conf file permissions so that hostapd process
8383 	 * can access it.
8384 	 */
8385 	if (chmod(ap_conf_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0)
8386 		sigma_dut_print(dut, DUT_MSG_ERROR,
8387 				"Error changing permissions");
8388 
8389 	gr = getgrnam("wifi");
8390 	if (!gr || chown(ap_conf_path, -1, gr->gr_gid) < 0)
8391 		sigma_dut_print(dut, DUT_MSG_ERROR, "Error changing groupid");
8392 #endif /* ANDROID */
8393 
8394 	f = fopen(ap_conf_path, "r");
8395 	if (f) {
8396 		size_t len;
8397 
8398 		len = fread(buf, 1, sizeof(buf), f);
8399 		fclose(f);
8400 		if (len >= sizeof(buf))
8401 			len = sizeof(buf) - 1;
8402 		buf[len] = '\0';
8403 		sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd debug log:\n%s",
8404 				buf);
8405 	}
8406 
8407 	if (drv == DRIVER_QNXNTO) {
8408 		snprintf(buf, sizeof(buf),
8409 			 "hostapd -B %s%s%s %s%s %s/sigma_dut-ap.conf",
8410 			 dut->hostapd_debug_log ? "-dddKt " : "",
8411 			 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ?
8412 			 "-f " : "",
8413 			 dut->hostapd_debug_log ? dut->hostapd_debug_log : "",
8414 			 dut->hostapd_entropy_log ? " -e" : "",
8415 			 dut->hostapd_entropy_log ? dut->hostapd_entropy_log :
8416 			 "",
8417 			 dut->sigma_tmpdir);
8418 	} else {
8419 		/*
8420 		 * It looks like a monitor interface can cause some issues for
8421 		 * beaconing, so remove it (if injection was used) before
8422 		 * starting hostapd.
8423 		 */
8424 		if (if_nametoindex("sigmadut") > 0 &&
8425 		    system("iw dev sigmadut del") != 0)
8426 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove "
8427 					"monitor interface");
8428 
8429 		snprintf(path, sizeof(path), "%shostapd",
8430 			 file_exists("hostapd") ? "./" : "");
8431 		snprintf(buf, sizeof(buf),
8432 			 "%s -B%s%s%s%s%s%s %s/sigma_dut-ap.conf",
8433 			 dut->hostapd_bin ? dut->hostapd_bin : path,
8434 			 dut->hostapd_debug_log ? " -dddKt" : "",
8435 			 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ?
8436 			 " -f " : "",
8437 			 dut->hostapd_debug_log ? dut->hostapd_debug_log : "",
8438 			 dut->hostapd_entropy_log ? " -e" : "",
8439 			 dut->hostapd_entropy_log ? dut->hostapd_entropy_log :
8440 			 "",
8441 			 dut->use_hostapd_pid_file ?
8442 			 " -P " SIGMA_DUT_HOSTAPD_PID_FILE : "",
8443 			 dut->sigma_tmpdir);
8444 	}
8445 
8446 	sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd command: %s", buf);
8447 	if (system(buf) != 0) {
8448 		send_resp(dut, conn, SIGMA_ERROR,
8449 			  "errorCode,Failed to start hostapd");
8450 		return 0;
8451 	}
8452 
8453 	/* allow some time for hostapd to start before returning success */
8454 	usleep(500000);
8455 	if (run_hostapd_cli(dut, "ping") != 0) {
8456 		send_resp(dut, conn, SIGMA_ERROR,
8457 			  "errorCode,Failed to talk to hostapd");
8458 		return 0;
8459 	}
8460 
8461 	if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) {
8462 		int buf_size;
8463 
8464 		if (dut->ap_ba_bufsize == BA_BUFSIZE_256)
8465 			buf_size = 256;
8466 		else
8467 			buf_size = 64;
8468 
8469 		if ((drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) &&
8470 		    sta_set_addba_buf_size(dut, ifname, buf_size)) {
8471 			send_resp(dut, conn, SIGMA_ERROR,
8472 				  "ErrorCode,set_addba_buf_size failed");
8473 			return STATUS_SENT_ERROR;
8474 		}
8475 
8476 		sigma_dut_print(dut, DUT_MSG_INFO,
8477 				"setting addba buf_size=%d", buf_size);
8478 	}
8479 
8480 	if (drv == DRIVER_LINUX_WCN) {
8481 		const char *ifname_ptr = ifname;
8482 
8483 		if ((dut->ap_key_mgmt == AP_OPEN &&
8484 		     dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) ||
8485 		    (dut->ap_key_mgmt == AP_WPA2_OWE &&
8486 		     dut->ap_tag_ssid[0][0] &&
8487 		     dut->ap_tag_key_mgmt[0] == AP2_OPEN)) {
8488 			/* OWE transition mode */
8489 			if (dut->bridge)
8490 				ifname_ptr = dut->bridge;
8491 		}
8492 
8493 		sigma_dut_print(dut, DUT_MSG_INFO,
8494 				"setting ip addr %s mask %s ifname %s",
8495 				ap_inet_addr, ap_inet_mask, ifname_ptr);
8496 		snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up",
8497 			 ifname_ptr, ap_inet_addr, ap_inet_mask);
8498 		if (system(buf) != 0) {
8499 			sigma_dut_print(dut, DUT_MSG_ERROR,
8500 					"Failed to initialize the interface");
8501 			return -1;
8502 		}
8503 	}
8504 
8505 	/* Configure the driver with LDPC setting for AP mode as a new vdev is
8506 	 * created when hostapd is started.
8507 	 */
8508 	if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN)
8509 		wcn_config_ap_ldpc(dut, ifname);
8510 
8511 	if (dut->ap_l2tif) {
8512 		snprintf(path, sizeof(path),
8513 			 "/sys/class/net/%s/brport/hairpin_mode",
8514 			 ifname);
8515 		if (!file_exists(path)) {
8516 			sigma_dut_print(dut, DUT_MSG_ERROR,
8517 					"%s must be binded to the bridge for L2TIF",
8518 					ifname);
8519 			return -2;
8520 		}
8521 
8522 		snprintf(buf, sizeof(buf), "echo 1 > %s", path);
8523 		if (system(buf) != 0) {
8524 			sigma_dut_print(dut, DUT_MSG_ERROR,
8525 				"Failed to enable hairpin_mode for L2TIF");
8526 			return -2;
8527 		}
8528 
8529 		snprintf(buf, sizeof(buf), "ebtables -P FORWARD ACCEPT");
8530 		if (system(buf) != 0) {
8531 			sigma_dut_print(dut, DUT_MSG_ERROR,
8532 					"Failed to set ebtables rules, RULE-9");
8533 			return -2;
8534 		}
8535 
8536 		snprintf(buf, sizeof(buf),
8537 			 "ebtables -A FORWARD -p IPv4 --ip-proto icmp -i %s -j DROP",
8538 			 ifname);
8539 		if (system(buf) != 0) {
8540 			sigma_dut_print(dut, DUT_MSG_ERROR,
8541 					"Failed to set ebtables rules, RULE-11");
8542 			return -2;
8543 		}
8544 	}
8545 
8546 	if (dut->ap_proxy_arp) {
8547 		if (dut->ap_dgaf_disable) {
8548 			if (set_ebtables_disable_dgaf(dut, "FORWARD", ifname) ||
8549 			    set_ebtables_disable_dgaf(dut, "OUTPUT", ifname))
8550 				return -2;
8551 		} else {
8552 			if (set_ebtables_proxy_arp(dut, "FORWARD", ifname) ||
8553 			    set_ebtables_proxy_arp(dut, "OUTPUT", ifname))
8554 				return -2;
8555 		}
8556 
8557 		/* For 4.5-(c) */
8558 		snprintf(buf, sizeof(buf),
8559 			 "ebtables -A FORWARD -p ARP --arp-opcode 2 -i %s -j DROP",
8560 			 ifname);
8561 		if (system(buf) != 0) {
8562 			sigma_dut_print(dut, DUT_MSG_ERROR,
8563 					"Failed to set ebtables rules, RULE-10");
8564 			return -2;
8565 		}
8566 	}
8567 
8568 	if (dut->ap_tdls_prohibit || dut->ap_l2tif) {
8569 		/* Drop TDLS frames */
8570 		snprintf(buf, sizeof(buf),
8571 			 "ebtables -A FORWARD -p 0x890d -i %s -j DROP", ifname);
8572 		if (system(buf) != 0) {
8573 			sigma_dut_print(dut, DUT_MSG_ERROR,
8574 					"Failed to set ebtables rules, RULE-13");
8575 			return -2;
8576 		}
8577 	}
8578 
8579 	if (dut->ap_fake_pkhash &&
8580 	    run_hostapd_cli(dut, "set wps_corrupt_pkhash 1") != 0) {
8581 		send_resp(dut, conn, SIGMA_ERROR,
8582 			  "errorCode,Could not enable FakePubKey");
8583 		return 0;
8584 	}
8585 
8586 	if (dut->program == PROGRAM_60GHZ) {
8587 		if (dut->ap_num_ese_allocs > 0) {
8588 			/* wait extra time for AP to start */
8589 			sleep(2);
8590 			if (ap_set_60g_ese(dut, dut->ap_num_ese_allocs,
8591 					   dut->ap_ese_allocs)) {
8592 				send_resp(dut, conn, SIGMA_ERROR,
8593 					  "errorCode,Could not set ExtSch");
8594 				return 0;
8595 			}
8596 		}
8597 		if (dut->ap_fixed_rate) {
8598 			sigma_dut_print(dut, DUT_MSG_DEBUG,
8599 					"forcing TX MCS index %d",
8600 					dut->ap_mcs);
8601 			if (ap_set_force_mcs(dut, 1, dut->ap_mcs)) {
8602 				send_resp(dut, conn, SIGMA_ERROR,
8603 					  "errorCode,Could not force MCS");
8604 				return -2;
8605 			}
8606 		}
8607 	}
8608 
8609 	if (dut->wps_forced_version) {
8610 		snprintf(buf, sizeof(buf), "SET wps_version_number %d",
8611 			 dut->wps_forced_version);
8612 		if (hapd_command(ifname, buf) < 0) {
8613 			send_resp(dut, conn, SIGMA_ERROR,
8614 				  "errorCode,Fail to set wps_version_number");
8615 			return STATUS_SENT;
8616 		}
8617 	}
8618 
8619 	dut->hostapd_running = 1;
8620 	return 1;
8621 }
8622 
8623 
8624 static int parse_qos_params(struct sigma_dut *dut, struct sigma_conn *conn,
8625 			    struct qos_params *qos, const char *cwmin,
8626 			    const char *cwmax, const char *aifs,
8627 			    const char *txop, const char *acm)
8628 {
8629 	int val;
8630 
8631 	if (cwmin) {
8632 		qos->ac = 1;
8633 		val = atoi(cwmin);
8634 		if (val < 0 || val > 15) {
8635 			send_resp(dut, conn, SIGMA_INVALID,
8636 				  "errorCode,Invalid cwMin");
8637 			return 0;
8638 		}
8639 		qos->cwmin = val;
8640 	}
8641 
8642 	if (cwmax) {
8643 		qos->ac = 1;
8644 		val = atoi(cwmax);
8645 		if (val < 0 || val > 15) {
8646 			send_resp(dut, conn, SIGMA_INVALID,
8647 				  "errorCode,Invalid cwMax");
8648 			return 0;
8649 		}
8650 		qos->cwmax = val;
8651 	}
8652 
8653 	if (aifs) {
8654 		qos->ac = 1;
8655 		val = atoi(aifs);
8656 		if (val < 1 || val > 255) {
8657 			send_resp(dut, conn, SIGMA_INVALID,
8658 				  "errorCode,Invalid AIFS");
8659 			return 0;
8660 		}
8661 		qos->aifs = val;
8662 	}
8663 
8664 	if (txop) {
8665 		qos->ac = 1;
8666 		val = atoi(txop);
8667 		if (val < 0 || val > 0xffff) {
8668 			send_resp(dut, conn, SIGMA_INVALID,
8669 				  "errorCode,Invalid txop");
8670 			return 0;
8671 		}
8672 		qos->txop = val * 32;
8673 	}
8674 
8675 	if (acm) {
8676 		qos->ac = 1;
8677 		qos->acm = strcasecmp(acm, "on") == 0;
8678 	}
8679 
8680 	return 1;
8681 }
8682 
8683 
8684 static enum sigma_cmd_result cmd_ap_set_apqos(struct sigma_dut *dut,
8685 					      struct sigma_conn *conn,
8686 					      struct sigma_cmd *cmd)
8687 {
8688 	/* TXOP: The values provided here for VHT5G only */
8689 	if (!parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VO],
8690 			      get_param(cmd, "cwmin_VO"),
8691 			      get_param(cmd, "cwmax_VO"),
8692 			      get_param(cmd, "AIFS_VO"),
8693 			      get_param(cmd, "TXOP_VO"),
8694 			      get_param(cmd, "ACM_VO")) ||
8695 	    !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VI],
8696 			      get_param(cmd, "cwmin_VI"),
8697 			      get_param(cmd, "cwmax_VI"),
8698 			      get_param(cmd, "AIFS_VI"),
8699 			      get_param(cmd, "TXOP_VI"),
8700 			      get_param(cmd, "ACM_VI")) ||
8701 	    !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BE],
8702 			      get_param(cmd, "cwmin_BE"),
8703 			      get_param(cmd, "cwmax_BE"),
8704 			      get_param(cmd, "AIFS_BE"),
8705 			      get_param(cmd, "TXOP_BE"),
8706 			      get_param(cmd, "ACM_BE")) ||
8707 	    !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BK],
8708 			      get_param(cmd, "cwmin_BK"),
8709 			      get_param(cmd, "cwmax_BK"),
8710 			      get_param(cmd, "AIFS_BK"),
8711 			      get_param(cmd, "TXOP_BK"),
8712 			      get_param(cmd, "ACM_BK")))
8713 		return 0;
8714 
8715 	return 1;
8716 }
8717 
8718 
8719 static enum sigma_cmd_result cmd_ap_set_staqos(struct sigma_dut *dut,
8720 					       struct sigma_conn *conn,
8721 					       struct sigma_cmd *cmd)
8722 {
8723 	if (!parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VO],
8724 			      get_param(cmd, "cwmin_VO"),
8725 			      get_param(cmd, "cwmax_VO"),
8726 			      get_param(cmd, "AIFS_VO"),
8727 			      get_param(cmd, "TXOP_VO"),
8728 			      get_param(cmd, "ACM_VO")) ||
8729 	    !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VI],
8730 			      get_param(cmd, "cwmin_VI"),
8731 			      get_param(cmd, "cwmax_VI"),
8732 			      get_param(cmd, "AIFS_VI"),
8733 			      get_param(cmd, "TXOP_VI"),
8734 			      get_param(cmd, "ACM_VI")) ||
8735 	    !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BE],
8736 			      get_param(cmd, "cwmin_BE"),
8737 			      get_param(cmd, "cwmax_BE"),
8738 			      get_param(cmd, "AIFS_BE"),
8739 			      get_param(cmd, "TXOP_BE"),
8740 			      get_param(cmd, "ACM_BE")) ||
8741 	    !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BK],
8742 			      get_param(cmd, "cwmin_BK"),
8743 			      get_param(cmd, "cwmax_BK"),
8744 			      get_param(cmd, "AIFS_BK"),
8745 			      get_param(cmd, "TXOP_BK"),
8746 			      get_param(cmd, "ACM_BK")))
8747 		return 0;
8748 
8749 	return 1;
8750 }
8751 
8752 
8753 static void cmd_ath_ap_hs2_reset(struct sigma_dut *dut)
8754 {
8755 	unsigned char bssid[6];
8756 	char buf[100];
8757 	run_system(dut, "cfg -a AP_SSID=\"Hotspot 2.0\"");
8758 	run_system(dut, "cfg -a AP_PRIMARY_CH=1");
8759 	run_system(dut, "cfg -a AP_SECMODE=WPA");
8760 	run_system(dut, "cfg -a AP_SECFILE=EAP");
8761 	run_system(dut, "cfg -a AP_WPA=2");
8762 	run_system(dut, "cfg -a AP_CYPHER=CCMP");
8763 	run_system(dut, "cfg -a AP_HOTSPOT=1");
8764 	run_system(dut, "cfg -a AP_HOTSPOT_ANT=2");
8765 	run_system(dut, "cfg -a AP_HOTSPOT_INTERNET=0");
8766 	run_system(dut, "cfg -a AP_HOTSPOT_VENUEGROUP=2");
8767 	run_system(dut, "cfg -a AP_HOTSPOT_VENUETYPE=8");
8768 	run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=506f9a");
8769 	run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2=001bc504bd");
8770 	if (!get_hwaddr("ath0", bssid)) {
8771 		snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID="
8772 			"%02x:%02x:%02x:%02x:%02x:%02x",
8773 			bssid[0], bssid[1], bssid[2], bssid[3],
8774 			bssid[4], bssid[5]);
8775 		run_system(dut, buf);
8776 		snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
8777 			"%02x:%02x:%02x:%02x:%02x:%02x",
8778 			bssid[0], bssid[1], bssid[2], bssid[3],
8779 			bssid[4], bssid[5]);
8780 	} else {
8781 		if (!get_hwaddr("wifi0", bssid)) {
8782 			snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID="
8783 				"%02x:%02x:%02x:%02x:%02x:%02x",
8784 				bssid[0], bssid[1], bssid[2], bssid[3],
8785 				bssid[4], bssid[5]);
8786 			run_system(dut, buf);
8787 			snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
8788 				"%02x:%02x:%02x:%02x:%02x:%02x",
8789 				bssid[0], bssid[1], bssid[2], bssid[3],
8790 				bssid[4], bssid[5]);
8791 		} else {
8792 			/* load the driver and try again */
8793 			run_system(dut, "/etc/rc.d/rc.wlan up");
8794 
8795 			if (!get_hwaddr("wifi0", bssid)) {
8796 				snprintf(buf, sizeof(buf),
8797 					 "cfg -a AP_HOTSPOT_HESSID="
8798 					 "%02x:%02x:%02x:%02x:%02x:%02x",
8799 					 bssid[0], bssid[1], bssid[2],
8800 					 bssid[3], bssid[4], bssid[5]);
8801 				run_system(dut, buf);
8802 				snprintf(dut->ap_hessid,
8803 					 sizeof(dut->ap_hessid),
8804 					 "%02x:%02x:%02x:%02x:%02x:%02x",
8805 					 bssid[0], bssid[1], bssid[2],
8806 					 bssid[3], bssid[4], bssid[5]);
8807 			}
8808 		}
8809 	}
8810 
8811 	run_system(dut, "cfg -r AP_SSID_2");
8812 	run_system(dut, "cfg -c");
8813 	/* run_system(dut, "cfg -s"); */
8814 }
8815 
8816 
8817 static void ath_reset_vht_defaults(struct sigma_dut *dut)
8818 {
8819 	run_system(dut, "cfg -x");
8820 	run_system(dut, "cfg -a AP_RADIO_ID=1");
8821 	run_system(dut, "cfg -a AP_PRIMARY_CH_2=36");
8822 	run_system(dut, "cfg -a AP_STARTMODE=standard");
8823 	run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
8824 	run_system(dut, "cfg -a TX_CHAINMASK_2=7");
8825 	run_system(dut, "cfg -a RX_CHAINMASK_2=7");
8826 	run_system(dut, "cfg -a ATH_countrycode=0x348");
8827 	/* NOTE: For Beeliner we have to turn off MU-MIMO */
8828 	if (system("rm /tmp/secath*") != 0) {
8829 		sigma_dut_print(dut, DUT_MSG_ERROR,
8830 				"Failed to remove secath file");
8831 	}
8832 }
8833 
8834 
8835 static enum sigma_cmd_result cmd_ap_reset_default(struct sigma_dut *dut,
8836 						  struct sigma_conn *conn,
8837 						  struct sigma_cmd *cmd)
8838 {
8839 	const char *type, *program;
8840 	enum driver_type drv;
8841 	char buf[128];
8842 	int i;
8843 
8844 	for (i = 0; i < MAX_WLAN_TAGS - 1; i++) {
8845 		/*
8846 		 * Reset all tagged SSIDs to NULL-string and all key management
8847 		 * to open.
8848 		 */
8849 		dut->ap_tag_ssid[i][0] = '\0';
8850 		dut->ap_tag_key_mgmt[i] = AP2_OPEN;
8851 	}
8852 
8853 	drv = get_driver_type(dut);
8854 
8855 	program = get_param(cmd, "program");
8856 	if (!program)
8857 		program = get_param(cmd, "prog");
8858 	dut->program = sigma_program_to_enum(program);
8859 	dut->device_type = AP_unknown;
8860 	type = get_param(cmd, "type");
8861 	if (type && strcasecmp(type, "Testbed") == 0)
8862 		dut->device_type = AP_testbed;
8863 	if (type && strcasecmp(type, "DUT") == 0)
8864 		dut->device_type = AP_dut;
8865 
8866 	dut->ap_rts = 0;
8867 	dut->ap_frgmnt = 0;
8868 	dut->ap_bcnint = 0;
8869 	dut->ap_key_mgmt = AP_OPEN;
8870 	dut->ap_ssid[0] = '\0';
8871 	dut->ap_fake_pkhash = 0;
8872 	memset(dut->ap_qos, 0, sizeof(dut->ap_qos));
8873 	memset(dut->ap_sta_qos, 0, sizeof(dut->ap_sta_qos));
8874 	dut->ap_addba_reject = VALUE_NOT_SET;
8875 	dut->ap_noack = VALUE_NOT_SET;
8876 	dut->ap_is_dual = 0;
8877 	dut->ap_mode = AP_inval;
8878 	dut->ap_mode_1 = AP_inval;
8879 
8880 	dut->ap_allow_vht_wep = 0;
8881 	dut->ap_allow_vht_tkip = 0;
8882 	dut->ap_disable_protection = 0;
8883 	memset(dut->ap_countrycode, 0, sizeof(dut->ap_countrycode));
8884 	dut->ap_dyn_bw_sig = VALUE_NOT_SET;
8885 	dut->ap_ldpc = VALUE_NOT_SET;
8886 	dut->ap_sig_rts = VALUE_NOT_SET;
8887 	dut->ap_rx_amsdu = VALUE_NOT_SET;
8888 	dut->ap_txBF = 0;
8889 	dut->ap_mu_txBF = 0;
8890 	dut->ap_chwidth = AP_AUTO;
8891 
8892 	dut->ap_rsn_preauth = 0;
8893 	dut->ap_wpsnfc = 0;
8894 	dut->ap_bss_load = -1;
8895 	dut->ap_p2p_cross_connect = -1;
8896 
8897 	dut->ap_regulatory_mode = AP_80211D_MODE_DISABLED;
8898 	dut->ap_dfs_mode = AP_DFS_MODE_DISABLED;
8899 	dut->ap_chwidth_offset = SEC_CH_NO;
8900 
8901 	dut->mbo_pref_ap_cnt = 0;
8902 	dut->ft_bss_mac_cnt = 0;
8903 	dut->ap_interface_5g = 0;
8904 	dut->ap_interface_2g = 0;
8905 	dut->ap_pmf = AP_PMF_DISABLED;
8906 
8907 	dut->wsc_fragment = 0;
8908 	dut->eap_fragment = 0;
8909 	dut->wps_forced_version = 0;
8910 
8911 	if (dut->program == PROGRAM_HT || dut->program == PROGRAM_VHT) {
8912 		dut->ap_wme = AP_WME_ON;
8913 		dut->ap_wmmps = AP_WMMPS_ON;
8914 	} else {
8915 		dut->ap_wme = AP_WME_OFF;
8916 		dut->ap_wmmps = AP_WMMPS_OFF;
8917 	}
8918 
8919 	dut->ap_venue_url = 0;
8920 	dut->ap_advice_of_charge = 0;
8921 	dut->ap_oper_icon_metadata = 0;
8922 	dut->ap_tnc_file_name = 0;
8923 	dut->ap_tnc_time_stamp = 0;
8924 
8925 	dut->ap_akm_values = 0;
8926 	free(dut->ap_sae_passwords);
8927 	dut->ap_sae_passwords = NULL;
8928 
8929 	if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
8930 	    dut->program == PROGRAM_HS2_R3 ||
8931 	    dut->program == PROGRAM_IOTLP) {
8932 		int i;
8933 
8934 		if (drv == DRIVER_ATHEROS)
8935 			cmd_ath_ap_hs2_reset(dut);
8936 		else if (drv == DRIVER_OPENWRT)
8937 			cmd_owrt_ap_hs2_reset(dut);
8938 
8939 		dut->ap_interworking = 1;
8940 		dut->ap_access_net_type = 2;
8941 		dut->ap_internet = 0;
8942 		dut->ap_venue_group = 2;
8943 		dut->ap_venue_type = 8;
8944 		dut->ap_domain_name_list[0] = '\0';
8945 		dut->ap_hs2 = 1;
8946 		snprintf(dut->ap_roaming_cons, sizeof(dut->ap_roaming_cons),
8947 			 "506f9a;001bc504bd");
8948 		dut->ap_l2tif = 0;
8949 		dut->ap_proxy_arp = 0;
8950 		if (dut->bridge) {
8951 			char buf[50];
8952 
8953 			snprintf(buf, sizeof(buf), "ip neigh flush dev %s",
8954 				 dut->bridge);
8955 			if (system(buf) != 0) {
8956 				sigma_dut_print(dut, DUT_MSG_DEBUG,
8957 						"%s ip neigh table flushing failed",
8958 						dut->bridge);
8959 			}
8960 
8961 			snprintf(buf, sizeof(buf), "ebtables -F");
8962 			if (system(buf) != 0) {
8963 				sigma_dut_print(dut, DUT_MSG_DEBUG,
8964 						"%s ebtables flushing failed",
8965 						dut->bridge);
8966 			}
8967 		}
8968 		dut->ap_dgaf_disable = 0;
8969 		dut->ap_p2p_cross_connect = 0;
8970 		dut->ap_gas_cb_delay = 0;
8971 		dut->ap_nai_realm_list = 0;
8972 		dut->ap_oper_name = 0;
8973 		dut->ap_venue_name = 0;
8974 		for (i = 0; i < 10; i++) {
8975 			dut->ap_plmn_mcc[i][0] = '\0';
8976 			dut->ap_plmn_mnc[i][0] = '\0';
8977 		}
8978 		dut->ap_wan_metrics = 0;
8979 		dut->ap_conn_capab = 0;
8980 		dut->ap_ip_addr_type_avail = 0;
8981 		dut->ap_net_auth_type = 0;
8982 		dut->ap_oper_class = 0;
8983 		dut->ap_pmf = 0;
8984 		dut->ap_add_sha256 = 0;
8985 	}
8986 
8987 	if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
8988 	    dut->program == PROGRAM_IOTLP) {
8989 		int i;
8990 		const char hessid[] = "50:6f:9a:00:11:22";
8991 
8992 		memcpy(dut->ap_hessid, hessid, strlen(hessid) + 1);
8993 		dut->ap_osu_ssid[0] = '\0';
8994 		dut->ap_pmf = 1;
8995 		dut->ap_osu_provider_list = 0;
8996 		dut->ap_osu_provider_nai_list = 0;
8997 		for (i = 0; i < 10; i++) {
8998 			dut->ap_osu_server_uri[i][0] = '\0';
8999 			dut->ap_osu_method[i] = 0xFF;
9000 		}
9001 		dut->ap_qos_map_set = 0;
9002 		dut->ap_tag_key_mgmt[0] = AP2_OPEN;
9003 		dut->ap2_proxy_arp = 0;
9004 		dut->ap2_osu = 0;
9005 		dut->ap_osu_icon_tag = 0;
9006 	}
9007 
9008 	if (dut->program == PROGRAM_VHT) {
9009 		/* Set up the defaults */
9010 		dut->use_5g = 1;
9011 		dut->ap_mode = AP_11ac;
9012 		dut->ap_channel = 36;
9013 		dut->ap_ampdu = VALUE_NOT_SET;
9014 		dut->ap_ndpa_frame = 1;
9015 		if (dut->device_type == AP_testbed) {
9016 			dut->ap_amsdu = VALUE_DISABLED;
9017 			dut->ap_ldpc = VALUE_DISABLED;
9018 			dut->ap_rx_amsdu = VALUE_DISABLED;
9019 			dut->ap_sgi80 = 0;
9020 		} else {
9021 			dut->ap_amsdu = VALUE_ENABLED;
9022 			/*
9023 			 * As LDPC is optional, don't enable this by default
9024 			 * for LINUX-WCN driver. The ap_set_wireless command
9025 			 * can be used to enable LDPC, when needed.
9026 			 */
9027 			if (drv != DRIVER_LINUX_WCN)
9028 				dut->ap_ldpc = VALUE_ENABLED;
9029 			dut->ap_rx_amsdu = VALUE_ENABLED;
9030 			dut->ap_sgi80 = 1;
9031 		}
9032 		dut->ap_fixed_rate = 0;
9033 		dut->ap_rx_streams = 3;
9034 		dut->ap_tx_streams = 3;
9035 		dut->ap_vhtmcs_map = 0;
9036 		dut->ap_chwidth = AP_80;
9037 		dut->ap_tx_stbc = 1;
9038 		dut->ap_dyn_bw_sig = VALUE_ENABLED;
9039 		if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9040 			dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
9041 		if (get_driver_type(dut) == DRIVER_ATHEROS)
9042 			ath_reset_vht_defaults(dut);
9043 	}
9044 
9045 	if (dut->program == PROGRAM_IOTLP) {
9046 		dut->wnm_bss_max_feature = VALUE_DISABLED;
9047 		dut->wnm_bss_max_idle_time = 0;
9048 		dut->wnm_bss_max_protection = VALUE_NOT_SET;
9049 		dut->ap_proxy_arp = 1;
9050 	} else {
9051 		/*
9052 		 * Do not touch the BSS-MAX Idle time feature
9053 		 * if the program is not IOTLP.
9054 		 */
9055 		dut->wnm_bss_max_feature = VALUE_NOT_SET;
9056 		dut->wnm_bss_max_idle_time = 0;
9057 		dut->wnm_bss_max_protection = VALUE_NOT_SET;
9058 	}
9059 
9060 	if (dut->program == PROGRAM_LOC) {
9061 		dut->ap_rrm = 1;
9062 		dut->ap_rtt = 1;
9063 		dut->ap_lci = 0;
9064 		dut->ap_val_lci[0] = '\0';
9065 		dut->ap_infoz[0] = '\0';
9066 		dut->ap_lcr = 0;
9067 		dut->ap_val_lcr[0] = '\0';
9068 		dut->ap_neighap = 0;
9069 		dut->ap_opchannel = 0;
9070 		dut->ap_scan = 0;
9071 		dut->ap_fqdn_held = 0;
9072 		dut->ap_fqdn_supl = 0;
9073 		dut->ap_interworking = 0;
9074 		dut->ap_gas_cb_delay = 0;
9075 		dut->ap_msnt_type = 0;
9076 	}
9077 	dut->ap_ft_oa = 0;
9078 	dut->ap_ft_ds = VALUE_NOT_SET;
9079 	dut->ap_reg_domain = REG_DOMAIN_NOT_SET;
9080 	dut->ap_mobility_domain[0] = '\0';
9081 
9082 	if (dut->program == PROGRAM_MBO) {
9083 		dut->ap_mbo = 1;
9084 		dut->ap_interworking = 1;
9085 		dut->ap_ne_class = 0;
9086 		dut->ap_ne_op_ch = 0;
9087 		dut->ap_set_bssidpref = 1;
9088 		dut->ap_btmreq_disassoc_imnt = 0;
9089 		dut->ap_btmreq_term_bit = 0;
9090 		dut->ap_disassoc_timer = 0;
9091 		dut->ap_btmreq_bss_term_dur = 0;
9092 		dut->ap_channel = 36;
9093 		dut->ap_chwidth = AP_20;
9094 		dut->ap_cell_cap_pref = 0;
9095 		dut->ap_gas_cb_delay = 0;
9096 		dut->mbo_self_ap_tuple.ap_ne_class = -1;
9097 		dut->mbo_self_ap_tuple.ap_ne_pref = -1; /* Not set */
9098 		dut->mbo_self_ap_tuple.ap_ne_op_ch = -1;
9099 		dut->ap_btmreq_bss_term_tsf = 0;
9100 		dut->ap_assoc_delay = 0;
9101 	}
9102 
9103 	if (dut->program == PROGRAM_OCE) {
9104 		if (dut->ap_dhcp_stop)
9105 			run_system(dut, "/etc/init.d/dnsmasq start");
9106 
9107 		dut->ap_dhcp_stop = 0;
9108 		dut->ap_oce = VALUE_ENABLED;
9109 		dut->ap_broadcast_ssid = VALUE_ENABLED;
9110 		dut->ap_fils_dscv_int = 20;
9111 		dut->ap_filsdscv = VALUE_ENABLED;
9112 		dut->ap_filshlp = VALUE_DISABLED;
9113 		dut->ap_rnr = VALUE_DISABLED;
9114 		dut->ap_nairealm[0] = '\0';
9115 		dut->ap_nairealm_int = 0;
9116 		dut->ap_blechanutil = 0;
9117 		dut->ap_ble_admit_cap = 0;
9118 		dut->ap_esp = VALUE_ENABLED;
9119 		dut->ap_datappdudura = 0;
9120 		dut->ap_airtimefract = 0;
9121 		dut->ap_blestacnt = 0;
9122 		dut->ap_ul_availcap = 0;
9123 		dut->ap_dl_availcap = 0;
9124 		dut->ap_akm = 0;
9125 		dut->ap_add_sha256 = 0;
9126 		dut->ap_add_sha384 = 0;
9127 		dut->ap_80plus80 = 0;
9128 	}
9129 
9130 	dut->ap_he_ppdu = PPDU_NOT_SET;
9131 	dut->ap_he_ulofdma = VALUE_NOT_SET;
9132 	dut->ap_numsounddim = 0;
9133 	dut->ap_bcc = VALUE_DISABLED;
9134 	dut->ap_mu_edca = VALUE_DISABLED;
9135 	dut->ap_he_mimo = MIMO_NOT_SET;
9136 	dut->ap_he_rtsthrshld = VALUE_NOT_SET;
9137 	dut->ap_mbssid = VALUE_DISABLED;
9138 	dut->ap_ampdu = VALUE_NOT_SET;
9139 	dut->he_mcsnssmap = 0;
9140 	dut->ap_fixed_rate = 0;
9141 	dut->he_mmss = 0;
9142 	dut->he_set_sta_1x1 = VALUE_DISABLED;
9143 	dut->he_srctrl_allow = -1;
9144 	if (dut->device_type == AP_testbed) {
9145 		dut->ap_he_dlofdma = VALUE_DISABLED;
9146 		dut->ap_he_frag = VALUE_DISABLED;
9147 		dut->ap_twtresp = VALUE_DISABLED;
9148 		dut->he_ul_mcs = 7;
9149 	} else {
9150 		dut->ap_he_dlofdma = VALUE_NOT_SET;
9151 		dut->ap_he_frag = VALUE_NOT_SET;
9152 		dut->ap_ba_bufsize = BA_BUFSIZE_NOT_SET;
9153 		dut->ap_twtresp = VALUE_NOT_SET;
9154 		dut->he_ul_mcs = 0;
9155 	}
9156 
9157 	if (dut->program == PROGRAM_HE) {
9158 		if (dut->device_type == AP_testbed) {
9159 			dut->ap_ldpc = VALUE_DISABLED;
9160 			dut->ap_ba_bufsize = BA_BUFSIZE_64;
9161 			dut->ap_amsdu = VALUE_DISABLED;
9162 			dut->ap_txBF = 0;
9163 			dut->ap_mu_txBF = 0;
9164 			dut->he_sounding = VALUE_DISABLED;
9165 		} else {
9166 			if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) {
9167 				dut->ap_txBF = 0;
9168 				dut->ap_mu_txBF = 0;
9169 			} else {
9170 				dut->ap_txBF = 1;
9171 				dut->ap_mu_txBF = 1;
9172 			}
9173 			dut->he_sounding = VALUE_ENABLED;
9174 			if (drv == DRIVER_LINUX_WCN) {
9175 				dut->ap_ldpc = VALUE_ENABLED;
9176 				wcn_config_ap_ldpc(dut, get_main_ifname(dut));
9177 #ifdef NL80211_SUPPORT
9178 				if (wcn_set_he_ltf(dut, get_main_ifname(dut),
9179 						   QCA_WLAN_HE_LTF_AUTO)) {
9180 					sigma_dut_print(dut, DUT_MSG_ERROR,
9181 							"Failed to set LTF in ap_reset_default");
9182 				}
9183 #endif /* NL80211_SUPPORT */
9184 			}
9185 		}
9186 		if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9187 			dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
9188 	}
9189 
9190 	dut->ap_oper_chn = 0;
9191 
9192 	dut->ap_pmksa = 0;
9193 	dut->ap_pmksa_caching = 0;
9194 
9195 	free(dut->rsne_override);
9196 	dut->rsne_override = NULL;
9197 	free(dut->rsnxe_override_eapol);
9198 	dut->rsnxe_override_eapol = NULL;
9199 
9200 	free(dut->sae_commit_override);
9201 	dut->sae_commit_override = NULL;
9202 
9203 	free(dut->ap_sae_groups);
9204 	dut->ap_sae_groups = NULL;
9205 
9206 	dut->sae_anti_clogging_threshold = -1;
9207 	dut->sae_reflection = 0;
9208 	dut->sae_confirm_immediate = 0;
9209 	dut->sae_pwe = SAE_PWE_DEFAULT;
9210 
9211 	dut->ap_cipher = AP_CCMP;
9212 	dut->ap_group_cipher = AP_NO_GROUP_CIPHER_SET;
9213 	dut->ap_group_mgmt_cipher = AP_NO_GROUP_MGMT_CIPHER_SET;
9214 	dut->ap_passphrase[0] = '\0';
9215 	dut->ap_psk[0] = '\0';
9216 	dut->ap_beacon_prot = 0;
9217 	dut->ap_transition_disable = 0;
9218 
9219 	dut->dpp_conf_id = -1;
9220 	free(dut->ap_dpp_conf_addr);
9221 	dut->ap_dpp_conf_addr = NULL;
9222 	free(dut->ap_dpp_conf_pkhash);
9223 	dut->ap_dpp_conf_pkhash = NULL;
9224 	dut->ap_start_disabled = 0;
9225 
9226 	if (is_60g_sigma_dut(dut)) {
9227 		dut->ap_mode = AP_11ad;
9228 		dut->ap_channel = 2;
9229 		dut->wps_disable = 0; /* WPS is enabled */
9230 		dut->ap_pmf = 0;
9231 		dut->ap_num_ese_allocs = 0;
9232 		dut->ap_fixed_rate = 0;
9233 
9234 		dut->dev_role = DEVROLE_AP;
9235 
9236 		sigma_dut_print(dut, DUT_MSG_DEBUG,
9237 				"Setting msdu_size to MAX: 7912");
9238 		snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
9239 			 get_main_ifname(dut));
9240 
9241 		if (system(buf) != 0) {
9242 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9243 					buf);
9244 			return ERROR_SEND_STATUS;
9245 		}
9246 
9247 		if (ap_set_force_mcs(dut, 0, 1)) {
9248 			sigma_dut_print(dut, DUT_MSG_ERROR,
9249 					"Failed to reset force MCS");
9250 			return ERROR_SEND_STATUS;
9251 		}
9252 
9253 		if (set_ps(get_main_ifname(dut), dut, 1)) {
9254 			sigma_dut_print(dut, DUT_MSG_ERROR,
9255 					"Failed to enable power save");
9256 			return ERROR_SEND_STATUS;
9257 		}
9258 	}
9259 
9260 	if (dut->program == PROGRAM_WPS &&
9261 	    get_driver_type(dut) == DRIVER_WIL6210) {
9262 		/*
9263 		 * In 60 GHz WPS tests, we configure the AP OOB to
9264 		 * secure connection with a random passphrase.
9265 		 */
9266 		char r[16], passphrase[65];
9267 
9268 		if (random_get_bytes(r, sizeof(r))) {
9269 			sigma_dut_print(dut, DUT_MSG_ERROR,
9270 					"Failed to get random bytes");
9271 			return ERROR_SEND_STATUS;
9272 		}
9273 		if (base64_encode(r, sizeof(r),
9274 				  passphrase, sizeof(passphrase))) {
9275 			sigma_dut_print(dut, DUT_MSG_ERROR,
9276 					"Failed to generate random passphrase");
9277 			return ERROR_SEND_STATUS;
9278 		}
9279 
9280 		dut->ap_key_mgmt = AP_WPA2_PSK;
9281 		dut->ap_cipher = AP_GCMP_128;
9282 		strlcpy(dut->ap_passphrase, passphrase,
9283 			sizeof(dut->ap_passphrase));
9284 		sigma_dut_print(dut, DUT_MSG_DEBUG,
9285 				"60G WPS: configure secure AP with random passphrase");
9286 	}
9287 
9288 	dut->hostapd_running = 0;
9289 
9290 	if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9291 		return 1;
9292 
9293 	if (dut->use_hostapd_pid_file) {
9294 		kill_hostapd_process_pid(dut);
9295 	} else if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
9296 		   system("killall hostapd") == 0) {
9297 		int i;
9298 		/* Wait some time to allow hostapd to complete cleanup before
9299 		 * starting a new process */
9300 		for (i = 0; i < 10; i++) {
9301 			usleep(500000);
9302 			if (system("pidof hostapd") != 0)
9303 				break;
9304 		}
9305 	}
9306 
9307 	if (if_nametoindex("sigmadut") > 0 &&
9308 	    system("iw dev sigmadut del") != 0)
9309 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove "
9310 				"monitor interface");
9311 
9312 	return 1;
9313 }
9314 
9315 
9316 int sta_cfon_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
9317 			   struct sigma_cmd *cmd)
9318 {
9319 	return cmd_ap_reset_default(dut, conn, cmd);
9320 }
9321 
9322 
9323 static enum sigma_cmd_result cmd_ap_get_info(struct sigma_dut *dut,
9324 					     struct sigma_conn *conn,
9325 					     struct sigma_cmd *cmd)
9326 {
9327 	/* const char *name = get_param(cmd, "NAME"); */
9328 	struct stat s;
9329 	char resp[200];
9330 	FILE *f;
9331 	enum driver_type drv = get_driver_type(dut);
9332 	int res;
9333 
9334 	switch (drv) {
9335 	case DRIVER_ATHEROS: {
9336 		/* Atheros AP */
9337 		struct utsname uts;
9338 		char *version, athver[100];
9339 
9340 		if (stat("/proc/athversion", &s) != 0) {
9341 			if (system("/etc/rc.d/rc.wlan up") != 0) {
9342 			}
9343 		}
9344 
9345 		athver[0] = '\0';
9346 		f = fopen("/proc/athversion", "r");
9347 		if (f) {
9348 			if (fgets(athver, sizeof(athver), f)) {
9349 				char *pos = strchr(athver, '\n');
9350 				if (pos)
9351 					*pos = '\0';
9352 			}
9353 			fclose(f);
9354 		}
9355 
9356 		if (uname(&uts) == 0)
9357 			version = uts.release;
9358 		else
9359 			version = "Unknown";
9360 
9361 		if (if_nametoindex("ath1") > 0)
9362 			res = snprintf(resp, sizeof(resp),
9363 				       "interface,ath0_24G ath1_5G,agent,1.0,version,%s/drv:%s",
9364 				       version, athver);
9365 		else
9366 			res = snprintf(resp, sizeof(resp),
9367 				       "interface,ath0_24G,agent,1.0,version,%s/drv:%s",
9368 				       version, athver);
9369 		if (res < 0 || res >= sizeof(resp))
9370 			send_resp(dut, conn, SIGMA_ERROR, NULL);
9371 		else
9372 			send_resp(dut, conn, SIGMA_COMPLETE, resp);
9373 		return 0;
9374 	}
9375 	case DRIVER_LINUX_WCN:
9376 	case DRIVER_MAC80211: {
9377 		struct utsname uts;
9378 		char *version;
9379 
9380 		if (uname(&uts) == 0)
9381 			version = uts.release;
9382 		else
9383 			version = "Unknown";
9384 
9385 		if (if_nametoindex("wlan1") > 0)
9386 			snprintf(resp, sizeof(resp), "interface,wlan0_24G "
9387 				 "wlan1_5G,agent,1.0,version,%s", version);
9388 		else
9389 			snprintf(resp, sizeof(resp), "interface,wlan0_any,"
9390 				 "agent,1.0,version,%s", version);
9391 
9392 		send_resp(dut, conn, SIGMA_COMPLETE, resp);
9393 		return 0;
9394 	}
9395 	case DRIVER_QNXNTO: {
9396 		struct utsname uts;
9397 		char *version;
9398 
9399 		if (uname(&uts) == 0)
9400 			version = uts.release;
9401 		else
9402 			version = "Unknown";
9403 		snprintf(resp, sizeof(resp),
9404 			 "interface,%s_any,agent,1.0,version,%s",
9405 			 dut->main_ifname ? get_main_ifname(dut) : "NA",
9406 			 version);
9407 		send_resp(dut, conn, SIGMA_COMPLETE, resp);
9408 		return 0;
9409 	}
9410 	case DRIVER_OPENWRT: {
9411 		switch (get_openwrt_driver_type()) {
9412 		case OPENWRT_DRIVER_ATHEROS: {
9413 			struct utsname uts;
9414 			char *version;
9415 
9416 			if (uname(&uts) == 0)
9417 				version = uts.release;
9418 			else
9419 				version = "Unknown";
9420 
9421 			if (if_nametoindex("ath1") > 0)
9422 				snprintf(resp, sizeof(resp),
9423 					 "interface,ath0_5G ath1_24G,agent,1.0,version,%s",
9424 					 version);
9425 			else
9426 				snprintf(resp, sizeof(resp),
9427 					 "interface,ath0_any,agent,1.0,version,%s",
9428 					 version);
9429 
9430 			send_resp(dut, conn, SIGMA_COMPLETE, resp);
9431 			return 0;
9432 		}
9433 		default:
9434 			send_resp(dut, conn, SIGMA_ERROR,
9435 				  "errorCode,Unsupported openwrt driver");
9436 			return 0;
9437 		}
9438 	}
9439 	default:
9440 		send_resp(dut, conn, SIGMA_ERROR,
9441 			  "errorCode,Unsupported driver");
9442 		return 0;
9443 	}
9444 }
9445 
9446 
9447 static enum sigma_cmd_result cmd_ap_deauth_sta(struct sigma_dut *dut,
9448 					       struct sigma_conn *conn,
9449 					       struct sigma_cmd *cmd)
9450 {
9451 	/* const char *name = get_param(cmd, "NAME"); */
9452 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
9453 	const char *val, *disconnect;
9454 	char buf[100];
9455 
9456 	val = get_param(cmd, "MinorCode");
9457 	if (val) {
9458 		/* TODO: add support for P2P minor code */
9459 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,MinorCode not "
9460 			  "yet supported");
9461 		return 0;
9462 	}
9463 
9464 	val = get_param(cmd, "STA_MAC_ADDRESS");
9465 	if (val == NULL)
9466 		return -1;
9467 	disconnect = get_param(cmd, "disconnect");
9468 	if (disconnect && strcasecmp(disconnect, "silent") == 0)
9469 		snprintf(buf, sizeof(buf), "deauth %s tx=0", val);
9470 	else
9471 		snprintf(buf, sizeof(buf), "deauth %s", val);
9472 	if (run_hostapd_cli(dut, buf) != 0)
9473 		return -2;
9474 
9475 	return 1;
9476 }
9477 
9478 
9479 #ifdef __linux__
9480 int inject_frame(int s, const void *data, size_t len, int encrypt);
9481 int open_monitor(const char *ifname);
9482 #endif /* __linux__ */
9483 
9484 enum send_frame_type {
9485 		DISASSOC, DEAUTH, SAQUERY
9486 };
9487 enum send_frame_protection {
9488 	CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9489 };
9490 
9491 
9492 static int ap_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9493 			   enum send_frame_type frame,
9494 			   enum send_frame_protection protected,
9495 			   const char *sta_addr)
9496 {
9497 #ifdef __linux__
9498 	unsigned char buf[1000], *pos;
9499 	int s, res;
9500 	unsigned char addr_sta[6], addr_own[6];
9501 	char *ifname;
9502 	char cbuf[100];
9503 	struct ifreq ifr;
9504 
9505 	if ((dut->ap_mode == AP_11a || dut->ap_mode == AP_11na ||
9506 	     dut->ap_mode == AP_11ac) &&
9507 	    if_nametoindex("wlan1") > 0)
9508 		ifname = "wlan1";
9509 	else
9510 		ifname = "wlan0";
9511 
9512 	if (hwaddr_aton(sta_addr, addr_sta) < 0)
9513 		return -1;
9514 
9515 	s = socket(AF_INET, SOCK_DGRAM, 0);
9516 	if (s < 0)
9517 		return -1;
9518 	memset(&ifr, 0, sizeof(ifr));
9519 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
9520 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
9521 		perror("ioctl");
9522 		close(s);
9523 		return -1;
9524 	}
9525 	close(s);
9526 	memcpy(addr_own, ifr.ifr_hwaddr.sa_data, 6);
9527 
9528 	if (if_nametoindex("sigmadut") == 0) {
9529 		snprintf(cbuf, sizeof(cbuf),
9530 			 "iw dev %s interface add sigmadut type monitor",
9531 			 ifname);
9532 		if (system(cbuf) != 0 ||
9533 		    if_nametoindex("sigmadut") == 0) {
9534 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9535 					"monitor interface with '%s'", cbuf);
9536 			return -2;
9537 		}
9538 	}
9539 
9540 	if (system("ifconfig sigmadut up") != 0) {
9541 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9542 				"monitor interface up");
9543 		return -2;
9544 	}
9545 
9546 	pos = buf;
9547 
9548 	/* Frame Control */
9549 	switch (frame) {
9550 	case DISASSOC:
9551 		*pos++ = 0xa0;
9552 		break;
9553 	case DEAUTH:
9554 		*pos++ = 0xc0;
9555 		break;
9556 	case SAQUERY:
9557 		*pos++ = 0xd0;
9558 		break;
9559 	}
9560 
9561 	if (protected == INCORRECT_KEY)
9562 		*pos++ = 0x40; /* Set Protected field to 1 */
9563 	else
9564 		*pos++ = 0x00;
9565 
9566 	/* Duration */
9567 	*pos++ = 0x00;
9568 	*pos++ = 0x00;
9569 
9570 	/* addr1 = DA (station) */
9571 	memcpy(pos, addr_sta, 6);
9572 	pos += 6;
9573 	/* addr2 = SA (own address) */
9574 	memcpy(pos, addr_own, 6);
9575 	pos += 6;
9576 	/* addr3 = BSSID (own address) */
9577 	memcpy(pos, addr_own, 6);
9578 	pos += 6;
9579 
9580 	/* Seq# (to be filled by driver/mac80211) */
9581 	*pos++ = 0x00;
9582 	*pos++ = 0x00;
9583 
9584 	if (protected == INCORRECT_KEY) {
9585 		/* CCMP parameters */
9586 		memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9587 		pos += 8;
9588 	}
9589 
9590 	if (protected == INCORRECT_KEY) {
9591 		switch (frame) {
9592 		case DEAUTH:
9593 			/* Reason code (encrypted) */
9594 			memcpy(pos, "\xa7\x39", 2);
9595 			pos += 2;
9596 			break;
9597 		case DISASSOC:
9598 			/* Reason code (encrypted) */
9599 			memcpy(pos, "\xa7\x39", 2);
9600 			pos += 2;
9601 			break;
9602 		case SAQUERY:
9603 			/* Category|Action|TransID (encrypted) */
9604 			memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9605 			pos += 4;
9606 			break;
9607 		default:
9608 			return -1;
9609 		}
9610 
9611 		/* CCMP MIC */
9612 		memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9613 		pos += 8;
9614 	} else {
9615 		switch (frame) {
9616 		case DEAUTH:
9617 			/* reason code = 8 */
9618 			*pos++ = 0x08;
9619 			*pos++ = 0x00;
9620 			break;
9621 		case DISASSOC:
9622 			/* reason code = 8 */
9623 			*pos++ = 0x08;
9624 			*pos++ = 0x00;
9625 			break;
9626 		case SAQUERY:
9627 			/* Category - SA Query */
9628 			*pos++ = 0x08;
9629 			/* SA query Action - Request */
9630 			*pos++ = 0x00;
9631 			/* Transaction ID */
9632 			*pos++ = 0x12;
9633 			*pos++ = 0x34;
9634 			break;
9635 		}
9636 	}
9637 
9638 	s = open_monitor("sigmadut");
9639 	if (s < 0) {
9640 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9641 			  "monitor socket");
9642 		return 0;
9643 	}
9644 
9645 	res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9646 	if (res < 0) {
9647 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9648 			  "inject frame");
9649 		close(s);
9650 		return 0;
9651 	}
9652 	if (res < pos - buf) {
9653 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9654 			  "frame sent");
9655 		close(s);
9656 		return 0;
9657 	}
9658 
9659 	close(s);
9660 
9661 	return 1;
9662 #else /* __linux__ */
9663 	send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_send_frame not "
9664 		  "yet supported");
9665 	return 0;
9666 #endif /* __linux__ */
9667 }
9668 
9669 
9670 int ap_send_frame_hs2(struct sigma_dut *dut, struct sigma_conn *conn,
9671 		      struct sigma_cmd *cmd)
9672 {
9673 	const char *val, *dest;
9674 	char buf[100];
9675 
9676 	val = get_param(cmd, "FrameName");
9677 	if (val == NULL)
9678 		return -1;
9679 
9680 	if (strcasecmp(val, "QoSMapConfigure") == 0) {
9681 		dest = get_param(cmd, "Dest");
9682 		if (!dest)
9683 			return -1;
9684 
9685 		val = get_param(cmd, "QoS_MAP_SET");
9686 		if (val) {
9687 			dut->ap_qos_map_set = atoi(val);
9688 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
9689 					dut->ap_qos_map_set);
9690 		}
9691 
9692 		if (dut->ap_qos_map_set == 1)
9693 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1);
9694 		else if (dut->ap_qos_map_set == 2)
9695 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2);
9696 
9697 		snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest);
9698 		if (run_hostapd_cli(dut, buf) != 0)
9699 			return -1;
9700 	}
9701 
9702 	return 1;
9703 }
9704 
9705 
9706 static int ath_ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn,
9707 				 struct sigma_cmd *cmd)
9708 {
9709 	const char *val;
9710 	const char *ifname;
9711 	int chwidth, nss;
9712 
9713 	val = get_param(cmd, "FrameName");
9714 	if (!val || strcasecmp(val, "op_md_notif_frm") != 0) {
9715 		send_resp(dut, conn, SIGMA_ERROR,
9716 			  "errorCode,Unsupported FrameName");
9717 		return 0;
9718 	}
9719 
9720 	/*
9721 	 * Sequence of commands for Opmode notification on
9722 	 * Peregrine based products
9723 	 */
9724 	ifname = get_main_ifname(dut);
9725 
9726 	/* Disable STBC */
9727 	run_iwpriv(dut, ifname, "tx_stbc 0");
9728 
9729 	/* Check whether optional arg channel width was passed */
9730 	val = get_param(cmd, "Channel_width");
9731 	if (val) {
9732 		switch (atoi(val)) {
9733 		case 20:
9734 			chwidth = 0;
9735 			break;
9736 		case 40:
9737 			chwidth = 1;
9738 			break;
9739 		case 80:
9740 			chwidth = 2;
9741 			break;
9742 		case 160:
9743 			chwidth = 3;
9744 			break;
9745 		default:
9746 			chwidth = 2;
9747 			break;
9748 		}
9749 		run_iwpriv(dut, ifname, "chwidth %d", chwidth);
9750 	}
9751 
9752 	/* Check whether optional arg NSS was passed */
9753 	val = get_param(cmd, "NSS");
9754 	if (val) {
9755 		/* Convert nss to chainmask */
9756 		switch (atoi(val)) {
9757 		case 1:
9758 			nss = 1;
9759 			break;
9760 		case 2:
9761 			nss = 3;
9762 			break;
9763 		case 3:
9764 			nss = 7;
9765 			break;
9766 		default:
9767 			/* We do not support NSS > 3 */
9768 			nss = 3;
9769 			break;
9770 		}
9771 		run_iwpriv(dut, ifname, "rxchainmask %d", nss);
9772 	}
9773 
9774 	/* Send the opmode notification */
9775 	run_iwpriv(dut, ifname, "opmode_notify 1");
9776 
9777 	return 1;
9778 }
9779 
9780 
9781 static int ath_ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn,
9782 				 struct sigma_cmd *cmd)
9783 {
9784 	const char *val;
9785 	FILE *f;
9786 	int rand_int = 0;
9787 
9788 	val = get_param(cmd, "MsntType");
9789 	if (val) {
9790 		if (dut->ap_msnt_type == 0)
9791 			dut->ap_msnt_type = atoi(val);
9792 
9793 		if (dut->ap_msnt_type != 5 && dut->ap_msnt_type != 2) {
9794 			dut->ap_msnt_type = atoi(val);
9795 			if (dut->ap_msnt_type == 1) {
9796 				val = get_param(cmd, "RandInterval");
9797 				if (val)
9798 					rand_int = atoi(val);
9799 				f = fopen("/tmp/ftmrr.txt", "a");
9800 				if (!f) {
9801 					sigma_dut_print(dut, DUT_MSG_ERROR,
9802 							"Failed to open /tmp/ftmrr.txt");
9803 					return -1;
9804 				}
9805 
9806 				fprintf(f, "sta_mac = %s\n", cmd->values[3]);
9807 				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",
9808 					rand_int, cmd->values[7]);
9809 				fclose(f);
9810 				dut->ap_msnt_type = 5;
9811 				run_system(dut, "wpc -f /tmp/ftmrr.txt");
9812 			}
9813 		} else if (dut->ap_msnt_type == 5) {
9814 			run_system(dut, "wpc -f /tmp/ftmrr.txt");
9815 		} else if (dut->ap_msnt_type == 2) {
9816 			f = fopen("/tmp/wru.txt", "w");
9817 			if (!f) {
9818 				sigma_dut_print(dut, DUT_MSG_ERROR,
9819 						"Failed to open /tmp/wru.txt");
9820 				return -1;
9821 			}
9822 
9823 			fprintf(f, "sta_mac = %s\n", cmd->values[3]);
9824 			fprintf(f, "meas_type = 0x08\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0x1\nmeas_req_mode = 0x00\nloc_subject = 0x01\n");
9825 			fclose(f);
9826 			run_system(dut, "wpc -w /tmp/wru.txt");
9827 		}
9828 	}
9829 	return 1;
9830 }
9831 
9832 
9833 /*
9834  * The following functions parse_send_frame_params_int(),
9835  * parse_send_frame_params_str(), and parse_send_frame_params_mac()
9836  * are used by ath_ap_send_frame_bcn_rpt_req().
9837  * Beacon Report Request is a frame used as part of the MBO program.
9838  * The command for sending beacon report has a lot of
9839  * arguments and having these functions reduces code size.
9840  *
9841  */
9842 static int parse_send_frame_params_int(char *param, struct sigma_cmd *cmd,
9843 				       struct sigma_dut *dut,
9844 				       char *buf, size_t buf_size)
9845 {
9846 	const char *str_val;
9847 	int int_val;
9848 	char temp[100];
9849 
9850 	str_val = get_param(cmd, param);
9851 	if (!str_val) {
9852 		sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
9853 		return -1;
9854 	}
9855 	int_val = atoi(str_val);
9856 	snprintf(temp, sizeof(temp), " %d", int_val);
9857 	strlcat(buf, temp, buf_size);
9858 	return 0;
9859 }
9860 
9861 
9862 static int parse_send_frame_params_str(char *param, struct sigma_cmd *cmd,
9863 				       struct sigma_dut *dut,
9864 				       char *buf, size_t buf_size)
9865 {
9866 	const char *str_val;
9867 	char temp[100];
9868 
9869 	str_val = get_param(cmd, param);
9870 	if (!str_val) {
9871 		sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
9872 		return -1;
9873 	}
9874 	snprintf(temp, sizeof(temp), " %s", str_val);
9875 	temp[sizeof(temp) - 1] = '\0';
9876 	strlcat(buf, temp, buf_size);
9877 	return 0;
9878 }
9879 
9880 
9881 static int parse_send_frame_params_mac(char *param, struct sigma_cmd *cmd,
9882 				       struct sigma_dut *dut,
9883 				       char *buf, size_t buf_size)
9884 {
9885 	const char *str_val;
9886 	unsigned char mac[6];
9887 	char temp[100];
9888 
9889 	str_val = get_param(cmd, param);
9890 	if (!str_val) {
9891 		sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
9892 		return -1;
9893 	}
9894 
9895 	if (parse_mac_address(dut, str_val, mac) < 0) {
9896 		sigma_dut_print(dut, DUT_MSG_ERROR,
9897 				"MAC Address not in proper format");
9898 		return -1;
9899 	}
9900 	snprintf(temp, sizeof(temp), " %02x:%02x:%02x:%02x:%02x:%02x",
9901 		 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
9902 	strlcat(buf, temp, buf_size);
9903 	return 0;
9904 }
9905 
9906 
9907 static void fill_1_or_0_based_on_presence(struct sigma_cmd *cmd, char *param,
9908 					  char *buf, size_t buf_size)
9909 {
9910 	const char *str_val;
9911 	char *value = " 1";
9912 
9913 	str_val = get_param(cmd, param);
9914 	if (!str_val || str_val[0] == '\0')
9915 		value = " 0";
9916 	strlcat(buf, value, buf_size);
9917 
9918 }
9919 
9920 
9921 /*
9922  * wifitool athN sendbcnrpt
9923  * <STA MAC        - Plugs in from Dest_MAC>
9924  * <regclass       - Plugs in from RegClass - int>
9925  * <channum        - Plugs in from Channel PARAM of dev_send_frame - int>
9926  * <rand_ivl       - Plugs in from RandInt - string>
9927  * <duration       - Plugs in from MeaDur - integer>
9928  * <mode           - Plugs in from MeaMode - string>
9929  * <req_ssid       - Plugs in from SSID PARAM of dev_send_frame - string>
9930  * <rep_cond       - Plugs in from RptCond - integer>
9931  * <rpt_detail     - Plugs in from RptDet - integer>
9932  * <req_ie         - Plugs in from ReqInfo PARAM of dev_send_frame - string>
9933  * <chanrpt_mode   - Plugs in from APChanRpt - integer>
9934  * <specific_bssid - Plugs in from BSSID PARAM of dev_send_frame>
9935  * [AP channel numbers]
9936  */
9937 static int ath_ap_send_frame_bcn_rpt_req(struct sigma_dut *dut,
9938 					 struct sigma_cmd *cmd,
9939 					 const char *ifname)
9940 {
9941 	char buf[100];
9942 	int rpt_det;
9943 	const char *str_val;
9944 	const char *mea_mode;
9945 
9946 	snprintf(buf, sizeof(buf), "wifitool %s sendbcnrpt", ifname);
9947 
9948 	if (parse_send_frame_params_mac("Dest_MAC", cmd, dut, buf, sizeof(buf)))
9949 		return -1;
9950 	if (parse_send_frame_params_int("RegClass", cmd, dut, buf, sizeof(buf)))
9951 		return -1;
9952 	if (parse_send_frame_params_int("Channel", cmd, dut, buf, sizeof(buf)))
9953 		return -1;
9954 	if (parse_send_frame_params_str("RandInt", cmd, dut, buf, sizeof(buf)))
9955 		return -1;
9956 	if (parse_send_frame_params_int("MeaDur", cmd, dut, buf, sizeof(buf)))
9957 		return -1;
9958 
9959 	str_val = get_param(cmd, "MeaMode");
9960 	if (!str_val) {
9961 		sigma_dut_print(dut, DUT_MSG_ERROR,
9962 				"MeaMode parameter not present in send bcn-rpt-req");
9963 		return -1;
9964 	}
9965 	if (strcasecmp(str_val, "passive") == 0) {
9966 		mea_mode = " 0";
9967 	} else if (strcasecmp(str_val, "active") == 0) {
9968 		mea_mode = " 1";
9969 	} else if (strcasecmp(str_val, "table") == 0) {
9970 		mea_mode = " 2";
9971 	} else {
9972 		sigma_dut_print(dut, DUT_MSG_ERROR,
9973 				"MEA-MODE Value not correctly given");
9974 		return -1;
9975 	}
9976 	strlcat(buf, mea_mode, sizeof(buf));
9977 
9978 	fill_1_or_0_based_on_presence(cmd, "SSID", buf, sizeof(buf));
9979 
9980 	if (parse_send_frame_params_int("RptCond", cmd, dut, buf, sizeof(buf)))
9981 		return -1;
9982 
9983 	if (parse_send_frame_params_int("RptDet", cmd, dut, buf, sizeof(buf)))
9984 		return -1;
9985 	str_val = get_param(cmd, "RptDet");
9986 	rpt_det = str_val ? atoi(str_val) : 0;
9987 
9988 	if (rpt_det)
9989 		fill_1_or_0_based_on_presence(cmd, "ReqInfo", buf, sizeof(buf));
9990 	else
9991 		strlcat(buf, " 0", sizeof(buf));
9992 
9993 	if (rpt_det)
9994 		fill_1_or_0_based_on_presence(cmd, "APChanRpt", buf,
9995 					      sizeof(buf));
9996 	else
9997 		strlcat(buf, " 0", sizeof(buf));
9998 
9999 	if (parse_send_frame_params_mac("BSSID", cmd, dut, buf, sizeof(buf)))
10000 		return -1;
10001 
10002 	str_val = get_param(cmd, "APChanRpt");
10003 	if (str_val) {
10004 		const char *pos;
10005 		int ap_chanrpt;
10006 		int ap_chanrpt_2 = 0;
10007 		char chanrpt[100];
10008 
10009 		ap_chanrpt = atoi(str_val);
10010 		pos = strchr(str_val, '_');
10011 		if (pos) {
10012 			pos++;
10013 			ap_chanrpt_2 = atoi(pos);
10014 		}
10015 		if (ap_chanrpt) {
10016 			snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt);
10017 			strlcat(buf, chanrpt, sizeof(buf));
10018 		}
10019 		if (ap_chanrpt_2) {
10020 			snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt_2);
10021 			strlcat(buf, chanrpt, sizeof(buf));
10022 		}
10023 	}
10024 
10025 	run_system(dut, buf);
10026 	return 0;
10027 }
10028 
10029 
10030 static void inform_and_sleep(struct sigma_dut *dut, int seconds)
10031 {
10032 	sigma_dut_print(dut, DUT_MSG_DEBUG, "sleeping for %d seconds", seconds);
10033 	sleep(seconds);
10034 	sigma_dut_print(dut, DUT_MSG_DEBUG, "woke up after %d seconds",
10035 			seconds);
10036 }
10037 
10038 
10039 static int ath_ap_send_frame_btm_req(struct sigma_dut *dut,
10040 				     struct sigma_cmd *cmd, const char *ifname)
10041 {
10042 	unsigned char mac_addr[ETH_ALEN];
10043 	int disassoc_timer;
10044 	char buf[100];
10045 	const char *val;
10046 	int cand_list = 1;
10047 
10048 	val = get_param(cmd, "Dest_MAC");
10049 	if (!val || parse_mac_address(dut, val, mac_addr) < 0) {
10050 		sigma_dut_print(dut, DUT_MSG_ERROR,
10051 				"MAC Address not in proper format");
10052 		return -1;
10053 	}
10054 
10055 	val = get_param(cmd, "Disassoc_Timer");
10056 	if (val)
10057 		disassoc_timer = atoi(val);
10058 	else
10059 		disassoc_timer = dut->ap_disassoc_timer;
10060 	if (disassoc_timer < 0) {
10061 		sigma_dut_print(dut, DUT_MSG_ERROR,
10062 				"Invalid Disassoc_Timer value %d",
10063 				disassoc_timer);
10064 		return -1;
10065 	}
10066 
10067 	val = get_param(cmd, "Cand_List");
10068 	if (val && val[0])
10069 		cand_list = atoi(val);
10070 
10071 	val = get_param(cmd, "BTMQuery_Reason_Code");
10072 	if (val)
10073 		run_iwpriv(dut, ifname, "mbo_trans_rs %s", val);
10074 
10075 	if (dut->ap_btmreq_disassoc_imnt && !dut->ap_assoc_delay)
10076 		run_iwpriv(dut, ifname, "mbo_asoc_ret 1");
10077 
10078 	snprintf(buf, sizeof(buf),
10079 		 "wifitool %s sendbstmreq %02x:%02x:%02x:%02x:%02x:%02x %d %d 15 %d %d %d %d",
10080 		 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
10081 		 mac_addr[4], mac_addr[5], cand_list, disassoc_timer,
10082 		 dut->ap_btmreq_disassoc_imnt,
10083 		 dut->ap_btmreq_term_bit,
10084 		 dut->ap_btmreq_bss_term_tsf,
10085 		 dut->ap_btmreq_bss_term_dur);
10086 	run_system(dut, buf);
10087 
10088 	if (dut->ap_btmreq_term_bit) {
10089 		if (dut->ap_btmreq_bss_term_tsf >= 2)
10090 			inform_and_sleep(dut, dut->ap_btmreq_bss_term_tsf - 2);
10091 		run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10092 			   mac_addr[0], mac_addr[1], mac_addr[2],
10093 			   mac_addr[3], mac_addr[4], mac_addr[5]);
10094 		inform_and_sleep(dut, 2);
10095 		run_system_wrapper(dut, "ifconfig %s down", ifname);
10096 		inform_and_sleep(dut, 5);
10097 		run_system_wrapper(dut, "ifconfig %s up", ifname);
10098 	} else if (dut->ap_btmreq_disassoc_imnt) {
10099 		inform_and_sleep(dut, (disassoc_timer / 1000) + 1);
10100 		run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10101 			   mac_addr[0], mac_addr[1], mac_addr[2],
10102 			   mac_addr[3], mac_addr[4], mac_addr[5]);
10103 	}
10104 	return 0;
10105 }
10106 
10107 
10108 static int ath_ap_send_frame_disassoc(struct sigma_dut *dut,
10109 				      struct sigma_cmd *cmd, const char *ifname)
10110 {
10111 	unsigned char mac_addr[ETH_ALEN];
10112 	const char *val;
10113 
10114 	val = get_param(cmd, "Dest_MAC");
10115 	if (!val || parse_mac_address(dut, val, mac_addr) < 0) {
10116 		sigma_dut_print(dut, DUT_MSG_ERROR,
10117 				"MAC Address not in proper format");
10118 		return -1;
10119 	}
10120 
10121 	run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10122 		   mac_addr[0], mac_addr[1], mac_addr[2],
10123 		   mac_addr[3], mac_addr[4], mac_addr[5]);
10124 	return 0;
10125 }
10126 
10127 
10128 static int ath_ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn,
10129 				 struct sigma_cmd *cmd)
10130 {
10131 	const char *val;
10132 	const char *ifname;
10133 
10134 	ifname = get_main_ifname(dut);
10135 
10136 	val = get_param(cmd, "FrameName");
10137 	if (!val)
10138 		return -1;
10139 
10140 	if (strcasecmp(val, "BTMReq") == 0)
10141 		ath_ap_send_frame_btm_req(dut, cmd, ifname);
10142 	else if (strcasecmp(val, "BcnRptReq") == 0)
10143 		ath_ap_send_frame_bcn_rpt_req(dut, cmd, ifname);
10144 	else if (strcasecmp(val, "disassoc") == 0)
10145 		ath_ap_send_frame_disassoc(dut, cmd, ifname);
10146 	else
10147 		return -1;
10148 
10149 	return 1;
10150 }
10151 
10152 
10153 static int ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10154 			     struct sigma_cmd *cmd)
10155 {
10156 	switch (get_driver_type(dut)) {
10157 	case DRIVER_ATHEROS:
10158 		return ath_ap_send_frame_vht(dut, conn, cmd);
10159 		break;
10160 	case DRIVER_OPENWRT:
10161 		switch (get_openwrt_driver_type()) {
10162 		case OPENWRT_DRIVER_ATHEROS:
10163 			return ath_ap_send_frame_vht(dut, conn, cmd);
10164 		default:
10165 			send_resp(dut, conn, SIGMA_ERROR,
10166 				  "errorCode,Unsupported ap_send_frame with the current openwrt driver");
10167 			return 0;
10168 		}
10169 	default:
10170 		send_resp(dut, conn, SIGMA_ERROR,
10171 			  "errorCode,Unsupported ap_send_frame with the current driver");
10172 		return 0;
10173 	}
10174 }
10175 
10176 
10177 static int ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn,
10178 			     struct sigma_cmd *cmd)
10179 {
10180 	switch (get_driver_type(dut)) {
10181 	case DRIVER_ATHEROS:
10182 		return ath_ap_send_frame_loc(dut, conn, cmd);
10183 	case DRIVER_OPENWRT:
10184 		switch (get_openwrt_driver_type()) {
10185 		case OPENWRT_DRIVER_ATHEROS:
10186 			return ath_ap_send_frame_loc(dut, conn, cmd);
10187 		default:
10188 			send_resp(dut, conn, SIGMA_ERROR,
10189 				  "errorCode,Unsupported ap_send_frame_loc with the current openwrt driver");
10190 			return 0;
10191 		}
10192 	default:
10193 		send_resp(dut, conn, SIGMA_ERROR,
10194 			  "errorCode,Unsupported ap_send_frame_loc with the current driver");
10195 		return 0;
10196 	}
10197 }
10198 
10199 
10200 static int ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn,
10201 			     struct sigma_cmd *cmd)
10202 {
10203 	switch (get_driver_type(dut)) {
10204 	case DRIVER_ATHEROS:
10205 		return ath_ap_send_frame_mbo(dut, conn, cmd);
10206 	case DRIVER_OPENWRT:
10207 		switch (get_openwrt_driver_type()) {
10208 		case OPENWRT_DRIVER_ATHEROS:
10209 			return ath_ap_send_frame_mbo(dut, conn, cmd);
10210 		default:
10211 			send_resp(dut, conn, SIGMA_ERROR,
10212 				  "errorCode,Unsupported ap_send_frame with the current openwrt driver");
10213 			return 0;
10214 		}
10215 	default:
10216 		send_resp(dut, conn, SIGMA_ERROR,
10217 			  "errorCode,Unsupported ap_send_frame with the current driver");
10218 		return 0;
10219 	}
10220 }
10221 
10222 
10223 static int ap_send_frame_60g(struct sigma_dut *dut,
10224 			     struct sigma_conn *conn,
10225 			     struct sigma_cmd *cmd)
10226 {
10227 	switch (get_driver_type(dut)) {
10228 #ifdef __linux__
10229 	case DRIVER_WIL6210:
10230 		return wil6210_send_frame_60g(dut, conn, cmd);
10231 #endif /* __linux__ */
10232 	default:
10233 		send_resp(dut, conn, SIGMA_ERROR,
10234 			  "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10235 		return 0;
10236 	}
10237 }
10238 
10239 
10240 enum sigma_cmd_result cmd_ap_send_frame(struct sigma_dut *dut,
10241 					struct sigma_conn *conn,
10242 					struct sigma_cmd *cmd)
10243 {
10244 	/* const char *name = get_param(cmd, "NAME"); */
10245 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
10246 	const char *val;
10247 	enum send_frame_type frame;
10248 	enum send_frame_protection protected;
10249 	char buf[100];
10250 
10251 	val = get_param(cmd, "Program");
10252 	if (val) {
10253 		if (strcasecmp(val, "HS2") == 0 ||
10254 		    strcasecmp(val, "HS2-R2") == 0 ||
10255 		    strcasecmp(val, "IOTLP") == 0)
10256 			return ap_send_frame_hs2(dut, conn, cmd);
10257 		if (strcasecmp(val, "VHT") == 0)
10258 			return ap_send_frame_vht(dut, conn, cmd);
10259 		if (strcasecmp(val, "LOC") == 0)
10260 			return ap_send_frame_loc(dut, conn, cmd);
10261 		if (strcasecmp(val, "MBO") == 0)
10262 			return ap_send_frame_mbo(dut, conn, cmd);
10263 		if (strcasecmp(val, "60GHz") == 0)
10264 			return ap_send_frame_60g(dut, conn, cmd);
10265 	}
10266 
10267 	val = get_param(cmd, "PMFFrameType");
10268 	if (val == NULL)
10269 		val = get_param(cmd, "FrameName");
10270 	if (val == NULL)
10271 		val = get_param(cmd, "Type");
10272 	if (val == NULL)
10273 		return -1;
10274 	if (strcasecmp(val, "disassoc") == 0)
10275 		frame = DISASSOC;
10276 	else if (strcasecmp(val, "deauth") == 0)
10277 		frame = DEAUTH;
10278 	else if (strcasecmp(val, "saquery") == 0)
10279 		frame = SAQUERY;
10280 	else {
10281 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10282 			  "PMFFrameType");
10283 		return 0;
10284 	}
10285 
10286 	val = get_param(cmd, "PMFProtected");
10287 	if (val == NULL)
10288 		val = get_param(cmd, "Protected");
10289 	if (val == NULL)
10290 		return -1;
10291 	if (strcasecmp(val, "Correct-key") == 0 ||
10292 	    strcasecmp(val, "CorrectKey") == 0)
10293 		protected = CORRECT_KEY;
10294 	else if (strcasecmp(val, "IncorrectKey") == 0)
10295 		protected = INCORRECT_KEY;
10296 	else if (strcasecmp(val, "Unprotected") == 0)
10297 		protected = UNPROTECTED;
10298 	else {
10299 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10300 			  "PMFProtected");
10301 		return 0;
10302 	}
10303 
10304 	val = get_param(cmd, "stationID");
10305 	if (val == NULL)
10306 		return -1;
10307 
10308 	if (protected == INCORRECT_KEY ||
10309 	    (protected == UNPROTECTED && frame == SAQUERY))
10310 		return ap_inject_frame(dut, conn, frame, protected, val);
10311 
10312 	switch (frame) {
10313 	case DISASSOC:
10314 		snprintf(buf, sizeof(buf), "disassoc %s test=%d",
10315 			 val, protected == CORRECT_KEY);
10316 		break;
10317 	case DEAUTH:
10318 		snprintf(buf, sizeof(buf), "deauth %s test=%d",
10319 			 val, protected == CORRECT_KEY);
10320 		break;
10321 	case SAQUERY:
10322 		snprintf(buf, sizeof(buf), "sa_query %s", val);
10323 		break;
10324 	}
10325 
10326 	if (run_hostapd_cli(dut, buf) != 0)
10327 		return -2;
10328 
10329 	return 1;
10330 }
10331 
10332 
10333 static enum sigma_cmd_result cmd_ap_get_mac_address(struct sigma_dut *dut,
10334 						    struct sigma_conn *conn,
10335 						    struct sigma_cmd *cmd)
10336 {
10337 #if defined( __linux__)
10338 	/* const char *name = get_param(cmd, "NAME"); */
10339 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
10340 	char resp[100];
10341 	unsigned char addr[6];
10342 	char ifname[50];
10343 	struct ifreq ifr;
10344 	int s, wlan_tag = 1;
10345 	const char *val;
10346 
10347 	val = get_param(cmd, "WLAN_TAG");
10348 	if (val) {
10349 		wlan_tag = atoi(val);
10350 		if (wlan_tag < 1 || wlan_tag > 3) {
10351 			/*
10352 			 * The only valid WLAN Tags as of now as per the latest
10353 			 * WFA scripts are 1, 2, and 3.
10354 			 */
10355 			send_resp(dut, conn, SIGMA_ERROR,
10356 				  "errorCode,Unsupported WLAN_TAG");
10357 			return 0;
10358 		}
10359 	}
10360 
10361 	get_if_name(dut, ifname, sizeof(ifname), wlan_tag);
10362 
10363 	s = socket(AF_INET, SOCK_DGRAM, 0);
10364 	if (s < 0)
10365 		return -1;
10366 	memset(&ifr, 0, sizeof(ifr));
10367 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10368 	if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
10369 		perror("ioctl");
10370 		close(s);
10371 		snprintf(resp, sizeof(resp),
10372 			 "errorCode,Could not find interface %s", ifname);
10373 		send_resp(dut, conn, SIGMA_ERROR, resp);
10374 		return 0;
10375 	}
10376 	close(s);
10377 	memcpy(addr, ifr.ifr_hwaddr.sa_data, 6);
10378 
10379 	snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x",
10380 		 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
10381 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
10382 	return 0;
10383 #elif defined( __QNXNTO__)
10384 	char resp[50];
10385 	unsigned char addr[6];
10386 
10387 	if (!dut->main_ifname) {
10388 		send_resp(dut, conn, SIGMA_ERROR, "ifname is null");
10389 		return 0;
10390 	}
10391 
10392 	if (get_hwaddr(get_main_ifname(dut), addr) != 0) {
10393 		send_resp(dut, conn, SIGMA_ERROR,
10394 			  "errorCode,Failed to get address");
10395 		return 0;
10396 	}
10397 	snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x",
10398 		 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
10399 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
10400 	return 0;
10401 #else /* __linux__ */
10402 	send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_get_mac_address not "
10403 		  "yet supported");
10404 	return 0;
10405 #endif /* __linux__ */
10406 }
10407 
10408 
10409 int sta_cfon_get_mac_address(struct sigma_dut *dut, struct sigma_conn *conn,
10410 			     struct sigma_cmd *cmd)
10411 {
10412 	return cmd_ap_get_mac_address(dut, conn, cmd);
10413 }
10414 
10415 
10416 static enum sigma_cmd_result cmd_ap_set_pmf(struct sigma_dut *dut,
10417 					    struct sigma_conn *conn,
10418 					    struct sigma_cmd *cmd)
10419 {
10420 	/*
10421 	 * Ignore the command since the parameters are already handled through
10422 	 * ap_set_security.
10423 	 */
10424 
10425 	return 1;
10426 }
10427 
10428 
10429 static enum sigma_cmd_result cmd_ap_set_hs2(struct sigma_dut *dut,
10430 					    struct sigma_conn *conn,
10431 					    struct sigma_cmd *cmd)
10432 {
10433 	/* const char *name = get_param(cmd, "NAME"); */
10434 	/* const char *ifname = get_param(cmd, "INTERFACE"); */
10435 	const char *val, *dest;
10436 	char *pos, buf[100];
10437 	int i, wlan_tag = 1, res;
10438 
10439 	sigma_dut_print(dut, DUT_MSG_INFO, "ap_set_hs2: Processing the "
10440 			"following parameters");
10441 	for (i = 0; i < cmd->count; i++) {
10442 		sigma_dut_print(dut, DUT_MSG_INFO, "%s %s", cmd->params[i],
10443 				(cmd->values[i] ? cmd->values[i] : "NULL"));
10444 	}
10445 
10446 	val = get_param(cmd, "ICMPv4_ECHO");
10447 	if (val && atoi(val)) {
10448 		snprintf(buf, sizeof(buf), "ebtables -F");
10449 		if (system(buf) != 0) {
10450 			sigma_dut_print(dut, DUT_MSG_ERROR,
10451 					"Failed to set ebtables rules, RULE-12");
10452 		}
10453 		return 1;
10454 	}
10455 
10456 	val = get_param(cmd, "WLAN_TAG");
10457 	if (val) {
10458 		wlan_tag = atoi(val);
10459 		if (wlan_tag != 1 && wlan_tag != 2) {
10460 			send_resp(dut, conn, SIGMA_INVALID,
10461 				  "errorCode,Invalid WLAN_TAG");
10462 			return 0;
10463 		}
10464 	}
10465 
10466 	if (wlan_tag == 2) {
10467 		val = get_param(cmd, "PROXY_ARP");
10468 		if (val)
10469 			dut->ap2_proxy_arp = atoi(val);
10470 
10471 		val = get_param(cmd, "OSU");
10472 		if (val)
10473 			dut->ap2_osu = atoi(val);
10474 		return 1;
10475 	}
10476 
10477 	dest = get_param(cmd, "STA_MAC");
10478 	if (dest) {
10479 		/* This is a special/ugly way of using this command.
10480 		 * If "Dest" MAC is included, assume that this command
10481 		 * is being issued after ap_config_commit for dynamically
10482 		 * setting the QoS Map Set.
10483 		 */
10484 		val = get_param(cmd, "QoS_MAP_SET");
10485 		if (val) {
10486 			dut->ap_qos_map_set = atoi(val);
10487 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
10488 					dut->ap_qos_map_set);
10489 		}
10490 
10491 		if (dut->ap_qos_map_set == 1)
10492 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1);
10493 		else if (dut->ap_qos_map_set == 2)
10494 			run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2);
10495 
10496 		snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest);
10497 		if (run_hostapd_cli(dut, buf) != 0)
10498 			return -1;
10499 	}
10500 
10501 	val = get_param(cmd, "DGAF_DISABLE");
10502 	if (val)
10503 		dut->ap_dgaf_disable = atoi(val);
10504 
10505 	dut->ap_interworking = 1;
10506 
10507 	val = get_param(cmd, "INTERWORKING");
10508 	if (val == NULL)
10509 		val = get_param(cmd, "INTERNETWORKING");
10510 	if (val != NULL && atoi(val) == 0) {
10511 		dut->ap_interworking = 0;
10512 		dut->ap_hs2 = 0;
10513 		return 1;
10514 	}
10515 
10516 	val = get_param(cmd, "ACCS_NET_TYPE");
10517 	if (val) {
10518 		if (strcasecmp(val, "Chargeable_Public_Network") == 0 ||
10519 		    strcasecmp(val, "Chargable_Public_Network") == 0 ||
10520 		    strcasecmp(val, "Chargable Public Network") == 0)
10521 			dut->ap_access_net_type = 2;
10522 		else
10523 			dut->ap_access_net_type = atoi(val);
10524 	}
10525 
10526 	val = get_param(cmd, "INTERNET");
10527 	if (val)
10528 		dut->ap_internet = atoi(val);
10529 
10530 	val = get_param(cmd, "VENUE_GRP");
10531 	if (val) {
10532 		if (strcasecmp(val, "Business") == 0)
10533 			dut->ap_venue_group = 2;
10534 		else
10535 			dut->ap_venue_group = atoi(val);
10536 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d",
10537 				dut->ap_venue_name);
10538 	}
10539 
10540 	val = get_param(cmd, "VENUE_TYPE");
10541 	if (val) {
10542 		if (strcasecmp(val, "R&D") == 0)
10543 			dut->ap_venue_type = 8;
10544 		else
10545 			dut->ap_venue_type = atoi(val);
10546 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_type %d",
10547 				dut->ap_venue_type);
10548 	}
10549 
10550 	val = get_param(cmd, "HESSID");
10551 	if (val) {
10552 		if (strlen(val) >= sizeof(dut->ap_hessid)) {
10553 			send_resp(dut, conn, SIGMA_ERROR,
10554 				  "errorCode,Invalid HESSID");
10555 			return 0;
10556 		}
10557 		snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), "%s", val);
10558 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_hessid %s",
10559 				dut->ap_hessid);
10560 	}
10561 
10562 	val = get_param(cmd, "ROAMING_CONS");
10563 	if (val) {
10564 		if (strlen(val) >= sizeof(dut->ap_roaming_cons)) {
10565 			send_resp(dut, conn, SIGMA_ERROR,
10566 				  "errorCode,Invalid ROAMING_CONS");
10567 			return 0;
10568 		}
10569 		if (strcasecmp(val, "Disabled") == 0) {
10570 			dut->ap_roaming_cons[0] = '\0';
10571 		} else {
10572 			snprintf(dut->ap_roaming_cons,
10573 				 sizeof(dut->ap_roaming_cons), "%s", val);
10574 		}
10575 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_roaming_cons %s",
10576 				dut->ap_roaming_cons);
10577 	}
10578 
10579 	val = get_param(cmd, "ANQP");
10580 	if (val)
10581 		dut->ap_anqpserver_on = atoi(val);
10582 
10583 	val = get_param(cmd, "NAI_REALM_LIST");
10584 	if (val) {
10585 		dut->ap_nai_realm_list = atoi(val);
10586 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_nai_realm_list %d",
10587 				dut->ap_nai_realm_list);
10588 	}
10589 
10590 	val = get_param(cmd, "3GPP_INFO");
10591 	if (val) {
10592 		/* What kind of encoding format is used?! */
10593 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,3GPP_INFO "
10594 			  "not yet supported (contents not fully defined)");
10595 		return 0;
10596 	}
10597 
10598 	val = get_param(cmd, "DOMAIN_LIST");
10599 	if (val) {
10600 		if (strlen(val) >= sizeof(dut->ap_domain_name_list)) {
10601 			send_resp(dut, conn, SIGMA_ERROR, "errorCode,Too long "
10602 				  "DOMAIN_LIST");
10603 			return 0;
10604 		}
10605 		snprintf(dut->ap_domain_name_list,
10606 			 sizeof(dut->ap_domain_name_list), "%s", val);
10607 		pos = dut->ap_domain_name_list;
10608 		while (*pos) {
10609 			if (*pos == ';')
10610 				*pos = ',';
10611 			pos++;
10612 		}
10613 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_domain_name_list %s",
10614 				dut->ap_domain_name_list);
10615 	}
10616 
10617 	val = get_param(cmd, "OPER_NAME");
10618 	if (val) {
10619 		dut->ap_oper_name = atoi(val);
10620 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_name %d",
10621 				dut->ap_oper_name);
10622 	}
10623 
10624 	val = get_param(cmd, "VENUE_NAME");
10625 	if (val) {
10626 		dut->ap_venue_name = atoi(val);
10627 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d",
10628 				dut->ap_venue_name);
10629 	}
10630 
10631 	val = get_param(cmd, "GAS_CB_DELAY");
10632 	if (val) {
10633 		dut->ap_gas_cb_delay = atoi(val);
10634 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_gas_cb_delay %d",
10635 				dut->ap_gas_cb_delay);
10636 	}
10637 
10638 	val = get_param(cmd, "MIH");
10639 	if (val && atoi(val) > 0) {
10640 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,MIH not "
10641 			  "supported");
10642 		return 0;
10643 	}
10644 
10645 	val = get_param(cmd, "L2_TRAFFIC_INSPECT");
10646 	if (val) {
10647 		dut->ap_l2tif = atoi(val);
10648 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_l2tif %d",
10649 				dut->ap_l2tif);
10650 	}
10651 
10652 	val = get_param(cmd, "BCST_UNCST");
10653 	if (val) {
10654 		send_resp(dut, conn, SIGMA_ERROR,
10655 			  "errorCode,BCST_UNCST not yet supported");
10656 		return 0;
10657 	}
10658 
10659 	val = get_param(cmd, "PLMN_MCC");
10660 	if (val) {
10661 		char mcc[100], *start, *end;
10662 		int i = 0;
10663 		if (strlen(val) >= sizeof(mcc)) {
10664 			send_resp(dut, conn, SIGMA_ERROR,
10665 				  "errorCode,PLMN_MCC too long");
10666 			return 0;
10667 		}
10668 		strlcpy(mcc, val, sizeof(mcc));
10669 		start = mcc;
10670 		while ((end = strchr(start, ';'))) {
10671 			/* process all except the last */
10672 			*end = '\0';
10673 			if (strlen(start) != 3) {
10674 				send_resp(dut, conn, SIGMA_ERROR,
10675 					  "errorCode,Invalid PLMN_MCC");
10676 				return 0;
10677 			}
10678 			res = snprintf(dut->ap_plmn_mcc[i],
10679 				       sizeof(dut->ap_plmn_mcc[i]), "%s",
10680 				       start);
10681 			if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i]))
10682 				return ERROR_SEND_STATUS;
10683 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s",
10684 					dut->ap_plmn_mcc[i]);
10685 			i++;
10686 			start = end + 1;
10687 			*end = ';';
10688 		}
10689 		if (strlen(start) != 3) {
10690 			send_resp(dut, conn, SIGMA_ERROR,
10691 				  "errorCode,Invalid PLMN_MCC");
10692 			return 0;
10693 		}
10694 		/* process last or only one */
10695 		res = snprintf(dut->ap_plmn_mcc[i],
10696 			       sizeof(dut->ap_plmn_mcc[i]), "%s", start);
10697 		if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i]))
10698 			return ERROR_SEND_STATUS;
10699 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s",
10700 			dut->ap_plmn_mcc[i]);
10701 	}
10702 
10703 	val = get_param(cmd, "PLMN_MNC");
10704 	if (val) {
10705 		char mnc[100], *start, *end;
10706 		int i = 0;
10707 		if (strlen(val) >= sizeof(mnc)) {
10708 			send_resp(dut, conn, SIGMA_ERROR,
10709 				  "errorCode,PLMN_MNC too long");
10710 			return 0;
10711 		}
10712 		strlcpy(mnc, val, sizeof(mnc));
10713 		start = mnc;
10714 		while ((end = strchr(start, ';'))) {
10715 			*end = '\0';
10716 			if (strlen(start) != 2 && strlen(start) != 3) {
10717 				send_resp(dut, conn, SIGMA_ERROR,
10718 					"errorCode,Invalid PLMN_MNC");
10719 				return 0;
10720 			}
10721 			res = snprintf(dut->ap_plmn_mnc[i],
10722 				       sizeof(dut->ap_plmn_mnc[i]), "%s",
10723 				       start);
10724 			if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i]))
10725 				return ERROR_SEND_STATUS;
10726 			sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s",
10727 				dut->ap_plmn_mnc[i]);
10728 			i++;
10729 			start = end + 1;
10730 			*end = ';';
10731 		}
10732 		if (strlen(start) != 2 && strlen(start) != 3) {
10733 			send_resp(dut, conn, SIGMA_ERROR,
10734 				  "errorCode,Invalid PLMN_MNC");
10735 			return 0;
10736 		}
10737 		res = snprintf(dut->ap_plmn_mnc[i],
10738 			       sizeof(dut->ap_plmn_mnc[i]), "%s", start);
10739 		if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i]))
10740 			return ERROR_SEND_STATUS;
10741 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s",
10742 			dut->ap_plmn_mnc[i]);
10743 	}
10744 
10745 	val = get_param(cmd, "PROXY_ARP");
10746 	if (val) {
10747 		dut->ap_proxy_arp = atoi(val);
10748 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_proxy_arp %d",
10749 				dut->ap_proxy_arp);
10750 	}
10751 
10752 	val = get_param(cmd, "WAN_METRICS");
10753 	if (val) {
10754 		dut->ap_wan_metrics = atoi(val);
10755 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_wan_metrics %d",
10756 				dut->ap_wan_metrics);
10757 	}
10758 
10759 	val = get_param(cmd, "CONN_CAP");
10760 	if (val) {
10761 		dut->ap_conn_capab = atoi(val);
10762 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_conn_capab %d",
10763 				dut->ap_conn_capab);
10764 	}
10765 
10766 	val = get_param(cmd, "IP_ADD_TYPE_AVAIL");
10767 	if (val) {
10768 		dut->ap_ip_addr_type_avail = atoi(val);
10769 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_ip_addr_type_avail %d",
10770 				dut->ap_ip_addr_type_avail);
10771 	}
10772 
10773 	val = get_param(cmd, "NET_AUTH_TYPE");
10774 	if (val) {
10775 		dut->ap_net_auth_type = atoi(val);
10776 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_net_auth_type %d",
10777 				dut->ap_net_auth_type);
10778 	}
10779 
10780 	val = get_param(cmd, "OP_CLASS");
10781 	if (val == NULL)
10782 		val = get_param(cmd, "OPER_CLASS");
10783 	if (val) {
10784 		dut->ap_oper_class = atoi(val);
10785 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_class %d",
10786 				dut->ap_oper_class);
10787 	}
10788 
10789 	val = get_param(cmd, "OSU_PROVIDER_LIST");
10790 	if (val) {
10791 		dut->ap_osu_provider_list = atoi(val);
10792 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_osu_provider_list %d",
10793 				dut->ap_osu_provider_list);
10794 	}
10795 
10796 	val = get_param(cmd, "OSU_PROVIDER_NAI_LIST");
10797 	if (val) {
10798 		dut->ap_osu_provider_nai_list = atoi(val);
10799 		sigma_dut_print(dut, DUT_MSG_INFO,
10800 				"ap_osu_provider_nai_list %d",
10801 				dut->ap_osu_provider_nai_list);
10802 	}
10803 
10804 	val = get_param(cmd, "OSU_SERVER_URI");
10805 	if (val) {
10806 		i = 0;
10807 		do {
10808 			int len;
10809 			const char *uri = val;
10810 			val = strchr(val, ' ');
10811 			len = val ? (val++ - uri) : (int) strlen(uri);
10812 			if (len > 0 && len < 256) {
10813 				memcpy(dut->ap_osu_server_uri[i], uri, len);
10814 				dut->ap_osu_server_uri[i][len] = '\0';
10815 				sigma_dut_print(dut, DUT_MSG_INFO,
10816 						"ap_osu_server_uri[%d] %s", i,
10817 						dut->ap_osu_server_uri[i]);
10818 			}
10819 		} while (val && ++i < 10);
10820 	}
10821 
10822 	val = get_param(cmd, "OSU_METHOD");
10823 	if (val) {
10824 		i = 0;
10825 		do {
10826 			int len;
10827 			const char *method = val;
10828 			val = strchr(val, ' ');
10829 			len = val ? (val++ - method) : (int) strlen(method);
10830 			if (len > 0) {
10831 				if (strncasecmp(method, "SOAP", len) == 0)
10832 					dut->ap_osu_method[i] = 1;
10833 				else if (strncasecmp(method, "OMADM", len) == 0)
10834 					dut->ap_osu_method[i] = 0;
10835 				else
10836 					return -2;
10837 			}
10838 		} while (val && ++i < 10);
10839 	}
10840 
10841 	val = get_param(cmd, "OSU_SSID");
10842 	if (val) {
10843 		if (strlen(val) > 0 && strlen(val) <= 32) {
10844 			strlcpy(dut->ap_osu_ssid, val,
10845 				sizeof(dut->ap_osu_ssid));
10846 			sigma_dut_print(dut, DUT_MSG_INFO,
10847 					"ap_osu_ssid %s",
10848 					dut->ap_osu_ssid);
10849 		}
10850 	}
10851 
10852 	val = get_param(cmd, "OSU_ICON_TAG");
10853 	if (val)
10854 		dut->ap_osu_icon_tag = atoi(val);
10855 
10856 	val = get_param(cmd, "QoS_MAP_SET");
10857 	if (val) {
10858 		dut->ap_qos_map_set = atoi(val);
10859 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
10860 				dut->ap_qos_map_set);
10861 	}
10862 
10863 	val = get_param(cmd, "BSS_LOAD");
10864 	if (val) {
10865 		dut->ap_bss_load = atoi(val);
10866 		sigma_dut_print(dut, DUT_MSG_INFO, "ap_bss_load %d",
10867 				dut->ap_bss_load);
10868 	}
10869 
10870 	val = get_param(cmd, "Venue_URL");
10871 	if (val)
10872 		dut->ap_venue_url = atoi(val);
10873 
10874 	val = get_param(cmd, "Advice_of_Charge");
10875 	if (val)
10876 		dut->ap_advice_of_charge = atoi(val);
10877 
10878 	val = get_param(cmd, "Operator_Icon_Metadata");
10879 	if (val)
10880 		dut->ap_oper_icon_metadata = atoi(val);
10881 
10882 	val = get_param(cmd, "TnC_File_Name");
10883 	if (val)
10884 		dut->ap_tnc_file_name = atoi(val);
10885 
10886 	val = get_param(cmd, "TnC_File_Time_Stamp");
10887 	if (val)
10888 		dut->ap_tnc_time_stamp = strtol(val, NULL, 10);
10889 
10890 	return 1;
10891 }
10892 
10893 
10894 void nfc_status(struct sigma_dut *dut, const char *state, const char *oper)
10895 {
10896 	char buf[100];
10897 
10898 	if (!file_exists("nfc-status"))
10899 		return;
10900 
10901 	snprintf(buf, sizeof(buf), "./nfc-status %s %s", state, oper);
10902 	run_system(dut, buf);
10903 }
10904 
10905 
10906 static int run_nfc_command(struct sigma_dut *dut, const char *cmd,
10907 			   const char *info)
10908 {
10909 	int res;
10910 
10911 	printf("\n\n\n=====[ NFC operation ]=========================\n\n");
10912 	printf("%s\n\n", info);
10913 
10914 	nfc_status(dut, "START", info);
10915 	res = run_system(dut, cmd);
10916 	nfc_status(dut, res ? "FAIL" : "SUCCESS", info);
10917 	if (res) {
10918 		sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s': %d",
10919 				cmd, res);
10920 		return res;
10921 	}
10922 
10923 	return 0;
10924 }
10925 
10926 
10927 static int ap_nfc_write_config_token(struct sigma_dut *dut,
10928 				     struct sigma_conn *conn,
10929 				     struct sigma_cmd *cmd)
10930 {
10931 	int res;
10932 	char buf[300];
10933 
10934 	run_system(dut, "killall wps-ap-nfc.py");
10935 	unlink("nfc-success");
10936 	snprintf(buf, sizeof(buf),
10937 		 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-config",
10938 		 dut->summary_log ? "--summary " : "",
10939 		 dut->summary_log ? dut->summary_log : "");
10940 	res = run_nfc_command(dut, buf,
10941 			      "Touch NFC Tag to write WPS configuration token");
10942 	if (res || !file_exists("nfc-success")) {
10943 		send_resp(dut, conn, SIGMA_ERROR,
10944 			  "ErrorCode,Failed to write tag");
10945 		return 0;
10946 	}
10947 
10948 	return 1;
10949 }
10950 
10951 
10952 static int ap_nfc_wps_read_passwd(struct sigma_dut *dut,
10953 				  struct sigma_conn *conn,
10954 				  struct sigma_cmd *cmd)
10955 {
10956 	int res;
10957 	char buf[300];
10958 
10959 	run_system(dut, "killall wps-ap-nfc.py");
10960 
10961 	unlink("nfc-success");
10962 	snprintf(buf, sizeof(buf),
10963 		 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success",
10964 		 dut->summary_log ? "--summary " : "",
10965 		 dut->summary_log ? dut->summary_log : "");
10966 	res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
10967 	if (res || !file_exists("nfc-success")) {
10968 		send_resp(dut, conn, SIGMA_ERROR,
10969 			  "ErrorCode,Failed to read tag");
10970 		return 0;
10971 	}
10972 
10973 	return 1;
10974 }
10975 
10976 
10977 static int ap_nfc_write_password_token(struct sigma_dut *dut,
10978 				       struct sigma_conn *conn,
10979 				       struct sigma_cmd *cmd)
10980 {
10981 	int res;
10982 	char buf[300];
10983 
10984 	run_system(dut, "killall wps-ap-nfc.py");
10985 	unlink("nfc-success");
10986 	snprintf(buf, sizeof(buf),
10987 		 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-password",
10988 		 dut->summary_log ? "--summary " : "",
10989 		 dut->summary_log ? dut->summary_log : "");
10990 	res = run_nfc_command(dut, buf,
10991 			      "Touch NFC Tag to write WPS password token");
10992 	if (res || !file_exists("nfc-success")) {
10993 		send_resp(dut, conn, SIGMA_ERROR,
10994 			  "ErrorCode,Failed to write tag");
10995 		return 0;
10996 	}
10997 
10998 	if (run_hostapd_cli(dut, "wps_nfc_token enable") != 0) {
10999 		send_resp(dut, conn, SIGMA_ERROR,
11000 			  "ErrorCode,Failed to enable NFC password token");
11001 		return 0;
11002 	}
11003 
11004 	return 1;
11005 }
11006 
11007 
11008 static int ap_nfc_wps_connection_handover(struct sigma_dut *dut,
11009 					  struct sigma_conn *conn,
11010 					  struct sigma_cmd *cmd)
11011 {
11012 	int res;
11013 	char buf[300];
11014 
11015 	run_system(dut, "killall wps-ap-nfc.py");
11016 	unlink("nfc-success");
11017 	snprintf(buf, sizeof(buf),
11018 		 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success",
11019 		 dut->summary_log ? "--summary " : "",
11020 		 dut->summary_log ? dut->summary_log : "");
11021 	res = run_nfc_command(dut, buf,
11022 			      "Touch NFC Device to respond to WPS connection handover");
11023 	if (res) {
11024 		send_resp(dut, conn, SIGMA_ERROR,
11025 			  "ErrorCode,Failed to enable NFC for connection "
11026 			  "handover");
11027 		return 0;
11028 	}
11029 	if (!file_exists("nfc-success")) {
11030 		send_resp(dut, conn, SIGMA_ERROR,
11031 			  "ErrorCode,Failed to complete NFC connection handover");
11032 		return 0;
11033 	}
11034 
11035 	return 1;
11036 }
11037 
11038 
11039 static enum sigma_cmd_result cmd_ap_nfc_action(struct sigma_dut *dut,
11040 					       struct sigma_conn *conn,
11041 					       struct sigma_cmd *cmd)
11042 {
11043 	/* const char *name = get_param(cmd, "Name"); */
11044 	/* const char *intf = get_param(cmd, "Interface"); */
11045 	const char *oper = get_param(cmd, "Operation");
11046 
11047 	if (oper == NULL)
11048 		return -1;
11049 
11050 	if (strcasecmp(oper, "WRITE_CONFIG") == 0)
11051 		return ap_nfc_write_config_token(dut, conn, cmd);
11052 	if (strcasecmp(oper, "WRITE_PASSWD") == 0)
11053 		return ap_nfc_write_password_token(dut, conn, cmd);
11054 	if (strcasecmp(oper, "WPS_READ_PASSWD") == 0)
11055 		return ap_nfc_wps_read_passwd(dut, conn, cmd);
11056 	if (strcasecmp(oper, "WPS_CONN_HNDOVR") == 0)
11057 		return ap_nfc_wps_connection_handover(dut, conn, cmd);
11058 
11059 	send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported operation");
11060 	return 0;
11061 }
11062 
11063 
11064 static enum sigma_cmd_result cmd_ap_wps_read_pin(struct sigma_dut *dut,
11065 						 struct sigma_conn *conn,
11066 						 struct sigma_cmd *cmd)
11067 {
11068 	char *pin = "12345670"; /* TODO: use random PIN */
11069 	char resp[100];
11070 
11071 	snprintf(resp, sizeof(resp), "PIN,%s", pin);
11072 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
11073 
11074 	return 0;
11075 }
11076 
11077 
11078 static enum sigma_cmd_result cmd_ap_wps_enter_pin(struct sigma_dut *dut,
11079 						  struct sigma_conn *conn,
11080 						  struct sigma_cmd *cmd)
11081 {
11082 	const char *pin = get_param(cmd, "PIN");
11083 	char wps_pin[11];
11084 
11085 	if (!pin)
11086 		return -1;
11087 
11088 	sigma_dut_print(dut, DUT_MSG_DEBUG,
11089 			"Authorize a client to join with WPS PIN %s", pin);
11090 
11091 	strlcpy(wps_pin, pin, sizeof(wps_pin));
11092 	/* we need to tolerate extra '-' characters entered */
11093 	str_remove_chars(wps_pin, '-');
11094 	strlcpy(dut->wps_pin, wps_pin, sizeof(dut->wps_pin));
11095 	dut->wps_method = WFA_CS_WPS_PIN_KEYPAD;
11096 
11097 	return 1;
11098 }
11099 
11100 
11101 static enum sigma_cmd_result cmd_ap_wps_set_pbc(struct sigma_dut *dut,
11102 						struct sigma_conn *conn,
11103 						struct sigma_cmd *cmd)
11104 {
11105 	sigma_dut_print(dut, DUT_MSG_DEBUG,
11106 			"Selecting the push button configuration method");
11107 
11108 	dut->wps_method = WFA_CS_WPS_PBC;
11109 
11110 	return 1;
11111 }
11112 
11113 
11114 int ap_wps_registration(struct sigma_dut *dut, struct sigma_conn *conn,
11115 			struct sigma_cmd *cmd)
11116 {
11117 	char buf[100], resp[256];
11118 	const char *intf = get_param(cmd, "interface");
11119 	const char *config_method = get_param(cmd, "WPSConfigMethod");
11120 
11121 	if (config_method && strcasecmp(config_method, "PBC") == 0)
11122 		dut->wps_method = WFA_CS_WPS_PBC;
11123 
11124 	if (!intf)
11125 		intf = get_main_ifname(dut);
11126 
11127 	if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
11128 		send_resp(dut, conn, SIGMA_ERROR,
11129 			  "ErrorCode,WPS parameters not yet set");
11130 		return STATUS_SENT;
11131 	}
11132 
11133 	if (dut->wps_method == WFA_CS_WPS_PBC)
11134 		snprintf(buf, sizeof(buf), "WPS_PBC");
11135 	else /* WFA_CS_WPS_PIN_KEYPAD */
11136 		snprintf(buf, sizeof(buf), "WPS_PIN any %s", dut->wps_pin);
11137 
11138 	/* Run WPS command */
11139 	if (hapd_command(intf, buf) < 0) {
11140 		/* command fails immediately if overlapped session detected */
11141 		snprintf(resp, sizeof(resp), "WpsState,OverlapSession");
11142 		send_resp(dut, conn, SIGMA_COMPLETE, resp);
11143 		return STATUS_SENT;
11144 	}
11145 
11146 	/* In AP mode return immediately and do not wait for WPS registration */
11147 	return SUCCESS_SEND_STATUS;
11148 }
11149 
11150 
11151 static enum sigma_cmd_result cmd_ap_get_parameter(struct sigma_dut *dut,
11152 						  struct sigma_conn *conn,
11153 						  struct sigma_cmd *cmd)
11154 {
11155 	char value[256], resp[512];
11156 	const char *param = get_param(cmd, "parameter");
11157 	const char *ifname = get_param(cmd, "Interface");
11158 	const char *var;
11159 
11160 	if (!ifname)
11161 		ifname = get_main_ifname(dut);
11162 
11163 	if (!param) {
11164 		send_resp(dut, conn, SIGMA_ERROR,
11165 			  "ErrorCode,Parameter not specified");
11166 		return 0;
11167 	}
11168 
11169 	if (strcasecmp(param, "SSID") == 0) {
11170 		if (get_hapd_config(ifname, "ssid", value, sizeof(value))) {
11171 			sigma_dut_print(dut, DUT_MSG_ERROR,
11172 					"Failed to get SSID");
11173 			return -2;
11174 		}
11175 		snprintf(resp, sizeof(resp), "SSID,%s", value);
11176 	} else if (strcasecmp(param, "PSK") == 0) {
11177 		if (get_hapd_config(ifname, "passphrase", value,
11178 				    sizeof(value))) {
11179 			sigma_dut_print(dut, DUT_MSG_ERROR,
11180 					"Failed to get PSK");
11181 			return -2;
11182 		}
11183 		snprintf(resp, sizeof(resp), "PSK,%s", value);
11184 	} else if (strcasecmp(param, "PMK") == 0) {
11185 		var = get_param(cmd, "STA_MAC_Address");
11186 		if (!var)
11187 			return INVALID_SEND_STATUS;
11188 		snprintf(resp, sizeof(resp), "GET_PMK %s", var);
11189 		if (hapd_command_resp(ifname, resp, &resp[4],
11190 				      sizeof(resp) - 4) < 0) {
11191 			send_resp(dut, conn, SIGMA_ERROR,
11192 				  "ErrorCode,GET_PMK failed");
11193 			return STATUS_SENT_ERROR;
11194 		}
11195 		memcpy(resp, "PMK,", 4);
11196 	} else {
11197 		send_resp(dut, conn, SIGMA_ERROR,
11198 			  "ErrorCode,Unsupported parameter");
11199 		return 0;
11200 	}
11201 
11202 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
11203 	return 0;
11204 }
11205 
11206 
11207 static int ath_vht_op_mode_notif(struct sigma_dut *dut, const char *ifname,
11208 				 const char *val)
11209 {
11210 	char *token, *result;
11211 	int nss = 0, chwidth = 0;
11212 	char *saveptr;
11213 
11214 	/*
11215 	 * The following commands should be invoked to generate
11216 	 * VHT op mode notification
11217 	 */
11218 
11219 	/* Extract the NSS info */
11220 	token = strdup(val);
11221 	if (!token)
11222 		return -1;
11223 	result = strtok_r(token, ";", &saveptr);
11224 	if (result) {
11225 		int count = atoi(result);
11226 
11227 		/* We do not support NSS > 3 */
11228 		if (count < 0 || count > 3) {
11229 			free(token);
11230 			return -1;
11231 		}
11232 
11233 		/* Convert nss to chainmask */
11234 		while (count--)
11235 			nss = (nss << 1) | 1;
11236 
11237 		run_iwpriv(dut, ifname, "rxchainmask %d", nss);
11238 	}
11239 
11240 	/* Extract the Channel width info */
11241 	result = strtok_r(NULL, ";", &saveptr);
11242 	if (result) {
11243 		switch (atoi(result)) {
11244 		case 20:
11245 			chwidth = 0;
11246 			break;
11247 		case 40:
11248 			chwidth = 1;
11249 			break;
11250 		case 80:
11251 			chwidth = 2;
11252 			break;
11253 		case 160:
11254 			chwidth = 3;
11255 			break;
11256 		default:
11257 			chwidth = 2;
11258 			break;
11259 		}
11260 		run_iwpriv(dut, ifname, "chwidth %d", chwidth);
11261 	}
11262 
11263 	/* Send the opmode notification */
11264 	run_iwpriv(dut, ifname, "opmode_notify 1");
11265 	free(token);
11266 
11267 	return 0;
11268 }
11269 
11270 
11271 static int ath_vht_nss_mcs(struct sigma_dut *dut, const char *ifname,
11272 			   const char *val)
11273 {
11274 	/* String (nss_operating_mode; mcs_operating_mode) */
11275 	int nss, mcs;
11276 	char *token, *result;
11277 	char *saveptr;
11278 
11279 	token = strdup(val);
11280 	if (!token)
11281 		return -1;
11282 	result = strtok_r(token, ";", &saveptr);
11283 	if (!result) {
11284 		sigma_dut_print(dut, DUT_MSG_ERROR,
11285 				"VHT NSS not specified");
11286 		goto end;
11287 	}
11288 	if (strcasecmp(result, "def") != 0) {
11289 		nss = atoi(result);
11290 
11291 		if (nss == 4)
11292 			ath_disable_txbf(dut, ifname);
11293 
11294 		run_iwpriv(dut, ifname, "nss %d", nss);
11295 	} else {
11296 		if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1)
11297 			run_iwpriv(dut, ifname, "nss 1");
11298 		if (dut->device_type == AP_testbed &&
11299 		    dut->program == PROGRAM_HE) {
11300 			nss = dut->ap_tx_streams;
11301 			run_iwpriv(dut, ifname, "nss %d", nss);
11302 		}
11303 	}
11304 
11305 	result = strtok_r(NULL, ";", &saveptr);
11306 	if (!result) {
11307 		sigma_dut_print(dut, DUT_MSG_ERROR,
11308 				"VHT MCS not specified");
11309 		goto end;
11310 	}
11311 	if (strcasecmp(result, "def") == 0) {
11312 		if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1)
11313 			run_iwpriv(dut, ifname, "vhtmcs 7");
11314 		else
11315 			run_iwpriv(dut, ifname, "set11NRates 0");
11316 		if (dut->device_type == AP_testbed &&
11317 		    dut->program == PROGRAM_HE)
11318 			run_iwpriv(dut, ifname, "he_mcs 7");
11319 	} else {
11320 		mcs = atoi(result);
11321 		if (dut->program == PROGRAM_HE)
11322 			run_iwpriv(dut, ifname, "he_mcs %d", mcs);
11323 		else
11324 			run_iwpriv(dut, ifname, "vhtmcs %d", mcs);
11325 	}
11326 
11327 end:
11328 	free(token);
11329 	return 0;
11330 }
11331 
11332 
11333 static int ath_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
11334 			      const char *val)
11335 {
11336 	char *token, *result;
11337 	int channel = 36;
11338 	int chwidth = 80;
11339 	char *saveptr;
11340 
11341 	/* Extract the channel info */
11342 	token = strdup(val);
11343 	if (!token)
11344 		return -1;
11345 	result = strtok_r(token, ";", &saveptr);
11346 	if (result)
11347 		channel = atoi(result);
11348 
11349 	/* Extract the channel width info */
11350 	result = strtok_r(NULL, ";", &saveptr);
11351 	if (result)
11352 		chwidth = atoi(result);
11353 
11354 	/* Issue the channel switch command */
11355 	run_iwpriv(dut, ifname, "doth_ch_chwidth %d 10 %d", channel, chwidth);
11356 
11357 	free(token);
11358 	return 0;
11359 }
11360 
11361 
11362 static int ath_ndpa_stainfo_mac(struct sigma_dut *dut, const char *ifname,
11363 				const char *val)
11364 {
11365 	char buf[80];
11366 	unsigned char mac_addr[6];
11367 
11368 	if (parse_mac_address(dut, val, mac_addr) < 0)
11369 		return -1;
11370 
11371 	snprintf(buf, sizeof(buf),
11372 		 "wifitool %s beeliner_fw_test 92 0x%02x%02x%02x%02x",
11373 		 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3]);
11374 	run_system(dut, buf);
11375 
11376 	snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 93 0x%02x%02x",
11377 		 ifname, mac_addr[4], mac_addr[5]);
11378 	run_system(dut, buf);
11379 
11380 	snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 94 1", ifname);
11381 	run_system(dut, buf);
11382 
11383 	return 0;
11384 }
11385 
11386 
11387 void novap_reset(struct sigma_dut *dut, const char *ifname, int reset)
11388 {
11389 	run_iwpriv(dut, ifname, "novap_reset %d", reset);
11390 }
11391 
11392 
11393 static struct mbo_pref_ap * mbo_find_nebor_ap_entry(struct sigma_dut *dut,
11394 						    const uint8_t *mac_addr)
11395 {
11396 	int i;
11397 
11398 	for (i = 0; i < dut->mbo_pref_ap_cnt; i++) {
11399 		if (memcmp(mac_addr, dut->mbo_pref_aps[i].mac_addr,
11400 			   ETH_ALEN) == 0)
11401 			return &dut->mbo_pref_aps[i];
11402 	}
11403 	return NULL;
11404 }
11405 
11406 
11407 static void mbo_add_nebor_entry(struct sigma_dut *dut, const uint8_t *mac_addr,
11408 				int ap_ne_class, int ap_ne_op_ch,
11409 				int ap_ne_pref)
11410 {
11411 	struct mbo_pref_ap *entry;
11412 	uint8_t self_mac[ETH_ALEN];
11413 	char ifname[50];
11414 
11415 	get_if_name(dut, ifname, sizeof(ifname), 1);
11416 	get_hwaddr(ifname, self_mac);
11417 
11418 	if (memcmp(mac_addr, self_mac, ETH_ALEN) == 0)
11419 		entry = &dut->mbo_self_ap_tuple;
11420 	else
11421 		entry = mbo_find_nebor_ap_entry(dut, mac_addr);
11422 
11423 	if (!entry) {
11424 		if (dut->mbo_pref_ap_cnt >= MBO_MAX_PREF_BSSIDS) {
11425 			sigma_dut_print(dut, DUT_MSG_ERROR,
11426 					"Nebor AP List is full. Not adding");
11427 			return;
11428 		}
11429 		entry = &dut->mbo_pref_aps[dut->mbo_pref_ap_cnt];
11430 		dut->mbo_pref_ap_cnt++;
11431 		memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
11432 		entry->ap_ne_class = -1;
11433 		entry->ap_ne_op_ch = -1;
11434 		entry->ap_ne_pref = -1;
11435 	}
11436 	if (ap_ne_class != -1)
11437 		entry->ap_ne_class = ap_ne_class;
11438 	if (ap_ne_op_ch != -1)
11439 		entry->ap_ne_op_ch = ap_ne_op_ch;
11440 	if (ap_ne_pref != -1)
11441 		entry->ap_ne_pref = ap_ne_pref;
11442 }
11443 
11444 
11445 static int ath_set_nebor_bssid(struct sigma_dut *dut, const char *ifname,
11446 			       struct sigma_cmd *cmd)
11447 {
11448 	unsigned char mac_addr[ETH_ALEN];
11449 	const char *val;
11450 	/*
11451 	 * -1 is invalid value for the following
11452 	 *  to differentiate between unset and set values
11453 	 *  -1 => implies not set by CAPI
11454 	 */
11455 	int ap_ne_class = -1, ap_ne_op_ch = -1, ap_ne_pref = -1;
11456 	int list_offset = dut->mbo_pref_ap_cnt;
11457 
11458 	if (list_offset >= MBO_MAX_PREF_BSSIDS) {
11459 		sigma_dut_print(dut, DUT_MSG_ERROR,
11460 				"AP Pref Entry list is full");
11461 		return -1;
11462 	}
11463 
11464 	val = get_param(cmd, "Nebor_Op_Class");
11465 	if (val)
11466 		ap_ne_class = atoi(val);
11467 
11468 	val = get_param(cmd, "Nebor_Op_Ch");
11469 	if (val)
11470 		ap_ne_op_ch = atoi(val);
11471 
11472 	val = get_param(cmd, "Nebor_Pref");
11473 	if (val)
11474 		ap_ne_pref = atoi(val);
11475 
11476 	val = get_param(cmd, "Nebor_BSSID");
11477 	if (!val || parse_mac_address(dut, val, mac_addr) < 0)
11478 		return -1;
11479 
11480 	mbo_add_nebor_entry(dut, mac_addr, ap_ne_class, ap_ne_op_ch,
11481 			    ap_ne_pref);
11482 	apply_mbo_pref_ap_list(dut);
11483 	return 0;
11484 }
11485 
11486 
11487 static enum sigma_cmd_result he_ltf(struct sigma_dut *dut,
11488 				    struct sigma_conn *conn,
11489 				    const char *ifname, const char *val)
11490 {
11491 	const char *var;
11492 
11493 	if (dut->ap_he_ulofdma == VALUE_ENABLED)
11494 		var = "he_ul_ltf";
11495 	else
11496 		var = "he_ltf";
11497 
11498 	if (strcmp(val, "6.4") == 0) {
11499 		run_iwpriv(dut, ifname, "%s 2", var);
11500 	} else if (strcmp(val, "12.8") == 0) {
11501 		run_iwpriv(dut, ifname, "%s 3", var);
11502 	} else if (strcmp(val, "3.2") == 0) {
11503 		run_iwpriv(dut, ifname, "%s 1", var);
11504 	} else {
11505 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported LTF");
11506 		return STATUS_SENT_ERROR;
11507 	}
11508 
11509 	return SUCCESS_SEND_STATUS;
11510 }
11511 
11512 
11513 static enum sigma_cmd_result he_shortgi(struct sigma_dut *dut,
11514 					struct sigma_conn *conn,
11515 					const char *ifname,
11516 					const char *val)
11517 {
11518 	const char *var;
11519 
11520 	if (dut->ap_he_ulofdma == VALUE_ENABLED)
11521 		var = "he_ul_shortgi";
11522 	else
11523 		var = "shortgi";
11524 
11525 	if (strcmp(val, "0.8") == 0) {
11526 		run_iwpriv(dut, ifname, "%s 0", var);
11527 	} else if (strcmp(val, "1.6") == 0) {
11528 		run_iwpriv(dut, ifname, "%s 2", var);
11529 	} else if (strcmp(val, "3.2") == 0) {
11530 		run_iwpriv(dut, ifname, "%s 3", var);
11531 	} else {
11532 		send_resp(dut, conn, SIGMA_ERROR,
11533 			  "errorCode,Unsupported shortGI");
11534 		return STATUS_SENT_ERROR;
11535 	}
11536 
11537 	return SUCCESS_SEND_STATUS;
11538 }
11539 
11540 
11541 static enum sigma_cmd_result he_ar_gi_ltf_mask(struct sigma_dut *dut,
11542 					       struct sigma_conn *conn,
11543 					       const char *ifname,
11544 					       const char *val)
11545 {
11546 
11547 	uint32_t he_ar_gi_ltf;
11548 	uint16_t he_ar_gi, he_ar_ltf;
11549 
11550 	if (strcmp(val, "0.4") == 0) {
11551 		he_ar_gi = 0x01;
11552 	} else if (strcmp(val, "0.8") == 0) {
11553 		he_ar_gi = 0x02;
11554 	} else if (strcmp(val, "1.6") == 0) {
11555 		he_ar_gi = 0x04;
11556 	} else if (strcmp(val, "3.2") == 0) {
11557 		he_ar_gi = 0x08;
11558 	} else {
11559 		send_resp(dut, conn, SIGMA_ERROR,
11560 			  "errorCode,Unsupported shortGI");
11561 		return STATUS_SENT_ERROR;
11562 	}
11563 
11564 	if (dut->ar_ltf && strcmp(dut->ar_ltf, "6.4") == 0) {
11565 		he_ar_ltf = 0x02;
11566 	} else if (dut->ar_ltf && strcmp(dut->ar_ltf, "12.8") == 0) {
11567 		he_ar_ltf = 0x04;
11568 	} else if (dut->ar_ltf && strcmp(dut->ar_ltf, "3.2") == 0) {
11569 		he_ar_ltf = 0x01;
11570 	} else {
11571 		send_resp(dut, conn, SIGMA_ERROR,
11572 			  "errorCode,Unsupported LTF");
11573 		return STATUS_SENT_ERROR;
11574 	}
11575 
11576 	he_ar_gi_ltf = (he_ar_gi << 8) | he_ar_ltf;
11577 	run_iwpriv(dut, ifname, "he_ar_gi_ltf %lu", he_ar_gi_ltf);
11578 
11579 	return SUCCESS_SEND_STATUS;
11580 }
11581 
11582 
11583 static enum sigma_cmd_result he_rualloctones(struct sigma_dut *dut,
11584 					     struct sigma_conn *conn,
11585 					     const char *ifname,
11586 					     const char *val)
11587 {
11588 	char *token, *result;
11589 	int value;
11590 	char *saveptr;
11591 	int rualloc_type;
11592 	enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
11593 
11594 	token = strdup(val);
11595 	if (!token)
11596 		return -1;
11597 	result = strtok_r(token, ":", &saveptr);
11598 	if (!result) {
11599 		free(token);
11600 		send_resp(dut, conn, SIGMA_ERROR,
11601 			  "errorCode,RUAllocTones not specified");
11602 		return STATUS_SENT_ERROR;
11603 	}
11604 
11605 	/*
11606 	* ru_allocation_type can take the values of:
11607 	* 1 - DL OFDMA data RU allocation
11608 	* 3 - UL OFDMA data RU allocation
11609 	*/
11610 	rualloc_type = dut->ap_he_ulofdma == VALUE_ENABLED ? 3 : 1;
11611 
11612 
11613 	value = atoi(result);
11614 	if (value == 106) {
11615 		enum value_not_set_enabled_disabled ap_he_rualloc_106_80 =
11616 			VALUE_NOT_SET;
11617 
11618 		result = strtok_r(NULL, ":", &saveptr);
11619 		if (result) {
11620 			result = strtok_r(NULL, ":", &saveptr);
11621 			if (result)
11622 				ap_he_rualloc_106_80 = VALUE_ENABLED;
11623 			else
11624 				ap_he_rualloc_106_80 = VALUE_DISABLED;
11625 		}
11626 		if (ap_he_rualloc_106_80 == VALUE_ENABLED) {
11627 			run_system_wrapper(dut,
11628 					   "wifitool %s setUnitTestCmd 0x4b 9 %d 0 2 1 2 2 2 3 2",
11629 					   ifname, rualloc_type);
11630 		} else {
11631 			run_system_wrapper(dut,
11632 					   "wifitool %s setUnitTestCmd 0x4b 5 %d 0 2 1 2",
11633 					   ifname, rualloc_type);
11634 		}
11635 	} else if (value == 242) {
11636 		run_system_wrapper(
11637 			dut,
11638 			"wifitool %s setUnitTestCmd 0x4b 9 %d 0 3 1 3 2 3 3 3",
11639 			ifname, rualloc_type);
11640 	} else if (value == 26) {
11641 		run_system_wrapper(
11642 			dut,
11643 			"wifitool %s setUnitTestCmd 0x4b 9 %d 0 0 2 0 5 0 7 0",
11644 			ifname, rualloc_type);
11645 	} else if (value == 52) {
11646 		run_system_wrapper(
11647 			dut,
11648 			"wifitool %s setUnitTestCmd 0x4b 9 %d 0 1 1 1 2 1 3 1",
11649 			ifname, rualloc_type);
11650 	} else if (value == 484) {
11651 		run_system_wrapper(
11652 			dut,
11653 			"wifitool %s setUnitTestCmd 0x4b 5 %d 0 4 1 4",
11654 			ifname, rualloc_type);
11655 	} else if (value == 996) {
11656 		run_system_wrapper(dut,
11657 				   "wifitool %s setUnitTestCmd 0x4b 3 %d 0 5",
11658 				   ifname, rualloc_type);
11659 	} else {
11660 		send_resp(dut, conn, SIGMA_ERROR,
11661 			  "errorCode,Unsupported RUAllocTones");
11662 		ret = STATUS_SENT_ERROR;
11663 	}
11664 
11665 	free(token);
11666 	return ret;
11667 }
11668 
11669 
11670 static void ath_set_trigger_type_0(struct sigma_dut *dut, const char *ifname)
11671 {
11672 	/* TriggerType "0" for Basic trigger */
11673 	if (dut->ap_channel >= 36) {
11674 		/* 1 and 2 here is interpreted to 5g and 2g (bitmasks) */
11675 		run_system_wrapper(dut,
11676 				   "wifitool %s setUnitTestCmd 0x47 2 42 1",
11677 				   ifname);
11678 	} else {
11679 		run_system_wrapper(dut,
11680 				   "wifitool %s setUnitTestCmd 0x47 2 42 2",
11681 				   ifname);
11682 	}
11683 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 6",
11684 			   ifname);
11685 }
11686 
11687 
11688 static void ath_set_trigger_type_1(struct sigma_dut *dut, const char *ifname)
11689 {
11690 	/* TriggerType "1" for MU BRP */
11691 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 1",
11692 			   ifname);
11693 	mubrp_commands(dut, ifname);
11694 }
11695 
11696 
11697 static void ath_set_trigger_type_2(struct sigma_dut *dut, const char *ifname)
11698 {
11699 	/* TriggerType "2" for MU BAR */
11700 	if (dut->ap_channel >= 36) {
11701 		/* RU allocation RU 242 - DL OFDMA data */
11702 		run_system_wrapper(dut,
11703 				   "wifitool %s setUnitTestCmd 0x4b 5 9 0 3 1 3 2 3 3 3",
11704 				   ifname);
11705 		/* RU allocation RU 52 - UL BA */
11706 		run_system_wrapper(dut,
11707 				   "wifitool %s setUnitTestCmd 0x4b 5 9 0 2 1 2 2 2 3 2",
11708 				   ifname);
11709 	} else {
11710 		/* RU allocation RU 52 - DL ofdma data */
11711 		run_system_wrapper(dut,
11712 				   "wifitool %s setUnitTestCmd 0x4b 5 9 0 1 1 1 2 1 3 1",
11713 				   ifname);
11714 	}
11715 	/* Force TBPPDU duration to 400 us */
11716 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 400",
11717 			   ifname);
11718 	/* 0 to enable MU BAR, 1 to enable SU BAR */
11719 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 49 0",
11720 			   ifname);
11721 	/* MU BAR */
11722 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 64 0",
11723 			   ifname);
11724 }
11725 
11726 
11727 static void ath_set_trigger_type_3(struct sigma_dut *dut, const char *ifname)
11728 {
11729 	/* TriggerType "3" for MU RTS */
11730 	/* Send MU RTS Trigger - '1' is to enable MU RTS */
11731 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 101 1",
11732 			   ifname);
11733 }
11734 
11735 
11736 static void ath_set_trigger_type_4(struct sigma_dut *dut, const char *ifname,
11737 				   const char *basedev)
11738 {
11739 	/* TriggerType "4" for BSRP */
11740 	run_system_wrapper(dut, "cfg80211tool %s he_ul_trig_int 200", basedev);
11741 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 1000",
11742 			   ifname);
11743 	if (dut->ap_channel >= 36) {
11744 		run_system_wrapper(dut,
11745 				   "wifitool %s setUnitTestCmd 0x47 2 42 1",
11746 				   ifname);
11747 	} else {
11748 		run_system_wrapper(dut,
11749 				   "wifitool %s setUnitTestCmd 0x47 2 42 2",
11750 				   ifname);
11751 	}
11752 	/* Send BSRP command */
11753 	run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 7",
11754 			   ifname);
11755 }
11756 
11757 
11758 static enum sigma_cmd_result ath_ap_set_rfeature(struct sigma_dut *dut,
11759 						 struct sigma_conn *conn,
11760 						 struct sigma_cmd *cmd)
11761 {
11762 	const char *val;
11763 	const char *ifname;
11764 	enum sigma_cmd_result res;
11765 	const char *basedev = "wifi0";
11766 	int trigtype;
11767 	int he_ackpolicymac = 0;
11768 	char *num_ss = NULL;
11769 	char *nss[4] = { NULL, NULL, NULL, NULL };
11770 	char *aid[4] = { NULL, NULL, NULL, NULL };
11771 	char *aid_ss = NULL;
11772 	int omctrl_rxnss = 0, omctrl_chwidth = 0;
11773 	int param;
11774 	unsigned char mac_addr[ETH_ALEN];
11775 
11776 	memset(mac_addr, 0x00, ETH_ALEN);
11777 
11778 	ifname = get_main_ifname(dut);
11779 
11780 	if (sigma_radio_ifname[0])
11781 		basedev = sigma_radio_ifname[0];
11782 
11783 	/* Disable vap reset between the commands */
11784 	novap_reset(dut, ifname, 1);
11785 
11786 	val = get_param(cmd, "Opt_md_notif_ie");
11787 	if (val && ath_vht_op_mode_notif(dut, ifname, val) < 0)
11788 		return ERROR_SEND_STATUS;
11789 
11790 	/* TODO: Optional arguments */
11791 
11792 	val = get_param(cmd, "nss_mcs_opt");
11793 	if (val && ath_vht_nss_mcs(dut, ifname, val) < 0)
11794 		return ERROR_SEND_STATUS;
11795 
11796 	val = get_param(cmd, "chnum_band");
11797 	if (val && ath_vht_chnum_band(dut, ifname, val) < 0)
11798 		return ERROR_SEND_STATUS;
11799 
11800 	val = get_param(cmd, "RTS_FORCE");
11801 	if (val)
11802 		ath_config_rts_force(dut, ifname, val);
11803 
11804 	val = get_param(cmd, "DYN_BW_SGNL");
11805 	if (val)
11806 		ath_config_dyn_bw_sig(dut, ifname, val);
11807 
11808 	val = get_param(cmd, "CTS_WIDTH");
11809 	if (val)
11810 		ath_set_cts_width(dut, ifname, val);
11811 
11812 	val = get_param(cmd, "Ndpa_stainfo_mac");
11813 	if (val && ath_ndpa_stainfo_mac(dut, ifname, val) < 0)
11814 		return ERROR_SEND_STATUS;
11815 
11816 	val = get_param(cmd, "txBandwidth");
11817 	if (val && ath_set_width(dut, conn, ifname, val) < 0)
11818 		return ERROR_SEND_STATUS;
11819 
11820 	val = get_param(cmd, "Assoc_Disallow");
11821 	if (val)
11822 		ath_set_assoc_disallow(dut, ifname, val);
11823 
11824 
11825 	ath_set_nebor_bssid(dut, ifname, cmd);
11826 	val = get_param(cmd, "BTMReq_DisAssoc_Imnt");
11827 	if (val) {
11828 		dut->ap_btmreq_disassoc_imnt = atoi(val);
11829 		dut->ap_disassoc_timer = 1000;
11830 	}
11831 
11832 	val = get_param(cmd, "BTMReq_Term_Bit");
11833 	if (val)
11834 		dut->ap_btmreq_term_bit = atoi(val);
11835 
11836 	val = get_param(cmd, "Assoc_Delay");
11837 	if (val) {
11838 		dut->ap_assoc_delay = 1;
11839 		run_iwpriv(dut, ifname, "mbo_asoc_ret %s", val);
11840 	}
11841 
11842 	val = get_param(cmd, "Disassoc_Timer");
11843 	if (val)
11844 		dut->ap_disassoc_timer = atoi(val);
11845 
11846 	val = get_param(cmd, "BSS_Term_Duration");
11847 	if (val)
11848 		dut->ap_btmreq_bss_term_dur = atoi(val);
11849 
11850 	val = get_param(cmd, "BSS_Term_TSF");
11851 	if (val)
11852 		dut->ap_btmreq_bss_term_tsf = atoi(val);
11853 
11854 	val = get_param(cmd, "TxPower");
11855 	if (val)
11856 		ath_set_txpower(dut, ifname, val);
11857 
11858 	val = get_param(cmd, "DownlinkAvailCap");
11859 	if (val)
11860 		dut->ap_dl_availcap = atoi(val);
11861 
11862 	val = get_param(cmd, "UplinkAvailCap");
11863 	if (val) {
11864 		dut->ap_ul_availcap = atoi(val);
11865 		run_iwpriv(dut, ifname, "oce_wan_mtr %d %d",
11866 			   dut->ap_dl_availcap, dut->ap_ul_availcap);
11867 	}
11868 
11869 	val = get_param(cmd, "RSSIthreshold");
11870 	if (val) {
11871 		int rssithreshold;
11872 
11873 		run_iwpriv(dut, ifname, "oce_asoc_rej 1");
11874 		rssithreshold = atoi(val);
11875 		run_iwpriv(dut, ifname, "oce_asoc_rssi %d", rssithreshold);
11876 	}
11877 
11878 	val = get_param(cmd, "RetryDelay");
11879 	if (val) {
11880 		int retrydelay;
11881 
11882 		run_iwpriv(dut, ifname, "oce_asoc_rej 1");
11883 		retrydelay = atoi(val);
11884 		run_iwpriv(dut, ifname, "oce_asoc_dly %d", retrydelay);
11885 	}
11886 
11887 	val = get_param(cmd, "LTF");
11888 	if (val) {
11889 		if (dut->ap_fixed_rate) {
11890 			res = he_ltf(dut, conn, ifname, val);
11891 			if (res != SUCCESS_SEND_STATUS)
11892 				return res;
11893 		} else {
11894 			free(dut->ar_ltf);
11895 			dut->ar_ltf = strdup(val);
11896 			if (!dut->ar_ltf)
11897 				return ERROR_SEND_STATUS;
11898 		}
11899 	}
11900 
11901 	val = get_param(cmd, "GI");
11902 	if (val) {
11903 		if (dut->ap_fixed_rate)
11904 			res = he_shortgi(dut, conn, ifname, val);
11905 		else
11906 			res = he_ar_gi_ltf_mask(dut, conn, ifname, val);
11907 		if (res != SUCCESS_SEND_STATUS)
11908 			return res;
11909 	}
11910 
11911 	val = get_param(cmd, "RUAllocTones");
11912 	if (val) {
11913 		res = he_rualloctones(dut, conn, ifname, val);
11914 		if (res != SUCCESS_SEND_STATUS)
11915 			return res;
11916 	}
11917 
11918 	val = get_param(cmd, "MPDU_MU_SpacingFactor");
11919 	if (val)
11920 		run_system_wrapper(dut,
11921 				   "wifitool %s setUnitTestCmd 0x48 2 119, %s",
11922 				   ifname, val);
11923 
11924 	val = get_param(cmd, "PPDUTxType");
11925 	if (val) {
11926 		if (strcasecmp(val, "HE-SU") == 0) {
11927 			/* Change PPDU format type to HE-SU MCS 1 */
11928 			run_system_wrapper(dut,
11929 					   "wifitool %s setUnitTestCmd 0x48 2 89 0x401",
11930 					   ifname);
11931 		} else if (strcasecmp(val, "legacy") == 0) {
11932 			/* Change PPDU format type to non-HT */
11933 			run_system_wrapper(dut,
11934 					   "wifitool %s setUnitTestCmd 0x48 2 89 3",
11935 					   ifname);
11936 		} else {
11937 			send_resp(dut, conn, SIGMA_ERROR,
11938 				  "errorCode,Unsupported PPDUTxType");
11939 			return STATUS_SENT_ERROR;
11940 		}
11941 	}
11942 
11943 	val = get_param(cmd, "TXOPDuration");
11944 	if (val) {
11945 		if (strcasecmp(val, "UNSPECIFIED") == 0) {
11946 			/* The hardware is hardcoded with 0x7f; do nothing */
11947 		} else {
11948 			send_resp(dut, conn, SIGMA_ERROR,
11949 				  "errorCode,Unsupported TXOPDuration");
11950 			return STATUS_SENT_ERROR;
11951 		}
11952 	}
11953 
11954 	val = get_param(cmd, "Trig_Usrinfo_UL-MCS");
11955 	if (val)
11956 		run_iwpriv(dut, ifname, "he_ul_mcs %d", atoi(val));
11957 
11958 	val = get_param(cmd, "Trig_Usrinfo_UL-Target-RSSI");
11959 	if (val) {
11960 		/* Set target RSSI to -55 dBm */
11961 		run_system_wrapper(dut,
11962 				   "wifitool %s setUnitTestCmd 0x4b 2 7 %d",
11963 				   ifname, atoi(val) - 110);
11964 	}
11965 
11966 	val = get_param(cmd, "Trig_Interval");
11967 	if (val)
11968 		run_iwpriv(dut, basedev, "he_ul_trig_int %d", atoi(val));
11969 
11970 	val = get_param(cmd, "Trig_ComInfo_ULLength");
11971 	if (val)
11972 		run_system_wrapper(dut,
11973 				   "wifitool %s setUnitTestCmd 0x48 2 141 %d",
11974 				   ifname, atoi(val));
11975 
11976 	val = get_param(cmd, "DisableTriggerType");
11977 	if (val) {
11978 		trigtype = atoi(val);
11979 		switch (trigtype) {
11980 		case 0:
11981 			/* DisableTriggerType "0" for basic trigger */
11982 			run_system_wrapper(dut,
11983 					   "wifitool %s setUnitTestCmd 0x47 2 42 0",
11984 					   ifname);
11985 			break;
11986 		default:
11987 			/* Nothing to be done for now */
11988 			break;
11989 		}
11990 	}
11991 
11992 	val = get_param(cmd, "Trigger_TxBF");
11993 	if (val) {
11994 		if (strcasecmp(val, "enable") == 0) {
11995 			run_iwpriv(dut, ifname, "he_sounding_mode 0x9");
11996 		} else if (strcasecmp(val, "disable") == 0) {
11997 			run_iwpriv(dut, ifname, "he_sounding_mode 0x1");
11998 		} else {
11999 			send_resp(dut, conn, SIGMA_ERROR,
12000 				  "errorCode,Unsupported trigger_txbf");
12001 			return STATUS_SENT_ERROR;
12002 		}
12003 	}
12004 
12005 	val = get_param(cmd, "Trig_UsrInfo_RUAlloc");
12006 	if (val) {
12007 		res = he_rualloctones(dut, conn, ifname, val);
12008 		if (res != SUCCESS_SEND_STATUS)
12009 			return res;
12010 	}
12011 
12012 	val = get_param(cmd, "TriggerCoding");
12013 	if (val) {
12014 		if (strcasecmp(val, "BCC") == 0) {
12015 			/* In case of LDPC enable this command can force BCC if
12016 			 * RU size <= 242 */
12017 			run_iwpriv(dut, ifname, "he_ul_ldpc 0");
12018 		} else if (strcasecmp(val, "LDPC") == 0) {
12019 			novap_reset(dut, ifname, 0);
12020 			run_iwpriv(dut, ifname, "he_ul_ldpc 1");
12021 			novap_reset(dut, ifname, 1);
12022 		} else {
12023 			send_resp(dut, conn, SIGMA_ERROR,
12024 				  "errorCode,Unsupported TriggerCoding");
12025 			return STATUS_SENT_ERROR;
12026 		}
12027 	}
12028 
12029 	val = get_param(cmd, "AckPolicy_MAC");
12030 	if (val) {
12031 		if (parse_mac_address(dut, val, mac_addr) < 0) {
12032 			send_resp(dut, conn, SIGMA_ERROR,
12033 				  "errorCode,MAC Address not in proper format");
12034 			return STATUS_SENT_ERROR;
12035 		}
12036 		he_ackpolicymac = 1;
12037 	}
12038 
12039 	val = get_param(cmd, "AckPolicy");
12040 	if (val) {
12041 		int ap_he_ackpolicy;
12042 
12043 		ap_he_ackpolicy = atoi(val);
12044 		if (ap_he_ackpolicy == 0 && he_ackpolicymac) {
12045 			/* Disable all-BAR ackpolicy for MU-MIMO */
12046 			run_system_wrapper(dut,
12047 					   "wifitool %s setUnitTestCmd 0x48 2 62 0",
12048 					   ifname);
12049 			/* Disable all-BAR ackpolicy first */
12050 			run_system_wrapper(dut,
12051 					   "wifitool %s setUnitTestCmd 0x48 2 64 0",
12052 					   ifname);
12053 			/* Set normal ack policy for the STA with the specified
12054 			 * MAC address in DL-TX case */
12055 			run_system_wrapper(dut,
12056 					   "wifitool %s setUnitTestCmd 0x4b 8 8 1 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
12057 					   ifname, mac_addr[0], mac_addr[1],
12058 					   mac_addr[2], mac_addr[3],
12059 					   mac_addr[4], mac_addr[5]);
12060 		} else if (ap_he_ackpolicy == 3) {
12061 			/* Enable all-BAR ackpolicy for MU-MIMO DL */
12062 			run_system_wrapper(dut,
12063 					   "wifitool %s setUnitTestCmd 0x48 2 62 1",
12064 					   ifname);
12065 			/* Enable all-BAR ackpolicy */
12066 			run_system_wrapper(dut,
12067 					   "wifitool %s setUnitTestCmd 0x48 2 64 1",
12068 					   ifname);
12069 		} else if (ap_he_ackpolicy == 4) {
12070 			/* Enable htp-ack ackpolicy */
12071 			run_system_wrapper(dut,
12072 					   "wifitool %s setUnitTestCmd 0x47 2 99 1",
12073 					   ifname);
12074 		} else {
12075 			send_resp(dut, conn, SIGMA_ERROR,
12076 				  "errorCode,Invalid AckPolicy setting");
12077 			return STATUS_SENT_ERROR;
12078 		}
12079 	}
12080 
12081 	val = get_param(cmd, "Trig_ComInfo_GI-LTF");
12082 	if (val) {
12083 		int trig_gi_ltf;
12084 
12085 		trig_gi_ltf = atoi(val);
12086 		if (trig_gi_ltf == 0) {
12087 			he_ltf(dut, conn, ifname, "3.2");
12088 			he_shortgi(dut, conn, ifname, "1.6");
12089 		} else if (trig_gi_ltf == 1) {
12090 			he_ltf(dut, conn, ifname, "6.4");
12091 			he_shortgi(dut, conn, ifname, "1.6");
12092 		} else if (trig_gi_ltf == 2) {
12093 			he_ltf(dut, conn, ifname, "12.8");
12094 			he_shortgi(dut, conn, ifname, "3.2");
12095 		} else {
12096 			send_resp(dut, conn, SIGMA_ERROR,
12097 				  "errorCode,Unsupported Trig_ComInfo_GI-LTF");
12098 			return STATUS_SENT_ERROR;
12099 		}
12100 	}
12101 
12102 	val = get_param(cmd, "Trig_ComInfo_BW");
12103 	if (val) {
12104 		int chwidth;
12105 
12106 		chwidth = atoi(val);
12107 		/* Set the channel width */
12108 		run_iwpriv(dut, ifname, "chwidth %d", chwidth);
12109 	}
12110 
12111 	val = get_param(cmd, "NumSS");
12112 	if (val) {
12113 		int i = 0;
12114 		char *numss_val;
12115 		char *saveptr;
12116 
12117 		num_ss = strdup(val);
12118 		if (!num_ss)
12119 			return ERROR_SEND_STATUS;
12120 
12121 		numss_val = strtok_r(num_ss, " ", &saveptr);
12122 		for (i = 0; numss_val && i < 4; i++) {
12123 			nss[i] = numss_val;
12124 			numss_val = strtok_r(NULL, " ", &saveptr);
12125 		}
12126 	}
12127 
12128 	val = get_param(cmd, "NumSS_MAC");
12129 	if (val) {
12130 		char *sta_mac_str;
12131 		char *saveptr;
12132 		char *sta_mac_list_str;
12133 
12134 		sta_mac_list_str = strdup(val);
12135 		if (!sta_mac_list_str) {
12136 			free(num_ss);
12137 			return ERROR_SEND_STATUS;
12138 		}
12139 
12140 		sta_mac_str = strtok_r(sta_mac_list_str, " ", &saveptr);
12141 		if (sta_mac_str && nss[0]) {
12142 			run_system_wrapper(dut,
12143 					   "wifitool %s chmask_persta %s %s",
12144 					   ifname, sta_mac_str, nss[0]);
12145 		}
12146 
12147 		sta_mac_str = strtok_r(NULL, " ", &saveptr);
12148 		if (sta_mac_str && nss[1]) {
12149 			run_system_wrapper(dut,
12150 					   "wifitool %s chmask_persta %s %s",
12151 					   ifname, sta_mac_str, nss[1]);
12152 		}
12153 
12154 		sta_mac_str = strtok_r(NULL, " ", &saveptr);
12155 		if (sta_mac_str && nss[2]) {
12156 			run_system_wrapper(dut,
12157 					   "wifitool %s chmask_persta %s %s",
12158 					   ifname, sta_mac_str, nss[2]);
12159 		}
12160 
12161 		sta_mac_str = strtok_r(NULL, " ", &saveptr);
12162 		if (sta_mac_str && nss[3]) {
12163 			run_system_wrapper(dut,
12164 					   "wifitool %s chmask_persta %s %s",
12165 					   ifname, sta_mac_str, nss[3]);
12166 		}
12167 
12168 		free(sta_mac_list_str);
12169 	}
12170 
12171 	free(num_ss);
12172 	num_ss = NULL;
12173 
12174 	val = get_param(cmd, "AID");
12175 	if (val) {
12176 		int i = 0;
12177 		char *aid_val;
12178 		char *saveptr;
12179 
12180 		aid_ss = strdup(val);
12181 		if (!aid_ss)
12182 			return ERROR_SEND_STATUS;
12183 
12184 		aid_val = strtok_r(aid_ss, " ", &saveptr);
12185 		for (i = 0; aid_val && i < 4; i++) {
12186 			aid[i] = aid_val;
12187 			aid_val = strtok_r(NULL, " ", &saveptr);
12188 		}
12189 	}
12190 
12191 	val = get_param(cmd, "AddbaReq");
12192 	if (val) {
12193 		if (strcasecmp(val, "enable") == 0) {
12194 			run_iwpriv(dut, ifname, "setaddbaoper 1");
12195 			run_system_wrapper(dut,
12196 					   "wifitool %s sendaddba %s 0 64",
12197 					   ifname, aid[0]);
12198 		} else {
12199 			send_resp(dut, conn, SIGMA_ERROR,
12200 				  "errorCode,Unsupported AddbaReq value");
12201 			free(aid_ss);
12202 			return STATUS_SENT_ERROR;
12203 		}
12204 	}
12205 
12206 	val = get_param(cmd, "AddbaResp");
12207 	if (val) {
12208 		if (aid_ss && strcasecmp(val, "accepted") == 0) {
12209 			int aid_1 = atoi(aid_ss);
12210 
12211 			if (aid_1 == 1)
12212 				aid_1 = 2;
12213 			else
12214 				aid_1 = aid_1 - 1;
12215 
12216 			/* There is no mechanism in place to reject Add BA Req
12217 			 * from all STAs and selectively accept Add BA Req from
12218 			 * a specified STA. Instead, it can accept Add BA Req
12219 			 * from all STAs and selectively reject from specified
12220 			 * STAs. Make changes for the same using the below
12221 			 * commands. */
12222 			run_system_wrapper(dut, ifname, "setaddbaoper 1");
12223 			run_system_wrapper(dut, "wifitool %s refusealladdbas 0",
12224 					   ifname);
12225 			run_system_wrapper(dut,
12226 					   "wifitool %s setaddbaresp %d 0 37",
12227 					   ifname, aid_1);
12228 		} else {
12229 			send_resp(dut, conn, SIGMA_ERROR,
12230 				  "errorCode,Unsupported Addbaresp value");
12231 			free(aid_ss);
12232 			return STATUS_SENT_ERROR;
12233 		}
12234 	}
12235 
12236 	val = get_param(cmd, "Trig_UsrInfo_SSAlloc_RA-RU");
12237 	if (val) {
12238 		char *ssalloc_str;
12239 		char *saveptr;
12240 		char *ssalloc_list_str;
12241 
12242 		ssalloc_list_str = strdup(val);
12243 		if (!ssalloc_list_str) {
12244 			free(aid_ss);
12245 			return ERROR_SEND_STATUS;
12246 		}
12247 
12248 		ssalloc_str = strtok_r(ssalloc_list_str, ":", &saveptr);
12249 		if (ssalloc_str && aid[0]) {
12250 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12251 					   ifname, aid[0], ssalloc_str);
12252 		}
12253 
12254 		ssalloc_str = strtok_r(NULL, " ", &saveptr);
12255 		if (ssalloc_str && aid[1]) {
12256 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12257 					   ifname, aid[1], ssalloc_str);
12258 		}
12259 
12260 		ssalloc_str = strtok_r(NULL, " ", &saveptr);
12261 		if (ssalloc_str && aid[2]) {
12262 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12263 					   ifname, aid[2], ssalloc_str);
12264 		}
12265 
12266 		ssalloc_str = strtok_r(NULL, " ", &saveptr);
12267 		if (ssalloc_str && aid[3]) {
12268 			run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12269 					   ifname, aid[3], ssalloc_str);
12270 		}
12271 
12272 		free(ssalloc_list_str);
12273 	}
12274 
12275 	free(aid_ss);
12276 	aid_ss = NULL;
12277 
12278 	val = get_param(cmd, "OMCtrl_RxNSS");
12279 	if (val)
12280 		omctrl_rxnss = atoi(val);
12281 
12282 	val = get_param(cmd, "OMCtrl_ChnlWidth");
12283 	if (val)
12284 		omctrl_chwidth = atoi(val);
12285 
12286 	val = get_param(cmd, "Client_mac");
12287 	if (val) {
12288 		if (parse_mac_address(dut, val, mac_addr) < 0) {
12289 			send_resp(dut, conn, SIGMA_ERROR,
12290 				  "errorCode,MAC Address not in proper format");
12291 			return STATUS_SENT_ERROR;
12292 		}
12293 
12294 		/* setUnitTestCmd 13 7 1 mac3mac2mac1mac0 mac5mac4 <rx_nss>
12295 		 * <bw> <ulmu> <tx_nss> */
12296 		run_system_wrapper(dut,
12297 				   "wifitool %s setUnitTestCmd 13 7 1 0x%02x%02x%02x%02x 0x%02x%02x %d %d 1 %d",
12298 				   ifname, mac_addr[3], mac_addr[2],
12299 				   mac_addr[1], mac_addr[0], mac_addr[5],
12300 				   mac_addr[4], omctrl_rxnss,
12301 				   omctrl_chwidth, omctrl_rxnss);
12302 	}
12303 
12304 	val = get_param(cmd, "TriggerType");
12305 	if (val) {
12306 		trigtype = atoi(val);
12307 		switch (trigtype) {
12308 		case 0:
12309 			ath_set_trigger_type_0(dut, ifname);
12310 			break;
12311 		case 1:
12312 			ath_set_trigger_type_1(dut, ifname);
12313 			break;
12314 		case 2:
12315 			ath_set_trigger_type_2(dut, ifname);
12316 			break;
12317 		case 3:
12318 			ath_set_trigger_type_3(dut, ifname);
12319 			break;
12320 		case 4:
12321 			ath_set_trigger_type_4(dut, ifname, basedev);
12322 			break;
12323 		default:
12324 			send_resp(dut, conn, SIGMA_ERROR,
12325 				  "errorCode,TriggerType not supported");
12326 			return STATUS_SENT_ERROR;
12327 		}
12328 	}
12329 
12330 	val = get_param(cmd, "HE_TXOPDurRTSThr");
12331 	if (val)
12332 		run_iwpriv(dut, ifname, "he_rtsthrshld %d", atoi(val));
12333 
12334 	val = get_param(cmd, "NAV_Update");
12335 	if (val) {
12336 		if (strcasecmp(val, "disable") == 0) {
12337 			run_iwpriv(dut, basedev, "nav_config 1 0");
12338 		} else if (strcasecmp(val, "enable") == 0) {
12339 			/* Do nothing */
12340 		} else {
12341 			send_resp(dut, conn, SIGMA_ERROR,
12342 				  "errorCode,Unsupported NAV update");
12343 			return STATUS_SENT_ERROR;
12344 		}
12345 	}
12346 
12347 	/* Configure WMM Parameter Elements */
12348 	val = get_param(cmd, "STA_WMMPE_ECWmin_BE");
12349 	if (val) {
12350 		param = atoi(val);
12351 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BE, param);
12352 	}
12353 
12354 	val = get_param(cmd, "STA_WMMPE_ECWmin_BK");
12355 	if (val) {
12356 		param = atoi(val);
12357 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BK, param);
12358 	}
12359 
12360 	val = get_param(cmd, "STA_WMMPE_ECWmin_VI");
12361 	if (val) {
12362 		param = atoi(val);
12363 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VI, param);
12364 	}
12365 
12366 	val = get_param(cmd, "STA_WMMPE_ECWmin_VO");
12367 	if (val) {
12368 		param = atoi(val);
12369 		run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VO, param);
12370 	}
12371 
12372 	val = get_param(cmd, "STA_WMMPE_ECWmax_BE");
12373 	if (val) {
12374 		param = atoi(val);
12375 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BE, param);
12376 	}
12377 
12378 	val = get_param(cmd, "STA_WMMPE_ECWmax_BK");
12379 	if (val) {
12380 		param = atoi(val);
12381 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BK, param);
12382 	}
12383 
12384 	val = get_param(cmd, "STA_WMMPE_ECWmax_VI");
12385 	if (val) {
12386 		param = atoi(val);
12387 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VI, param);
12388 	}
12389 
12390 	val = get_param(cmd, "STA_WMMPE_ECWmax_VO");
12391 	if (val) {
12392 		param = atoi(val);
12393 		run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VO, param);
12394 	}
12395 
12396 	val = get_param(cmd, "STA_WMMPE_AIFSN_BE");
12397 	if (val) {
12398 		param = atoi(val);
12399 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BE, param);
12400 	}
12401 
12402 	val = get_param(cmd, "STA_WMMPE_AIFSN_BK");
12403 	if (val) {
12404 		param = atoi(val);
12405 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BK, param);
12406 	}
12407 
12408 	val = get_param(cmd, "STA_WMMPE_AIFSN_VI");
12409 	if (val) {
12410 		param = atoi(val);
12411 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VI, param);
12412 	}
12413 
12414 	val = get_param(cmd, "STA_WMMPE_AIFSN_VO");
12415 	if (val) {
12416 		param = atoi(val);
12417 		run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VO, param);
12418 	}
12419 
12420 
12421 	val = get_param(cmd, "STA_WMMPE_TXOP_BE");
12422 	if (val) {
12423 		param = atoi(val);
12424 		run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BE, param);
12425 	}
12426 
12427 	val = get_param(cmd, "STA_WMMPE_TOXP_BK");
12428 	if (val) {
12429 		param = atoi(val);
12430 		run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BK, param);
12431 	}
12432 
12433 	val = get_param(cmd, "STA_WMMPE_TXOP_VI");
12434 	if (val) {
12435 		param = atoi(val);
12436 		run_iwpriv(dut, ifname, "txoplimit %d %d", AP_AC_VI, param);
12437 	}
12438 
12439 	val = get_param(cmd, "STA_WMMPE_TXOP_VO");
12440 	if (val) {
12441 		param = atoi(val);
12442 		run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_VO, param);
12443 	}
12444 
12445 	/* Configure MU EDCA */
12446 	val = get_param(cmd, "STA_MUEDCA_ECWmin_BE");
12447 	if (val) {
12448 		param = atoi(val);
12449 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BE, param);
12450 	}
12451 
12452 	val = get_param(cmd, "STA_MUEDCA_ECWmin_BK");
12453 	if (val) {
12454 		param = atoi(val);
12455 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BK, param);
12456 	}
12457 
12458 	val = get_param(cmd, "STA_MUEDCA_ECWmin_VI");
12459 	if (val) {
12460 		param = atoi(val);
12461 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VI, param);
12462 	}
12463 
12464 	val = get_param(cmd, "STA_MUEDCA_ECWmin_VO");
12465 	if (val) {
12466 		param = atoi(val);
12467 		run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VO, param);
12468 	}
12469 
12470 	val = get_param(cmd, "STA_MUEDCA_ECWmax_BE");
12471 	if (val) {
12472 		param = atoi(val);
12473 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BE, param);
12474 	}
12475 
12476 	val = get_param(cmd, "STA_MUEDCA_ECWmax_BK");
12477 	if (val) {
12478 		param = atoi(val);
12479 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BK, param);
12480 	}
12481 
12482 	val = get_param(cmd, "STA_MUEDCA_ECWmax_VI");
12483 	if (val) {
12484 		param = atoi(val);
12485 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VI, param);
12486 	}
12487 
12488 	val = get_param(cmd, "STA_MUEDCA_ECWmax_VO");
12489 	if (val) {
12490 		param = atoi(val);
12491 		run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VO, param);
12492 	}
12493 
12494 	val = get_param(cmd, "STA_MUEDCA_AIFSN_BE");
12495 	if (val) {
12496 		param = atoi(val);
12497 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BE, param);
12498 	}
12499 
12500 	val = get_param(cmd, "STA_MUEDCA_AIFSN_BK");
12501 	if (val) {
12502 		param = atoi(val);
12503 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BK, param);
12504 	}
12505 
12506 	val = get_param(cmd, "STA_MUEDCA_AIFSN_VI");
12507 	if (val) {
12508 		param = atoi(val);
12509 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VI, param);
12510 	}
12511 
12512 	val = get_param(cmd, "STA_MUEDCA_AIFSN_VO");
12513 	if (val) {
12514 		param = atoi(val);
12515 		run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VO, param);
12516 	}
12517 
12518 	val = get_param(cmd, "STA_MUEDCA_Timer_BE");
12519 	if (val) {
12520 		param = atoi(val);
12521 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BE, param);
12522 	}
12523 
12524 	val = get_param(cmd, "STA_MUEDCA_Timer_BK");
12525 	if (val) {
12526 		param = atoi(val);
12527 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BK, param);
12528 	}
12529 
12530 	val = get_param(cmd, "STA_MUEDCA_Timer_VI");
12531 	if (val) {
12532 		param = atoi(val);
12533 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VI, param);
12534 	}
12535 
12536 	val = get_param(cmd, "STA_MUEDCA_Timer_VO");
12537 	if (val) {
12538 		param = atoi(val);
12539 		run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VO, param);
12540 	}
12541 
12542 	return SUCCESS_SEND_STATUS;
12543 }
12544 
12545 
12546 static int wcn_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
12547 			      const char *val)
12548 {
12549 	char *token, *result;
12550 	int channel = 36;
12551 	char *saveptr;
12552 
12553 	/* Extract the channel info */
12554 	token = strdup(val);
12555 	if (!token)
12556 		return -1;
12557 	result = strtok_r(token, ";", &saveptr);
12558 	if (result)
12559 		channel = atoi(result);
12560 
12561 	/* Issue the channel switch command */
12562 	run_iwpriv(dut, ifname, "setChanChange %d", channel);
12563 
12564 	free(token);
12565 	return 0;
12566 }
12567 
12568 
12569 static enum sigma_cmd_result wcn_ap_set_rfeature(struct sigma_dut *dut,
12570 						 struct sigma_conn *conn,
12571 						 struct sigma_cmd *cmd)
12572 {
12573 	const char *val;
12574 	const char *ifname;
12575 
12576 	ifname = get_main_ifname(dut);
12577 
12578 	val = get_param(cmd, "chnum_band");
12579 	if (val && wcn_vht_chnum_band(dut, ifname, val) < 0)
12580 		return ERROR_SEND_STATUS;
12581 
12582 	val = get_param(cmd, "txBandwidth");
12583 	if (val) {
12584 		int old_ch_bw = dut->ap_chwidth;
12585 
12586 		if (strcasecmp(val, "Auto") == 0) {
12587 			dut->ap_chwidth = 0;
12588 		} else if (strcasecmp(val, "20") == 0) {
12589 			dut->ap_chwidth = 0;
12590 		} else if (strcasecmp(val, "40") == 0) {
12591 			dut->ap_chwidth = 1;
12592 		} else if (strcasecmp(val, "80") == 0) {
12593 			dut->ap_chwidth = 2;
12594 		} else if (strcasecmp(val, "160") == 0) {
12595 			dut->ap_chwidth = 3;
12596 		} else {
12597 			send_resp(dut, conn, SIGMA_ERROR,
12598 				  "ErrorCode,WIDTH not supported");
12599 			return STATUS_SENT_ERROR;
12600 		}
12601 		if (old_ch_bw != dut->ap_chwidth) {
12602 			if (cmd_ap_config_commit(dut, conn, cmd) <= 0)
12603 				return STATUS_SENT_ERROR;
12604 		} else {
12605 			sigma_dut_print(dut, DUT_MSG_DEBUG, "No change in BW");
12606 		}
12607 	}
12608 
12609 	val = get_param(cmd, "GI");
12610 	if (val) {
12611 		int fix_rate_sgi;
12612 
12613 		if (strcmp(val, "0.8") == 0) {
12614 			run_iwpriv(dut, ifname, "enable_short_gi 9");
12615 			fix_rate_sgi = 1;
12616 		} else if (strcmp(val, "1.6") == 0) {
12617 			run_iwpriv(dut, ifname, "enable_short_gi 10");
12618 			fix_rate_sgi = 2;
12619 		} else if (strcmp(val, "3.2") == 0) {
12620 			run_iwpriv(dut, ifname, "enable_short_gi 11");
12621 			fix_rate_sgi = 3;
12622 		} else {
12623 			send_resp(dut, conn, SIGMA_ERROR,
12624 				  "errorCode,GI value not supported");
12625 			return STATUS_SENT_ERROR;
12626 		}
12627 		run_iwpriv(dut, ifname, "enable_short_gi %d", fix_rate_sgi);
12628 	}
12629 
12630 	val = get_param(cmd, "LTF");
12631 	if (val) {
12632 #ifdef NL80211_SUPPORT
12633 		if (strcmp(val, "3.2") == 0) {
12634 			wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_1X);
12635 		} if (strcmp(val, "6.4") == 0) {
12636 			wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_2X);
12637 		} else if (strcmp(val, "12.8") == 0) {
12638 			wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_4X);
12639 		} else {
12640 			send_resp(dut, conn, SIGMA_ERROR,
12641 				  "errorCode,LTF value not supported");
12642 			return STATUS_SENT;
12643 		}
12644 #else /* NL80211_SUPPORT */
12645 		sigma_dut_print(dut, DUT_MSG_ERROR,
12646 				"LTF cannot be set without NL80211_SUPPORT defined");
12647 		return ERROR_SEND_STATUS;
12648 #endif /* NL80211_SUPPORT */
12649 	}
12650 
12651 	return SUCCESS_SEND_STATUS;
12652 }
12653 
12654 
12655 static int mac80211_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
12656 				   const char *val)
12657 {
12658 	char *token, *result;
12659 	int channel = 36, chwidth = 80, center_freq_idx, center_freq,
12660 		channel_freq;
12661 	char buf[100];
12662 	char *saveptr;
12663 	int res;
12664 
12665 	/* Extract the channel info */
12666 	token = strdup(val);
12667 	if (!token)
12668 		return -1;
12669 	result = strtok_r(token, ";", &saveptr);
12670 	if (result)
12671 		channel = atoi(result);
12672 
12673 	/* Extract the channel width info */
12674 	result = strtok_r(NULL, ";", &saveptr);
12675 	if (result)
12676 		chwidth = atoi(result);
12677 
12678 	center_freq_idx = get_oper_centr_freq_seq_idx(chwidth, channel);
12679 	if (center_freq_idx < 0) {
12680 		free(token);
12681 		return -1;
12682 	}
12683 
12684 	center_freq = get_5g_channel_freq(center_freq_idx);
12685 	channel_freq = get_5g_channel_freq(channel);
12686 
12687 	/* Issue the channel switch command */
12688 	res = snprintf(buf, sizeof(buf),
12689 		       " -i %s chan_switch 10 %d sec_channel_offset=1 center_freq1=%d bandwidth=%d blocktx vht",
12690 		       ifname, channel_freq, center_freq, chwidth);
12691 	if (res < 0 || res >= sizeof(buf) || run_hostapd_cli(dut, buf) != 0) {
12692 		sigma_dut_print(dut, DUT_MSG_ERROR,
12693 				"hostapd_cli chan_switch failed");
12694 	}
12695 
12696 	free(token);
12697 	return 0;
12698 }
12699 
12700 
12701 static int mac80211_ap_set_rfeature(struct sigma_dut *dut,
12702 				    struct sigma_conn *conn,
12703 				    struct sigma_cmd *cmd)
12704 {
12705 	const char *val;
12706 	const char *ifname;
12707 
12708 	ifname = get_main_ifname(dut);
12709 
12710 	val = get_param(cmd, "RTS_FORCE");
12711 	if (val)
12712 		mac80211_config_rts_force(dut, ifname, val);
12713 
12714 	val = get_param(cmd, "chnum_band");
12715 	if (val && mac80211_vht_chnum_band(dut, ifname, val) < 0)
12716 		return -1;
12717 
12718 	return 1;
12719 }
12720 
12721 
12722 #ifdef __linux__
12723 static int wil6210_ap_set_rfeature(struct sigma_dut *dut,
12724 				   struct sigma_conn *conn,
12725 				   struct sigma_cmd *cmd)
12726 {
12727 	const char *val;
12728 
12729 	val = get_param(cmd, "ExtSchIE");
12730 	if (val && !strcasecmp(val, "Enable")) {
12731 		struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
12732 		int count = MAX_ESE_ALLOCS;
12733 
12734 		if (sta_extract_60g_ese(dut, cmd, allocs, &count))
12735 			return -1;
12736 		if (wil6210_set_ese(dut, count, allocs))
12737 			return -1;
12738 		return 1;
12739 	}
12740 
12741 	send_resp(dut, conn, SIGMA_ERROR,
12742 		  "errorCode,Invalid ap_set_rfeature(60G)");
12743 	return 0;
12744 }
12745 #endif /* __linux__ */
12746 
12747 
12748 static enum sigma_cmd_result cmd_ap_set_rfeature(struct sigma_dut *dut,
12749 						 struct sigma_conn *conn,
12750 						 struct sigma_cmd *cmd)
12751 {
12752 	/* const char *name = get_param(cmd, "NAME"); */
12753 	/* const char *type = get_param(cmd, "Type"); */
12754 	const char *val;
12755 	char buf[100];
12756 
12757 	val = get_param(cmd, "ReassocResp_RSNXE_Used");
12758 	if (val) {
12759 		const char *ifname = get_hostapd_ifname(dut);
12760 
12761 		if (atoi(val) == 0)
12762 			snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 2");
12763 		else
12764 			snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 1");
12765 		if (hapd_command(ifname, buf) < 0) {
12766 			send_resp(dut, conn, SIGMA_ERROR,
12767 				  "ErrorCode,Failed to set ft_rsnxe_used");
12768 			return STATUS_SENT_ERROR;
12769 		}
12770 	}
12771 
12772 	switch (get_driver_type(dut)) {
12773 	case DRIVER_ATHEROS:
12774 		return ath_ap_set_rfeature(dut, conn, cmd);
12775 	case DRIVER_OPENWRT:
12776 		switch (get_openwrt_driver_type()) {
12777 		case OPENWRT_DRIVER_ATHEROS:
12778 			return ath_ap_set_rfeature(dut, conn, cmd);
12779 		default:
12780 			send_resp(dut, conn, SIGMA_ERROR,
12781 				  "errorCode,Unsupported ap_set_rfeature with the current openwrt driver");
12782 			return 0;
12783 		}
12784 	case DRIVER_LINUX_WCN:
12785 	case DRIVER_WCN:
12786 		return wcn_ap_set_rfeature(dut, conn, cmd);
12787 	case DRIVER_MAC80211:
12788 		return mac80211_ap_set_rfeature(dut, conn, cmd);
12789 #ifdef __linux__
12790 	case DRIVER_WIL6210:
12791 		return wil6210_ap_set_rfeature(dut, conn, cmd);
12792 #endif /* __linux__ */
12793 	default:
12794 		send_resp(dut, conn, SIGMA_ERROR,
12795 			  "errorCode,Unsupported ap_set_rfeature with the current driver");
12796 		return 0;
12797 	}
12798 }
12799 
12800 
12801 static enum sigma_cmd_result cmd_accesspoint(struct sigma_dut *dut,
12802 					     struct sigma_conn *conn,
12803 					     struct sigma_cmd *cmd)
12804 {
12805 	/* const char *name = get_param(cmd, "NAME"); */
12806 	return 1;
12807 }
12808 
12809 
12810 static enum sigma_cmd_result
12811 cmd_ap_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
12812 			     struct sigma_cmd *cmd)
12813 {
12814 	const char *val;
12815 
12816 	val = get_param(cmd, "Oper_Chn");
12817 	if (val) {
12818 		dut->ap_oper_chn = 1;
12819 		dut->ap_channel = atoi(val);
12820 	}
12821 
12822 	val = get_param(cmd, "DPPConfiguratorAddress");
12823 	if (val) {
12824 		free(dut->ap_dpp_conf_addr);
12825 		dut->ap_dpp_conf_addr = strdup(val);
12826 	}
12827 
12828 	val = get_param(cmd, "DPPConfiguratorPKHash");
12829 	if (val) {
12830 		free(dut->ap_dpp_conf_pkhash);
12831 		dut->ap_dpp_conf_pkhash = strdup(val);
12832 	}
12833 
12834 	return 1;
12835 }
12836 
12837 
12838 void ap_register_cmds(void)
12839 {
12840 	sigma_dut_reg_cmd("ap_ca_version", NULL, cmd_ap_ca_version);
12841 	sigma_dut_reg_cmd("ap_set_wireless", NULL, cmd_ap_set_wireless);
12842 	sigma_dut_reg_cmd("ap_send_addba_req", NULL, cmd_ap_send_addba_req);
12843 	sigma_dut_reg_cmd("ap_set_11n_wireless", NULL, cmd_ap_set_wireless);
12844 	sigma_dut_reg_cmd("ap_set_11n", NULL, cmd_ap_set_wireless);
12845 	sigma_dut_reg_cmd("ap_set_11d", NULL, cmd_ap_set_wireless);
12846 	sigma_dut_reg_cmd("ap_set_11h", NULL, cmd_ap_set_wireless);
12847 	sigma_dut_reg_cmd("ap_set_security", NULL, cmd_ap_set_security);
12848 	sigma_dut_reg_cmd("ap_set_apqos", NULL, cmd_ap_set_apqos);
12849 	sigma_dut_reg_cmd("ap_set_staqos", NULL, cmd_ap_set_staqos);
12850 	sigma_dut_reg_cmd("ap_set_radius", NULL, cmd_ap_set_radius);
12851 	sigma_dut_reg_cmd("ap_reboot", NULL, cmd_ap_reboot);
12852 	sigma_dut_reg_cmd("ap_config_commit", NULL, cmd_ap_config_commit);
12853 	sigma_dut_reg_cmd("ap_reset_default", NULL, cmd_ap_reset_default);
12854 	sigma_dut_reg_cmd("ap_get_info", NULL, cmd_ap_get_info);
12855 	sigma_dut_reg_cmd("ap_deauth_sta", NULL, cmd_ap_deauth_sta);
12856 	sigma_dut_reg_cmd("ap_send_frame", NULL, cmd_ap_send_frame);
12857 	sigma_dut_reg_cmd("ap_get_mac_address", NULL, cmd_ap_get_mac_address);
12858 	sigma_dut_reg_cmd("ap_set_pmf", NULL, cmd_ap_set_pmf);
12859 	sigma_dut_reg_cmd("ap_set_hs2", NULL, cmd_ap_set_hs2);
12860 	sigma_dut_reg_cmd("ap_set_rfeature", NULL, cmd_ap_set_rfeature);
12861 	sigma_dut_reg_cmd("ap_nfc_action", NULL, cmd_ap_nfc_action);
12862 	sigma_dut_reg_cmd("ap_wps_read_pin", NULL, cmd_ap_wps_read_pin);
12863 	sigma_dut_reg_cmd("ap_wps_enter_pin", NULL, cmd_ap_wps_enter_pin);
12864 	sigma_dut_reg_cmd("ap_wps_set_pbc", NULL, cmd_ap_wps_set_pbc);
12865 	sigma_dut_reg_cmd("ap_get_parameter", NULL, cmd_ap_get_parameter);
12866 	sigma_dut_reg_cmd("AccessPoint", NULL, cmd_accesspoint);
12867 	sigma_dut_reg_cmd("ap_preset_testparameters", NULL,
12868 			  cmd_ap_preset_testparameters);
12869 }
12870