1 /*
2 * Sigma Control API DUT (station/AP)
3 * Copyright (c) 2010-2011, Atheros Communications, Inc.
4 * Copyright (c) 2011-2017, Qualcomm Atheros, Inc.
5 * Copyright (c) 2018-2019, The Linux Foundation
6 * All Rights Reserved.
7 * Licensed under the Clear BSD license. See README for more details.
8 */
9
10 #include "sigma_dut.h"
11 #include <sys/stat.h>
12 #include <sys/wait.h>
13 #include <sys/utsname.h>
14 #include <sys/ioctl.h>
15 #ifdef __linux__
16 #include <limits.h>
17 #include <dirent.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 #endif /* __linux__ */
22 #ifdef __QNXNTO__
23 #include <ifaddrs.h>
24 #include <net/if_dl.h>
25 #endif /* __QNXNTO__ */
26 #include "wpa_ctrl.h"
27 #include "wpa_helpers.h"
28 #ifdef ANDROID
29 #include <hardware_legacy/wifi.h>
30 #include <grp.h>
31 #include <pwd.h>
32 #endif /* ANDROID */
33
34 /* Temporary files for ap_send_addba_req */
35 #define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
36 #define VI_QOS_FILE "/tmp/vi-qos.txt"
37 #define VI_QOS_REFFILE "/etc/vi-qos.txt"
38
39 /* Configuration file name on Android */
40 #ifndef ANDROID_CONFIG_FILE
41 #define ANDROID_CONFIG_FILE "/data/misc/wifi/hostapd.conf"
42 #endif /* ANDROID_CONFIG_FILE */
43 /* Maximum length of the line in the configuration file */
44 #define MAX_CONF_LINE_LEN (156)
45
46 #ifndef SIGMA_DUT_HOSTAPD_PID_FILE
47 #define SIGMA_DUT_HOSTAPD_PID_FILE "/tmp/sigma_dut-ap-hostapd.pid"
48 #endif /* SIGMA_DUT_HOSTAPD_PID_FILE */
49
50 /* The following is taken from Hotspot 2.0 testplan Appendix B.1 */
51 #define ANQP_VENUE_NAME_1 "02019c0002083d656e6757692d466920416c6c69616e63650a3239383920436f7070657220526f61640a53616e746120436c6172612c2043412039353035312c205553415b63686957692d4669e88194e79b9fe5ae9ee9aa8ce5aea40ae4ba8ce4b99de585abe4b99de5b9b4e5ba93e69f8fe8b7af0ae59ca3e5858be68b89e68b892c20e58aa0e588a9e7a68fe5b0bce4ba9a39353035312c20e7be8ee59bbd"
52 #define ANQP_VENUE_NAME_1_CHI "P\"\x63\x68\x69\x3a\x57\x69\x2d\x46\x69\xe8\x81\x94\xe7\x9b\x9f\xe5\xae\x9e\xe9\xaa\x8c\xe5\xae\xa4\\n\xe4\xba\x8c\xe4\xb9\x9d\xe5\x85\xab\xe4\xb9\x9d\xe5\xb9\xb4\xe5\xba\x93\xe6\x9f\x8f\xe8\xb7\xaf\\n\xe5\x9c\xa3\xe5\x85\x8b\xe6\x8b\x89\xe6\x8b\x89\x2c\x20\xe5\x8a\xa0\xe5\x88\xa9\xe7\xa6\x8f\xe5\xb0\xbc\xe4\xba\x9a\x39\x35\x30\x35\x31\x2c\x20\xe7\xbe\x8e\xe5\x9b\xbd\""
53 #define ANQP_IP_ADDR_TYPE_1 "060101000c"
54 #define ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "dddd2700506f9a11030011656e6757692d466920416c6c69616e63650e63686957692d4669e88194e79b9f"
55 #define ANQP_HS20_WAN_METRICS_1 "dddd1300506f9a11040001c40900008001000000000000"
56 #define ANQP_HS20_CONNECTION_CAPABILITY_1 "dddd3200506f9a1105000100000006140001061600000650000106bb010106bb060006c4130011f4010111c413001194110132000001"
57 #define QOS_MAP_SET_1 "53,2,22,6,8,15,0,7,255,255,16,31,32,39,255,255,40,47,255,255"
58 #define QOS_MAP_SET_2 "8,15,0,7,255,255,16,31,32,39,255,255,40,47,48,63"
59
60 #define ADV_OF_CHARGE_1 \
61 "bc01000000d200454e475553443c3f786d6c2076657273696f6e3d22312e30222065" \
62 "6e636f64696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f77" \
63 "77772e77692d66692e6f72672f73706563696669636174696f6e732f686f7473706f7432646f" \
64 "74302f76312e302f616f637069223e3c4465736372697074696f6e3e57692d46692061636365" \
65 "737320666f72203120686f75722c207768696c6520796f752077616974206174207468652067" \
66 "6174652c2024302e39393c2f4465736372697074696f6e3e3c2f506c616e3ee3004652414341" \
67 "443c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f" \
68 "3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77692d66692e6f72672f737065" \
69 "63696669636174696f6e732f686f7473706f7432646f74302f76312e302f616f637069223e3c" \
70 "4465736372697074696f6e3e416363c3a8732057692d46692070656e64616e74203120686575" \
71 "72652c2070656e64616e742071756520766f757320617474656e64657a20c3a0206c6120706f" \
72 "7274652c20302c393920243c2f4465736372697074696f6e3e3c2f506c616e3ea101010000c7" \
73 "00454e475553443c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d2255" \
74 "54462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77692d66692e6f" \
75 "72672f73706563696669636174696f6e732f686f7473706f7432646f74302f76312e302f616f" \
76 "637069223e3c4465736372697074696f6e3e446f776e6c6f616420766964656f7320666f7220" \
77 "796f757220666c696768742c2024322e393920666f7220313047423c2f446573637269707469" \
78 "6f6e3e3c2f506c616e3ed3004652414341443c3f786d6c2076657273696f6e3d22312e302220" \
79 "656e636f64696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f" \
80 "7777772e77692d66692e6f72672f73706563696669636174696f6e732f686f7473706f743264" \
81 "6f74302f76312e302f616f637069223e3c4465736372697074696f6e3e54c3a96cc3a9636861" \
82 "7267657a2064657320766964c3a96f7320706f757220766f74726520766f6c2c20322c393920" \
83 "2420706f757220313020476f3c2f4465736372697074696f6e3e3c2f506c616e3ee40003002b" \
84 "736572766963652d70726f76696465722e636f6d3b66656465726174696f6e2e6578616d706c" \
85 "652e636f6db400454e475553443c3f786d6c2076657273696f6e3d22312e302220656e636f64" \
86 "696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77" \
87 "692d66692e6f72672f73706563696669636174696f6e732f686f7473706f7432646f74302f76" \
88 "312e302f616f637069223e3c4465736372697074696f6e3e46726565207769746820796f7572" \
89 "20737562736372697074696f6e213c2f4465736372697074696f6e3e3c2f506c616e3e"
90
91 #define SAE_PK_KEY_1 \
92 "MHcCAQEEIDNNDttjdQmLVyr1DOrWiapbMt15LDn4hnMLIXrBLAN+oAoGCCqGSM49AwEHoUQDQgAENAv4e3IlpYkqQjc/9KM4O4Athh6iY25wlT8Gdg+EhR7yoMR03nHri6QaaLogXxTsa9qGyXj1K9G8DEOyHMQCbg=="
93 #define SAE_PK_KEY_2 \
94 "MHcCAQEEIF4LGkE30VdIeJe1ZVOo3TmkvT9RKRx30+yOx/9nhQY9oAoGCCqGSM49AwEHoUQDQgAE3PNzZH4m41vT5q6W7p5Q6B9owz5MHLwCUnpK84YRTVDLKKZXOPYxSHRh/O5Kz0OnVeOq1QfjEZRhNH79XhHCQQ=="
95 #define SAE_PK_KEY_P256 \
96 "MHcCAQEEIAJIGlfnteonDb7rQyP/SGQjwzrZAnfrXIm4280VWajYoAoGCCqGSM49AwEHoUQDQgAEeRkstKQV+FSAMqBayqFknn2nAQsdsh/MhdX6tiHOTAFin/sUMFRMyspPtIu7YvlKdsexhI0jPVhaYZn1jKWhZg=="
97 #define SAE_PK_KEY_P384 \
98 "MIGkAgEBBDB7iMoR2se0sWriXYCEsiLd8WFEblxWlCqb5kD7JgZfQjjylGwqOgIE7JShOOjE0Z2gBwYFK4EEACKhZANiAATntlmb7rlUopsaA/w5Uhut9jLlcY2sJdT6IzCdQ8uzuxk9Fgh+dwS25pd+lWC91rQ7kyjfZRpoePhwQasnjGRAl6rH2VWI/XtI5Q9iFXbhEaWEdKzWjetd6B5OPWy/BQg="
99 #define SAE_PK_KEY_P521 \
100 "MIHcAgEBBEIBuNKSnOQY5ZVdBgWiXcL1Gr/W+VCw69nOte1gT4sqdVeV3grCl5HJxogVG2LFdtnEDLJrs0AtFoFN9nWnIuMu+ZWgBwYFK4EEACOhgYkDgYYABADuDQkFO2102xXwNnoGpBU+13kNuxZ/gwy8+G0UG75h6iiTqNWRaQIpSWgTmPNER7Ubb7etyXaoOTnsq4v4f9m8wgDt2LMZptHvUkHCq522rRK43ITmCayelbHWY1FhhAE1ETXRItSV8nLymjliEtjdfP45dsr25ySlkSaVCBNUFrAtfw=="
101
102 /*
103 * MTU for Ethernet need to take into account 8-byte SNAP header
104 * to be added when encapsulating Ethernet frame into 802.11.
105 */
106 #ifndef IEEE80211_MAX_DATA_LEN_DMG
107 #define IEEE80211_MAX_DATA_LEN_DMG 7920
108 #endif /* IEEE80211_MAX_DATA_LEN_DMG */
109 #ifndef IEEE80211_SNAP_LEN_DMG
110 #define IEEE80211_SNAP_LEN_DMG 8
111 #endif /* IEEE80211_SNAP_LEN_DMG */
112
113 extern char *sigma_wpas_ctrl;
114 extern char *sigma_hapd_ctrl;
115 extern char *ap_inet_addr;
116 extern char *ap_inet_mask;
117 extern char *sigma_radio_ifname[];
118
119 static int ath_ap_start_hostapd(struct sigma_dut *dut);
120 static void ath_ap_set_params(struct sigma_dut *dut);
121 static int kill_process(struct sigma_dut *dut, char *proc_name,
122 unsigned char is_proc_instance_one, int sig);
123
124
fwtest_cmd_wrapper(struct sigma_dut * dut,const char * arg,const char * ifname)125 static int fwtest_cmd_wrapper(struct sigma_dut *dut, const char *arg,
126 const char *ifname)
127 {
128 int ret = -1;
129
130 if (strcmp(dut->device_driver, "ath11k") == 0)
131 ret = run_system_wrapper(dut, "ath11k-fwtest -i %s %s",
132 ifname, arg);
133
134 return ret;
135 }
136
137
ap_ft_enabled(struct sigma_dut * dut)138 static int ap_ft_enabled(struct sigma_dut *dut)
139 {
140 return dut->ap_ft_oa == 1 ||
141 dut->ap_ft_ds == VALUE_ENABLED ||
142 dut->ap_key_mgmt == AP_WPA2_FT_EAP ||
143 dut->ap_key_mgmt == AP_WPA2_FT_PSK ||
144 dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP ||
145 (dut->ap_akm_values &
146 ((1 << AKM_FT_EAP) |
147 (1 << AKM_FT_PSK) |
148 (1 << AKM_FT_SAE) |
149 (1 << AKM_FT_SUITE_B) |
150 (1 << AKM_FT_FILS_SHA256) |
151 (1 << AKM_FT_FILS_SHA384)));
152 }
153
154
cmd_ap_ca_version(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)155 static enum sigma_cmd_result cmd_ap_ca_version(struct sigma_dut *dut,
156 struct sigma_conn *conn,
157 struct sigma_cmd *cmd)
158 {
159 /* const char *name = get_param(cmd, "NAME"); */
160 send_resp(dut, conn, SIGMA_COMPLETE, "version,1.0");
161 return 0;
162 }
163
164
kill_hostapd_process_pid(struct sigma_dut * dut)165 static void kill_hostapd_process_pid(struct sigma_dut *dut)
166 {
167 FILE *f;
168 int pid, res;
169 char path[100];
170 int count;
171
172 f = fopen(SIGMA_DUT_HOSTAPD_PID_FILE, "r");
173 if (!f)
174 return;
175 res = fscanf(f, "%d", &pid);
176 fclose(f);
177 if (res != 1)
178 return;
179 sigma_dut_print(dut, DUT_MSG_INFO, "Killing hostapd pid %d", pid);
180 kill(pid, SIGTERM);
181 snprintf(path, sizeof(path), "/proc/%d", pid);
182 for (count = 0; count < 20 && file_exists(path); count++)
183 usleep(100000);
184 }
185
186
get_hwaddr(const char * ifname,unsigned char * hwaddr)187 int get_hwaddr(const char *ifname, unsigned char *hwaddr)
188 {
189 #ifndef __QNXNTO__
190 struct ifreq ifr;
191 int s;
192
193 s = socket(AF_INET, SOCK_DGRAM, 0);
194 if (s < 0)
195 return -1;
196 memset(&ifr, 0, sizeof(ifr));
197 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
198 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
199 perror("ioctl");
200 close(s);
201 return -1;
202 }
203 close(s);
204 memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
205 #else /* __QNXNTO__ */
206 struct ifaddrs *ifaddrshead = NULL;
207 int found = 0;
208 struct ifaddrs *temp_ifap = NULL;
209 struct sockaddr_dl *sdl = NULL;
210
211 if (getifaddrs(&ifaddrshead) != 0) {
212 perror("getifaddrs failed");
213 return -1;
214 }
215
216 for (temp_ifap = ifaddrshead; ifaddrshead && !found;
217 ifaddrshead = ifaddrshead->ifa_next) {
218 if (ifaddrshead->ifa_addr->sa_family == AF_LINK &&
219 strcmp(ifaddrshead->ifa_name, ifname) == 0) {
220 found = 1;
221 sdl = (struct sockaddr_dl *) ifaddrshead->ifa_addr;
222 if (sdl)
223 memcpy(hwaddr, LLADDR(sdl), sdl->sdl_alen);
224 }
225 }
226
227 if (temp_ifap)
228 freeifaddrs(temp_ifap);
229
230 if (!found) {
231 perror("Failed to get the interface");
232 return -1;
233 }
234 #endif /* __QNXNTO__ */
235 return 0;
236 }
237
238
ath_ap_set_group_id(struct sigma_dut * dut,const char * ifname,const char * val)239 static void ath_ap_set_group_id(struct sigma_dut *dut, const char *ifname,
240 const char *val)
241 {
242 char buf[60];
243
244 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 55 %d",
245 ifname, atoi(val));
246 if (system(buf) != 0) {
247 sigma_dut_print(dut, DUT_MSG_ERROR,
248 "wifitool ap_group_id failed");
249 }
250 }
251
252
ath_set_cts_width(struct sigma_dut * dut,const char * ifname,const char * val)253 void ath_set_cts_width(struct sigma_dut *dut, const char *ifname,
254 const char *val)
255 {
256 char buf[60];
257
258 /* TODO: Enable support for other values */
259 if (strcasecmp(val, "40") == 0) {
260 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 1",
261 ifname);
262 if (system(buf) != 0) {
263 sigma_dut_print(dut, DUT_MSG_ERROR,
264 "wifitool cts_width failed");
265 }
266 snprintf(buf, sizeof(buf),
267 "athdiag --set --address=0x10024 --val=0xd90b8a14");
268 if (system(buf) != 0) {
269 sigma_dut_print(dut, DUT_MSG_ERROR,
270 "disabling phy restart failed");
271 }
272 } else {
273 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported CTS_WIDTH");
274 }
275 }
276
277
ath_config_dyn_bw_sig(struct sigma_dut * dut,const char * ifname,const char * val)278 void ath_config_dyn_bw_sig(struct sigma_dut *dut, const char *ifname,
279 const char *val)
280 {
281 char buf[60];
282
283 if (strcasecmp(val, "enable") == 0) {
284 dut->ap_dyn_bw_sig = VALUE_ENABLED;
285 run_iwpriv(dut, ifname, "cwmenable 1");
286
287 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 96 1",
288 ifname);
289 if (system(buf) != 0) {
290 sigma_dut_print(dut, DUT_MSG_ERROR,
291 "disabling RTS from rate control logic failed");
292 }
293 } else if (strcasecmp(val, "disable") == 0) {
294 dut->ap_dyn_bw_sig = VALUE_DISABLED;
295 run_iwpriv(dut, ifname, "cwmenable 0");
296 } else {
297 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported DYN_BW_SGL");
298 }
299 }
300
301
wcn_config_ap_ldpc(struct sigma_dut * dut,const char * ifname)302 static void wcn_config_ap_ldpc(struct sigma_dut *dut, const char *ifname)
303 {
304 if (dut->ap_ldpc == VALUE_NOT_SET)
305 return;
306 run_iwpriv(dut, ifname, "ldpc %d", dut->ap_ldpc != VALUE_DISABLED);
307 }
308
309
wcn_config_ap_fils_dscv(struct sigma_dut * dut,const char * ifname)310 static int wcn_config_ap_fils_dscv(struct sigma_dut *dut, const char *ifname)
311 {
312 #ifdef NL80211_SUPPORT
313 uint8_t enable_fils_dscv = dut->ap_filsdscv == VALUE_ENABLED;
314
315 if (dut->ap_filsdscv == VALUE_NOT_SET)
316 return 0;
317
318 return wcn_wifi_test_config_set_u8(
319 dut, ifname,
320 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FILS_DISCOVERY_FRAMES_TX,
321 enable_fils_dscv);
322 #else /* NL80211_SUPPORT */
323 sigma_dut_print(dut, DUT_MSG_ERROR,
324 "FILS Discovery frames configuration can't be set without NL80211_SUPPORT defined");
325 if (dut->ap_filsdscv == VALUE_NOT_SET)
326 return 0;
327 return -1;
328 #endif /* NL80211_SUPPORT */
329 }
330
331
mac80211_config_rts_force(struct sigma_dut * dut,const char * ifname,const char * val)332 static void mac80211_config_rts_force(struct sigma_dut *dut, const char *ifname,
333 const char *val)
334 {
335 char buf[60];
336 char fname[128], path[128], *pos;
337 ssize_t res;
338
339 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
340 ifname);
341 if (res < 0 || res >= sizeof(fname))
342 return;
343
344 res = readlink(fname, path, sizeof(path));
345 if (res < 0)
346 return;
347
348 if (res >= (int) sizeof(path))
349 res = sizeof(path) - 1;
350 path[res] = '\0';
351
352 pos = strrchr(path, '/');
353 if (!pos)
354 pos = path;
355 else
356 pos++;
357
358 if (strcasecmp(val, "enable") == 0) {
359 dut->ap_sig_rts = VALUE_ENABLED;
360 res = snprintf(buf, sizeof(buf), "iw %s set rts 64", pos);
361 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
362 sigma_dut_print(dut, DUT_MSG_ERROR,
363 "iw set rts 64 failed");
364 }
365 } else if (strcasecmp(val, "disable") == 0) {
366 dut->ap_sig_rts = VALUE_DISABLED;
367 res = snprintf(buf, sizeof(buf), "iw %s set rts 2347", pos);
368 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
369 sigma_dut_print(dut, DUT_MSG_ERROR,
370 "iw rts 2347 failed");
371 }
372 } else {
373 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE");
374 }
375
376 }
377
378
ath_config_rts_force(struct sigma_dut * dut,const char * ifname,const char * val)379 static void ath_config_rts_force(struct sigma_dut *dut, const char *ifname,
380 const char *val)
381 {
382 char buf[60];
383
384 if (strcasecmp(val, "enable") == 0) {
385 dut->ap_sig_rts = VALUE_ENABLED;
386 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname);
387 if (system(buf) != 0) {
388 sigma_dut_print(dut, DUT_MSG_ERROR,
389 "iwconfig rts 64 failed");
390 }
391 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 100 1",
392 ifname);
393 if (system(buf) != 0) {
394 sigma_dut_print(dut, DUT_MSG_ERROR,
395 "wifitool beeliner_fw_test 100 1 failed");
396 }
397 } else if (strcasecmp(val, "disable") == 0) {
398 dut->ap_sig_rts = VALUE_DISABLED;
399 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname);
400 if (system(buf) != 0) {
401 sigma_dut_print(dut, DUT_MSG_ERROR,
402 "iwconfig rts 2347 failed");
403 }
404 } else {
405 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE");
406 }
407 }
408
409
ath_radio(struct sigma_dut * dut,const char * val)410 static void ath_radio(struct sigma_dut *dut, const char *val)
411 {
412 if (strcasecmp(val, "on") == 0) {
413 if (dut->ap_interface_5g == 1) {
414 run_system(dut, "uci set wireless.wifi0.disabled=0");
415 } else if (dut->ap_interface_2g == 1) {
416 run_system(dut, "uci set wireless.wifi1.disabled=0");
417 } else {
418 run_system(dut, "uci set wireless.wifi0.disabled=0");
419 run_system(dut, "uci set wireless.wifi1.disabled=0");
420 }
421 run_system(dut, "uci commit");
422 run_system(dut, "wifi down");
423 run_system(dut, "wifi up");
424 } else if (strcasecmp(val, "off") == 0) {
425 if (dut->ap_interface_5g == 1) {
426 run_system(dut, "uci set wireless.wifi0.disabled=1");
427 } else if (dut->ap_interface_2g == 1) {
428 run_system(dut, "uci set wireless.wifi1.disabled=1");
429 } else {
430 run_system(dut, "uci set wireless.wifi0.disabled=1");
431 run_system(dut, "uci set wireless.wifi1.disabled=1");
432 }
433 run_system(dut, "uci commit");
434 run_system(dut, "wifi down");
435 run_system(dut, "wifi up");
436 }
437 }
438
439
deauth_disassoc(struct sigma_dut * dut,const char * ifname,const char * val)440 static void deauth_disassoc(struct sigma_dut *dut, const char *ifname,
441 const char *val)
442 {
443 if (strcasecmp(val, "disable") == 0)
444 run_iwpriv(dut, ifname, "stealthdown 1");
445 }
446
447
ath_set_txpower(struct sigma_dut * dut,const char * ifname,const char * val)448 static void ath_set_txpower(struct sigma_dut *dut, const char *ifname,
449 const char *val)
450 {
451 char buf[60];
452
453 if (strcasecmp(val, "high") == 0)
454 snprintf(buf, sizeof(buf), "iwconfig %s txpower 29", ifname);
455 else if (strcasecmp(val, "low") == 0)
456 snprintf(buf, sizeof(buf), "iwconfig %s txpower 1", ifname);
457 else
458 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported txpower");
459
460 if (system(buf) != 0)
461 sigma_dut_print(dut, DUT_MSG_ERROR, "setting txpower failed");
462 }
463
464
get_mode(const char * str)465 static enum ap_mode get_mode(const char *str)
466 {
467 if (strcasecmp(str, "11a") == 0)
468 return AP_11a;
469 else if (strcasecmp(str, "11g") == 0)
470 return AP_11g;
471 else if (strcasecmp(str, "11b") == 0)
472 return AP_11b;
473 else if (strcasecmp(str, "11na") == 0)
474 return AP_11na;
475 else if (strcasecmp(str, "11ng") == 0)
476 return AP_11ng;
477 else if (strcasecmp(str, "11ac") == 0 || strcasecmp(str, "ac") == 0)
478 return AP_11ac;
479 else if (strcasecmp(str, "11ad") == 0)
480 return AP_11ad;
481 else if (strcasecmp(str, "11ax") == 0)
482 return AP_11ax;
483 else
484 return AP_inval;
485 }
486
487
run_hostapd_cli(struct sigma_dut * dut,char * buf)488 static int run_hostapd_cli(struct sigma_dut *dut, char *buf)
489 {
490 char command[1000];
491 const char *bin;
492 enum driver_type drv = get_driver_type(dut);
493 char *sigma_hapd_file = sigma_hapd_ctrl;
494
495 if (file_exists("hostapd_cli"))
496 bin = "./hostapd_cli";
497 else if (file_exists("../../hostapd/hostapd_cli"))
498 bin = "../../hostapd/hostapd_cli";
499 else
500 bin = "hostapd_cli";
501
502 if (drv == DRIVER_OPENWRT && sigma_hapd_ctrl == NULL) {
503 sigma_hapd_file = "/var/run/hostapd-wifi0";
504
505 if (sigma_radio_ifname[0] &&
506 strcmp(sigma_radio_ifname[0], "wifi1") == 0)
507 sigma_hapd_file = "/var/run/hostapd-wifi1";
508 else if (sigma_radio_ifname[0] &&
509 strcmp(sigma_radio_ifname[0], "wifi2") == 0)
510 sigma_hapd_file = "/var/run/hostapd-wifi2";
511 }
512
513 if (sigma_hapd_file)
514 snprintf(command, sizeof(command), "%s -p %s %s",
515 bin, sigma_hapd_file, buf);
516 else
517 snprintf(command, sizeof(command), "%s %s", bin, buf);
518 return run_system(dut, command);
519 }
520
521
ath_set_lci_config(struct sigma_dut * dut,const char * val,struct sigma_cmd * cmd)522 static int ath_set_lci_config(struct sigma_dut *dut, const char *val,
523 struct sigma_cmd *cmd)
524 {
525 FILE *f;
526 int i;
527
528 f = fopen("/tmp/lci_cfg.txt", "w");
529 if (!f) {
530 sigma_dut_print(dut, DUT_MSG_ERROR,
531 "Failed to open /tmp/lci_cfg.txt");
532 return -1;
533 }
534
535 for (i = 2; i < cmd->count; i++)
536 fprintf(f, "%s = %s \n", cmd->params[i], cmd->values[i]);
537 fprintf(f, "\n");
538 fclose(f);
539
540 return 0;
541 }
542
543
set_ap_country_code(struct sigma_dut * dut)544 static void set_ap_country_code(struct sigma_dut *dut)
545 {
546 #if defined(ANDROID) || defined(LINUX_EMBEDDED)
547 char buf[256];
548
549 if (dut->ap_countrycode[0]) {
550 snprintf(buf, sizeof(buf), "DRIVER COUNTRY %s",
551 dut->ap_countrycode);
552 if (wpa_command(get_station_ifname(dut), buf) < 0)
553 sigma_dut_print(dut, DUT_MSG_ERROR,
554 "Failed to set country code");
555 else
556 sigma_dut_print(dut, DUT_MSG_INFO,
557 "Successfully set country code to %s",
558 dut->ap_countrycode);
559 }
560 #endif
561 }
562
563
set_vht_mcsmap_nss(struct sigma_dut * dut,int nss,int mcs)564 static void set_vht_mcsmap_nss(struct sigma_dut *dut, int nss, int mcs)
565 {
566 switch (nss) {
567 case 1:
568 switch (mcs) {
569 case 7:
570 dut->ap_vhtmcs_map = 0xfffc;
571 break;
572 case 8:
573 dut->ap_vhtmcs_map = 0xfffd;
574 break;
575 case 9:
576 dut->ap_vhtmcs_map = 0xfffe;
577 break;
578 default:
579 dut->ap_vhtmcs_map = 0xfffe;
580 break;
581 }
582 break;
583 case 2:
584 switch (mcs) {
585 case 7:
586 dut->ap_vhtmcs_map = 0xfff0;
587 break;
588 case 8:
589 dut->ap_vhtmcs_map = 0xfff5;
590 break;
591 case 9:
592 dut->ap_vhtmcs_map = 0xfffa;
593 break;
594 default:
595 dut->ap_vhtmcs_map = 0xfffa;
596 break;
597 }
598 break;
599 case 3:
600 switch (mcs) {
601 case 7:
602 dut->ap_vhtmcs_map = 0xffc0;
603 break;
604 case 8:
605 dut->ap_vhtmcs_map = 0xffd5;
606 break;
607 case 9:
608 dut->ap_vhtmcs_map = 0xffea;
609 break;
610 default:
611 dut->ap_vhtmcs_map = 0xffea;
612 break;
613 }
614 default:
615 dut->ap_vhtmcs_map = 0xffea;
616 break;
617 }
618 }
619
620
621 /* Get 2*nss bitmask */
622 /* We are trying to pack 2-bit MCS values per NSS in a 16-bit wide field.
623 * IEEE P802.11ax/D5.0, 9.4.2.247.4 supported HE-MCS And NSS Set field
624 * defines the following format for the 16 bit value. */
625
626 #define HE_GET_MCS_NSS_PACK_MASK(nss) ((1 << ((nss) << 1)) - 1)
627
he_reset_mcs_values_for_unsupported_ss(uint8_t * mcsnssmap,uint8_t nss)628 static void he_reset_mcs_values_for_unsupported_ss(uint8_t *mcsnssmap,
629 uint8_t nss)
630 {
631 uint8_t nssmask;
632
633 if (nss <= 4) {
634 nssmask = ~HE_GET_MCS_NSS_PACK_MASK(nss);
635 mcsnssmap[0] |= nssmask;
636 mcsnssmap[1] = 0xff;
637 } else if (nss > 4 && nss <= 8) {
638 nssmask = ~HE_GET_MCS_NSS_PACK_MASK(nss - 4);
639 mcsnssmap[0] &= 0xff;
640 mcsnssmap[1] |= nssmask;
641 }
642 }
643
644
get_he_mcs_nssmap(uint8_t * mcsnssmap,uint8_t nss,uint8_t mcs)645 static void get_he_mcs_nssmap(uint8_t *mcsnssmap, uint8_t nss,
646 uint8_t mcs)
647 {
648 switch (mcs) {
649 case 11:
650 mcsnssmap[0] = 0xaa;
651 mcsnssmap[1] = 0xaa;
652 break;
653 case 9:
654 mcsnssmap[0] = 0x55;
655 mcsnssmap[1] = 0x55;
656 break;
657 case 7:
658 mcsnssmap[0] = 0x0;
659 mcsnssmap[1] = 0x0;
660 break;
661 }
662 he_reset_mcs_values_for_unsupported_ss(mcsnssmap, nss);
663 }
664
665
cmd_ap_set_wireless(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)666 static enum sigma_cmd_result cmd_ap_set_wireless(struct sigma_dut *dut,
667 struct sigma_conn *conn,
668 struct sigma_cmd *cmd)
669 {
670 /* const char *name = get_param(cmd, "NAME"); */
671 /* const char *ifname = get_param(cmd, "INTERFACE"); */
672 const char *val;
673 unsigned int wlan_tag = 1;
674 const char *ifname = get_main_ifname(dut);
675 char buf[128];
676
677 /* Allow program to be overridden if specified in the ap_set_wireless
678 * to support some 60 GHz test scripts where the program may be 60 GHz
679 * or WPS. */
680 val = get_param(cmd, "PROGRAM");
681 if (val)
682 dut->program = sigma_program_to_enum(val);
683
684 val = get_param(cmd, "WLAN_TAG");
685 if (val) {
686 wlan_tag = atoi(val);
687 if (wlan_tag < 1 || wlan_tag > 3) {
688 /*
689 * The only valid WLAN Tags as of now as per the latest
690 * WFA scripts are 1, 2, and 3.
691 */
692 send_resp(dut, conn, SIGMA_INVALID,
693 "errorCode,Invalid WLAN_TAG");
694 return STATUS_SENT;
695 }
696 }
697
698 val = get_param(cmd, "Interface");
699 if (val) {
700 if (strcasecmp(val, "5G") == 0)
701 dut->ap_interface_5g = 1;
702 else
703 dut->ap_interface_2g = 1;
704
705 if (dut->ap_interface_5g && dut->ap_interface_2g)
706 dut->ap_is_dual = 1;
707 }
708
709 val = get_param(cmd, "CountryCode");
710 if (val) {
711 if (strlen(val) > sizeof(dut->ap_countrycode) - 1)
712 return INVALID_SEND_STATUS;
713 snprintf(dut->ap_countrycode, sizeof(dut->ap_countrycode),
714 "%s", val);
715
716 /*
717 * Regdomain self-managed driver does not accept hostapd country
718 * code setting in all cases. Try to use wpa_supplicant DRIVER
719 * command first to set the driver to a specific country code
720 * before starting AP functionality. This is targeting cases
721 * where wpa_supplicant is running on the device as well for
722 * non-AP mode functionality.
723 */
724 if (get_driver_type(dut) == DRIVER_LINUX_WCN)
725 set_ap_country_code(dut);
726 }
727
728 val = get_param(cmd, "regulatory_mode");
729 if (val) {
730 if (strcasecmp(val, "11d") == 0 || strcasecmp(val, "11h") == 0)
731 dut->ap_regulatory_mode = AP_80211D_MODE_ENABLED;
732 }
733
734 val = get_param(cmd, "SSID");
735 if (val) {
736 if (strlen(val) > sizeof(dut->ap_ssid) - 1)
737 return INVALID_SEND_STATUS;
738
739 if (wlan_tag == 1) {
740 /*
741 * If tag is not specified, it is deemed to be 1.
742 * Hence tag of 1 is a special case and the values
743 * corresponding to wlan-tag=1 are stored separately
744 * from the values corresponding tags 2 and 3.
745 * This approach minimises the changes to existing code
746 * since most of the sigma_dut code does not deal with
747 * WLAN-TAG CAPI variable.
748 */
749 snprintf(dut->ap_ssid,
750 sizeof(dut->ap_ssid), "%s", val);
751 } else {
752 snprintf(dut->ap_tag_ssid[wlan_tag - 2],
753 sizeof(dut->ap_tag_ssid[wlan_tag - 2]),
754 "%s", val);
755 }
756 }
757
758 val = get_param(cmd, "CHANNEL");
759 if (val) {
760 const char *pos;
761 dut->ap_channel = atoi(val);
762 pos = strchr(val, ';');
763 if (pos) {
764 pos++;
765 dut->ap_channel_1 = atoi(pos);
766 }
767 }
768
769 /* Overwrite the AP channel with DFS channel if configured */
770 val = get_param(cmd, "dfs_chan");
771 if (val) {
772 dut->ap_channel = atoi(val);
773 }
774
775 val = get_param(cmd, "dfs_mode");
776 if (val) {
777 if (strcasecmp(val, "Enable") == 0)
778 dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
779 else if (strcasecmp(val, "Disable") == 0)
780 dut->ap_dfs_mode = AP_DFS_MODE_DISABLED;
781 else
782 sigma_dut_print(dut, DUT_MSG_ERROR,
783 "Unsupported dfs_mode value: %s", val);
784 }
785
786 val = get_param(cmd, "MODE");
787 if (val) {
788 char *str, *pos;
789
790 str = strdup(val);
791 if (str == NULL)
792 return INVALID_SEND_STATUS;
793 pos = strchr(str, ';');
794 if (pos)
795 *pos++ = '\0';
796
797 dut->ap_is_dual = 0;
798 dut->ap_mode = get_mode(str);
799 if (dut->ap_mode == AP_inval) {
800 send_resp(dut, conn, SIGMA_INVALID,
801 "errorCode,Unsupported MODE");
802 free(str);
803 return STATUS_SENT;
804 }
805 if (dut->ap_mode == AP_11ac && dut->ap_80plus80 != 1)
806 dut->ap_chwidth = AP_80;
807
808 if (pos) {
809 dut->ap_mode_1 = get_mode(pos);
810 if (dut->ap_mode_1 == AP_inval) {
811 send_resp(dut, conn, SIGMA_INVALID,
812 "errorCode,Unsupported MODE");
813 free(str);
814 return STATUS_SENT;
815 }
816 if (dut->ap_mode_1 == AP_11ac)
817 dut->ap_chwidth_1 = AP_80;
818 dut->ap_is_dual = 1;
819 }
820
821 free(str);
822 } else if (dut->ap_mode == AP_inval) {
823 if (dut->ap_channel <= 11)
824 dut->ap_mode = AP_11ng;
825 else if (dut->program == PROGRAM_VHT)
826 dut->ap_mode = AP_11ac;
827 else
828 dut->ap_mode = AP_11na;
829 }
830
831 /* Override the AP mode in case of 60 GHz */
832 if (dut->program == PROGRAM_60GHZ) {
833 dut->ap_mode = AP_11ad;
834 /* Workaround to force channel 2 if not specified */
835 if (!dut->ap_channel)
836 dut->ap_channel = 2;
837 }
838
839 switch (dut->ap_mode) {
840 case AP_11g:
841 case AP_11b:
842 case AP_11ng:
843 dut->use_5g = 0;
844 break;
845 case AP_11a:
846 case AP_11na:
847 case AP_11ac:
848 dut->use_5g = 1;
849 break;
850 case AP_11ax:
851 if (dut->ap_channel >= 1 && dut->ap_channel <= 14)
852 dut->use_5g = 0;
853 else if (dut->ap_channel >= 36 && dut->ap_channel <= 171)
854 dut->use_5g = 1;
855 break;
856 case AP_11ad:
857 case AP_inval:
858 break;
859 }
860
861 val = get_param(cmd, "WME");
862 if (val) {
863 if (strcasecmp(val, "on") == 0)
864 dut->ap_wme = AP_WME_ON;
865 else if (strcasecmp(val, "off") == 0)
866 dut->ap_wme = AP_WME_OFF;
867 else
868 sigma_dut_print(dut, DUT_MSG_ERROR,
869 "Unsupported WME value: %s", val);
870 }
871
872 val = get_param(cmd, "WMMPS");
873 if (val) {
874 if (strcasecmp(val, "on") == 0)
875 dut->ap_wmmps = AP_WMMPS_ON;
876 else if (strcasecmp(val, "off") == 0)
877 dut->ap_wmmps = AP_WMMPS_OFF;
878 else
879 sigma_dut_print(dut, DUT_MSG_ERROR,
880 "Unsupported WMMPS value: %s", val);
881 }
882
883 val = get_param(cmd, "RTS");
884 if (val)
885 dut->ap_rts = atoi(val);
886
887 val = get_param(cmd, "FRGMNT");
888 if (val)
889 dut->ap_frgmnt = atoi(val);
890
891 /* TODO: PWRSAVE */
892
893 val = get_param(cmd, "BCNINT");
894 if (val)
895 dut->ap_bcnint = atoi(val);
896
897 val = get_param(cmd, "RADIO");
898 if (val) {
899 enum driver_type drv = get_driver_type(dut);
900
901 if (strcasecmp(val, "on") == 0) {
902 if (drv == DRIVER_OPENWRT)
903 ath_radio(dut, val);
904 if (drv == DRIVER_ATHEROS)
905 ath_ap_start_hostapd(dut);
906 else if (cmd_ap_config_commit(dut, conn, cmd) <= 0)
907 return STATUS_SENT;
908 } else if (strcasecmp(val, "off") == 0) {
909 if (drv == DRIVER_OPENWRT) {
910 ath_radio(dut, val);
911 } else if (dut->use_hostapd_pid_file) {
912 kill_hostapd_process_pid(dut);
913 } else if (kill_process(dut, "(hostapd)", 1,
914 SIGTERM) == 0 ||
915 system("killall hostapd") == 0) {
916 sigma_dut_print(dut, DUT_MSG_INFO,
917 "Killed hostapd on radio,off");
918 }
919 } else {
920 send_resp(dut, conn, SIGMA_INVALID,
921 "errorCode,Unsupported RADIO value");
922 return STATUS_SENT;
923 }
924 }
925
926 val = get_param(cmd, "P2PMgmtBit");
927 if (val)
928 dut->ap_p2p_mgmt = atoi(val);
929
930 /* TODO: ChannelUsage */
931
932 /* TODO: 40_INTOLERANT */
933
934 val = get_param(cmd, "ADDBA_REJECT");
935 if (val) {
936 if (strcasecmp(val, "Enable") == 0)
937 dut->ap_addba_reject = VALUE_ENABLED;
938 else if (strcasecmp(val, "Disable") == 0)
939 dut->ap_addba_reject = VALUE_DISABLED;
940 }
941
942 val = get_param(cmd, "AMPDU");
943 if (val) {
944 if (strcasecmp(val, "Enable") == 0)
945 dut->ap_ampdu = VALUE_ENABLED;
946 else if (strcasecmp(val, "Disable") == 0)
947 dut->ap_ampdu = VALUE_DISABLED;
948 }
949
950 val = get_param(cmd, "AMPDU_EXP");
951 if (val)
952 dut->ap_ampdu_exp = atoi(val);
953
954 val = get_param(cmd, "AMSDU");
955 if (val) {
956 if (strcasecmp(val, "Enable") == 0)
957 dut->ap_amsdu = VALUE_ENABLED;
958 else if (strcasecmp(val, "Disable") == 0)
959 dut->ap_amsdu = VALUE_DISABLED;
960 }
961
962 val = get_param(cmd, "NoAck");
963 if (val) {
964 if (strcasecmp(val, "on") == 0)
965 dut->ap_noack = VALUE_ENABLED;
966 else if (strcasecmp(val, "off") == 0)
967 dut->ap_noack = VALUE_DISABLED;
968 }
969
970 /* TODO: GREENFIELD */
971 /* TODO: MCS_32 */
972
973 val = get_param(cmd, "OFFSET");
974 if (val) {
975 if (strcasecmp(val, "Above") == 0)
976 dut->ap_chwidth_offset = SEC_CH_40ABOVE;
977 else if (strcasecmp(val, "Below") == 0)
978 dut->ap_chwidth_offset = SEC_CH_40BELOW;
979 }
980
981 val = get_param(cmd, "MCS_FIXEDRATE");
982 if (val) {
983 dut->ap_fixed_rate = 1;
984 dut->ap_mcs = atoi(val);
985 }
986
987 val = get_param(cmd, "SPATIAL_RX_STREAM");
988 if (val) {
989 if (strcasecmp(val, "1SS") == 0 || strcasecmp(val, "1") == 0) {
990 dut->ap_rx_streams = 1;
991 if (dut->device_type == AP_testbed)
992 dut->ap_vhtmcs_map = 0xfffc;
993 } else if (strcasecmp(val, "2SS") == 0 ||
994 strcasecmp(val, "2") == 0) {
995 dut->ap_rx_streams = 2;
996 if (dut->device_type == AP_testbed)
997 dut->ap_vhtmcs_map = 0xfff0;
998 } else if (strcasecmp(val, "3SS") == 0 ||
999 strcasecmp(val, "3") == 0) {
1000 dut->ap_rx_streams = 3;
1001 if (dut->device_type == AP_testbed)
1002 dut->ap_vhtmcs_map = 0xffc0;
1003 } else if (strcasecmp(val, "4SS") == 0 ||
1004 strcasecmp(val, "4") == 0) {
1005 dut->ap_rx_streams = 4;
1006 }
1007 }
1008
1009 val = get_param(cmd, "SPATIAL_TX_STREAM");
1010 if (val) {
1011 if (strcasecmp(val, "1SS") == 0 ||
1012 strcasecmp(val, "1") == 0) {
1013 dut->ap_tx_streams = 1;
1014 if (dut->device_type == AP_testbed)
1015 dut->ap_vhtmcs_map = 0xfffc;
1016 } else if (strcasecmp(val, "2SS") == 0 ||
1017 strcasecmp(val, "2") == 0) {
1018 dut->ap_tx_streams = 2;
1019 if (dut->device_type == AP_testbed)
1020 dut->ap_vhtmcs_map = 0xfff0;
1021 } else if (strcasecmp(val, "3SS") == 0 ||
1022 strcasecmp(val, "3") == 0) {
1023 dut->ap_tx_streams = 3;
1024 if (dut->device_type == AP_testbed)
1025 dut->ap_vhtmcs_map = 0xffc0;
1026 } else if (strcasecmp(val, "4SS") == 0 ||
1027 strcasecmp(val, "4") == 0) {
1028 dut->ap_tx_streams = 4;
1029 }
1030 }
1031
1032 val = get_param(cmd, "BSS_max_idle");
1033 if (val) {
1034 if (strncasecmp(val, "Enable", 7) == 0) {
1035 dut->wnm_bss_max_feature = VALUE_ENABLED;
1036 } else if (strncasecmp(val, "Disable", 8) == 0) {
1037 dut->wnm_bss_max_feature = VALUE_DISABLED;
1038 } else {
1039 send_resp(dut, conn, SIGMA_ERROR,
1040 "errorCode,Invalid value for BSS_max_Feature");
1041 return STATUS_SENT;
1042 }
1043 }
1044
1045 val = get_param(cmd, "BSS_Idle_Protection_options");
1046 if (val) {
1047 int protection = (int) strtol(val, (char **) NULL, 10);
1048
1049 if (protection != 1 && protection != 0) {
1050 send_resp(dut, conn, SIGMA_ERROR,
1051 "errorCode,Invalid value for BSS_Idle_Protection_options");
1052 return STATUS_SENT;
1053 }
1054 dut->wnm_bss_max_protection = protection ?
1055 VALUE_ENABLED : VALUE_DISABLED;
1056 }
1057
1058 val = get_param(cmd, "BSS_max_Idle_period");
1059 if (val) {
1060 long int idle_time = strtol(val, (char **) NULL, 10);
1061
1062 if (idle_time == LONG_MIN || idle_time == LONG_MAX) {
1063 send_resp(dut, conn, SIGMA_ERROR,
1064 "errorCode,Invalid value for BSS_max_Idle_period");
1065 return STATUS_SENT;
1066 }
1067 dut->wnm_bss_max_idle_time = (int) idle_time;
1068 }
1069
1070 val = get_param(cmd, "PROXY_ARP");
1071 if (val)
1072 dut->ap_proxy_arp = (int) strtol(val, (char **) NULL, 10);
1073
1074 val = get_param(cmd, "nss_mcs_cap");
1075 if (val) {
1076 int nss, mcs;
1077 char token[20];
1078 char *result = NULL;
1079 char *saveptr;
1080
1081 if (strlen(val) >= sizeof(token))
1082 return INVALID_SEND_STATUS;
1083 strlcpy(token, val, sizeof(token));
1084 result = strtok_r(token, ";", &saveptr);
1085 if (!result) {
1086 send_resp(dut, conn, SIGMA_ERROR,
1087 "errorCode,VHT NSS not specified");
1088 return STATUS_SENT;
1089 }
1090 nss = atoi(result);
1091 result = strtok_r(NULL, ";", &saveptr);
1092 if (result == NULL) {
1093 send_resp(dut, conn, SIGMA_ERROR,
1094 "errorCode,VHTMCS not specified");
1095 return STATUS_SENT;
1096 }
1097 result = strtok_r(result, "-", &saveptr);
1098 result = strtok_r(NULL, "-", &saveptr);
1099 if (!result) {
1100 send_resp(dut, conn, SIGMA_ERROR,
1101 "errorCode,VHT MCS not specified");
1102 return STATUS_SENT;
1103 }
1104 mcs = atoi(result);
1105 if (dut->program == PROGRAM_HE) {
1106 uint16_t mcsnssmap = 0;
1107
1108 get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs);
1109 dut->he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap;
1110 dut->he_ul_mcs = mcs;
1111 } else {
1112 set_vht_mcsmap_nss(dut, nss, mcs);
1113 }
1114 }
1115
1116 /* TODO: MPDU_MIN_START_SPACING */
1117 /* TODO: RIFS_TEST */
1118 /* TODO: SGI20 */
1119
1120 val = get_param(cmd, "STBC_TX");
1121 if (val)
1122 dut->ap_tx_stbc = atoi(val);
1123
1124 val = get_param(cmd, "WIDTH");
1125 if (val) {
1126 if (strcasecmp(val, "20") == 0)
1127 dut->ap_chwidth = AP_20;
1128 else if (strcasecmp(val, "40") == 0)
1129 dut->ap_chwidth = AP_40;
1130 else if (strcasecmp(val, "80") == 0)
1131 dut->ap_chwidth = AP_80;
1132 else if (strcasecmp(val, "160") == 0)
1133 dut->ap_chwidth = AP_160;
1134 else if (strcasecmp(val, "80plus80") == 0) {
1135 dut->ap_80plus80 = 1;
1136 dut->ap_chwidth = AP_80_80;
1137 } else if (strcasecmp(val, "Auto") == 0)
1138 dut->ap_chwidth = AP_AUTO;
1139 else {
1140 send_resp(dut, conn, SIGMA_INVALID,
1141 "errorCode,Unsupported WIDTH");
1142 return STATUS_SENT;
1143 }
1144 }
1145
1146 /* TODO: WIDTH_SCAN */
1147
1148 val = get_param(cmd, "TDLSProhibit");
1149 dut->ap_tdls_prohibit = val && strcasecmp(val, "Enabled") == 0;
1150 val = get_param(cmd, "TDLSChswitchProhibit");
1151 dut->ap_tdls_prohibit_chswitch =
1152 val && strcasecmp(val, "Enabled") == 0;
1153 val = get_param(cmd, "HS2");
1154 if (val && wlan_tag == 1)
1155 dut->ap_hs2 = atoi(val);
1156 val = get_param(cmd, "P2P_CROSS_CONNECT");
1157 if (val)
1158 dut->ap_p2p_cross_connect = strcasecmp(val, "Enabled") == 0;
1159
1160 val = get_param(cmd, "FakePubKey");
1161 dut->ap_fake_pkhash = val && atoi(val);
1162
1163 val = get_param(cmd, "vht_tkip");
1164 dut->ap_allow_vht_tkip = val && strcasecmp(val, "Enable") == 0;
1165 val = get_param(cmd, "vht_wep");
1166 dut->ap_allow_vht_wep = val && strcasecmp(val, "Enable") == 0;
1167
1168 val = get_param(cmd, "Protect_mode");
1169 dut->ap_disable_protection = val && strcasecmp(val, "Disable") == 0;
1170
1171 val = get_param(cmd, "DYN_BW_SGNL");
1172 if (val) {
1173 switch (get_driver_type(dut)) {
1174 case DRIVER_OPENWRT:
1175 switch (get_openwrt_driver_type()) {
1176 case OPENWRT_DRIVER_ATHEROS:
1177 ath_config_dyn_bw_sig(dut, ifname, val);
1178 break;
1179 default:
1180 send_resp(dut, conn, SIGMA_ERROR,
1181 "errorCode,Unsupported DYN_BW_SGNL with OpenWrt driver");
1182 return STATUS_SENT;
1183 }
1184 break;
1185 case DRIVER_WCN:
1186 case DRIVER_LINUX_WCN:
1187 ath_config_dyn_bw_sig(dut, ifname, val);
1188 break;
1189 default:
1190 sigma_dut_print(dut, DUT_MSG_ERROR,
1191 "Unsupported DYN_BW_SGL with the current driver");
1192 break;
1193 }
1194 }
1195
1196 val = get_param(cmd, "SGI80");
1197 if (val) {
1198 if (strcasecmp(val, "enable") == 0)
1199 dut->ap_sgi80 = 1;
1200 else if (strcasecmp(val, "disable") == 0)
1201 dut->ap_sgi80 = 0;
1202 else {
1203 send_resp(dut, conn, SIGMA_INVALID,
1204 "errorCode,Unsupported SGI80");
1205 return STATUS_SENT;
1206 }
1207 }
1208
1209 val = get_param(cmd, "LDPC");
1210 if (val) {
1211 if (strcasecmp(val, "enable") == 0)
1212 dut->ap_ldpc = VALUE_ENABLED;
1213 else if (strcasecmp(val, "disable") == 0)
1214 dut->ap_ldpc = VALUE_DISABLED;
1215 else {
1216 send_resp(dut, conn, SIGMA_INVALID,
1217 "errorCode,Unsupported LDPC");
1218 return STATUS_SENT;
1219 }
1220 switch (get_driver_type(dut)) {
1221 case DRIVER_WCN:
1222 case DRIVER_LINUX_WCN:
1223 wcn_config_ap_ldpc(dut, ifname);
1224 break;
1225 default:
1226 break;
1227 }
1228 }
1229
1230 val = get_param(cmd, "BW_SGNL");
1231 if (val) {
1232 /*
1233 * With dynamic bandwidth signaling enabled we should see
1234 * RTS if the threshold is met.
1235 */
1236 if (strcasecmp(val, "enable") == 0) {
1237 dut->ap_sig_rts = VALUE_ENABLED;
1238 } else if (strcasecmp(val, "disable") == 0) {
1239 dut->ap_sig_rts = VALUE_DISABLED;
1240 } else {
1241 send_resp(dut, conn, SIGMA_INVALID,
1242 "errorCode,Unsupported BW_SGNL");
1243 return STATUS_SENT;
1244 }
1245 }
1246
1247 val = get_param(cmd, "RTS_FORCE");
1248 if (val) {
1249 switch (get_driver_type(dut)) {
1250 case DRIVER_OPENWRT:
1251 switch (get_openwrt_driver_type()) {
1252 case OPENWRT_DRIVER_ATHEROS:
1253 ath_config_rts_force(dut, ifname, val);
1254 break;
1255 default:
1256 send_resp(dut, conn, SIGMA_ERROR,
1257 "errorCode,Unsupported RTS_FORCE with OpenWrt driver");
1258 return STATUS_SENT;
1259 }
1260 break;
1261 case DRIVER_MAC80211:
1262 mac80211_config_rts_force(dut, ifname, val);
1263 break;
1264 default:
1265 sigma_dut_print(dut, DUT_MSG_ERROR,
1266 "Unsupported RTS_FORCE with the current driver");
1267 break;
1268 }
1269 }
1270
1271 val = get_param(cmd, "Zero_crc");
1272 if (val) {
1273 switch (get_driver_type(dut)) {
1274 case DRIVER_ATHEROS:
1275 ath_set_zero_crc(dut, val);
1276 break;
1277 case DRIVER_OPENWRT:
1278 switch (get_openwrt_driver_type()) {
1279 case OPENWRT_DRIVER_ATHEROS:
1280 ath_set_zero_crc(dut, val);
1281 break;
1282 default:
1283 send_resp(dut, conn, SIGMA_ERROR,
1284 "errorCode,Unsupported zero_crc with the current driver");
1285 return STATUS_SENT;
1286 }
1287 break;
1288 default:
1289 send_resp(dut, conn, SIGMA_ERROR,
1290 "errorCode,Unsupported zero_crc with the current driver");
1291 return STATUS_SENT;
1292 }
1293 }
1294
1295 val = get_param(cmd, "TxBF");
1296 if (val) {
1297 dut->ap_txBF = strcasecmp(val, "enable") == 0;
1298 dut->he_sounding = VALUE_DISABLED;
1299 dut->he_set_sta_1x1 = VALUE_ENABLED;
1300 }
1301
1302 val = get_param(cmd, "MU_TxBF");
1303 if (val) {
1304 if (strcasecmp(val, "enable") == 0) {
1305 dut->ap_txBF = 1;
1306 dut->ap_mu_txBF = 1;
1307 dut->he_sounding = VALUE_DISABLED;
1308 } else if (strcasecmp(val, "disable") == 0) {
1309 dut->ap_txBF = 0;
1310 dut->ap_mu_txBF = 0;
1311 } else {
1312 sigma_dut_print(dut, DUT_MSG_ERROR,
1313 "Unsupported MU_TxBF");
1314 }
1315 }
1316
1317 /* UNSUPPORTED: tx_lgi_rate */
1318
1319 val = get_param(cmd, "wpsnfc");
1320 if (val)
1321 dut->ap_wpsnfc = atoi(val);
1322
1323 val = get_param(cmd, "GROUP_ID");
1324 if (val) {
1325 switch (get_driver_type(dut)) {
1326 case DRIVER_OPENWRT:
1327 switch (get_openwrt_driver_type()) {
1328 case OPENWRT_DRIVER_ATHEROS:
1329 ath_ap_set_group_id(dut, ifname, val);
1330 break;
1331 default:
1332 send_resp(dut, conn, SIGMA_ERROR,
1333 "errorCode,Unsupported group_id with the current driver");
1334 return STATUS_SENT;
1335 }
1336 break;
1337 default:
1338 send_resp(dut, conn, SIGMA_ERROR,
1339 "errorCode,Unsupported group_id with the current driver");
1340 return STATUS_SENT;
1341 }
1342 }
1343
1344 val = get_param(cmd, "CTS_WIDTH");
1345 if (val) {
1346 switch (get_driver_type(dut)) {
1347 case DRIVER_OPENWRT:
1348 switch (get_openwrt_driver_type()) {
1349 case OPENWRT_DRIVER_ATHEROS:
1350 ath_set_cts_width(dut, ifname, val);
1351 break;
1352 default:
1353 send_resp(dut, conn, SIGMA_ERROR,
1354 "errorCode,Unsupported cts_width with the current driver");
1355 return STATUS_SENT;
1356 }
1357 break;
1358 default:
1359 send_resp(dut, conn, SIGMA_ERROR,
1360 "errorCode,Unsupported cts_width with the current driver");
1361 return STATUS_SENT;
1362 }
1363 }
1364
1365 val = get_param(cmd, "MU_NDPA_FrameFormat");
1366 if (val)
1367 dut->ap_ndpa_frame = atoi(val);
1368
1369 val = get_param(cmd, "interworking");
1370 if (val && strcmp(val, "1") == 0)
1371 dut->ap_interworking = 1;
1372
1373 val = get_param(cmd, "GAS_CB_DELAY");
1374 if (val)
1375 dut->ap_gas_cb_delay = atoi(val);
1376
1377 val = get_param(cmd, "LCI");
1378 if (val) {
1379 if (strlen(val) > sizeof(dut->ap_val_lci) - 1)
1380 return INVALID_SEND_STATUS;
1381 dut->ap_lci = 1;
1382 snprintf(dut->ap_val_lci, sizeof(dut->ap_val_lci), "%s", val);
1383 ath_set_lci_config(dut, val, cmd);
1384 }
1385
1386 val = get_param(cmd, "InfoZ");
1387 if (val) {
1388 if (strlen(val) > sizeof(dut->ap_infoz) - 1)
1389 return INVALID_SEND_STATUS;
1390 snprintf(dut->ap_infoz, sizeof(dut->ap_infoz), "%s", val);
1391 }
1392
1393 val = get_param(cmd, "LocCivicAddr");
1394 if (val) {
1395 if (strlen(val) > sizeof(dut->ap_val_lcr) - 1)
1396 return INVALID_SEND_STATUS;
1397 dut->ap_lcr = 1;
1398 snprintf(dut->ap_val_lcr, sizeof(dut->ap_val_lcr), "%s", val);
1399 if (dut->ap_lci == 0)
1400 ath_set_lci_config(dut, val, cmd);
1401 }
1402
1403 val = get_param(cmd, "NeighAPBSSID");
1404 if (val) {
1405 if (dut->ap_neighap < 3) {
1406 if (parse_mac_address(
1407 dut, val,
1408 dut->ap_val_neighap[dut->ap_neighap]) < 0) {
1409 send_resp(dut, conn, SIGMA_INVALID,
1410 "Failed to parse MAC address");
1411 return STATUS_SENT;
1412 }
1413 dut->ap_neighap++;
1414 if (dut->ap_lci == 1)
1415 dut->ap_scan = 1;
1416 }
1417 }
1418
1419 val = get_param(cmd, "OpChannel");
1420 if (val) {
1421 if (dut->ap_opchannel < 3) {
1422 dut->ap_val_opchannel[dut->ap_opchannel] = atoi(val);
1423 dut->ap_opchannel++;
1424 }
1425 }
1426
1427 val = get_param(cmd, "URI-FQDNdescriptor");
1428 if (val) {
1429 if (strcasecmp(val, "HELD") == 0) {
1430 dut->ap_fqdn_held = 1;
1431 } else if (strcasecmp(val, "SUPL") == 0) {
1432 dut->ap_fqdn_supl = 1;
1433 } else {
1434 send_resp(dut, conn, SIGMA_INVALID,
1435 "errorCode,Unsupported URI-FQDNdescriptor");
1436 return STATUS_SENT;
1437 }
1438 }
1439
1440 val = get_param(cmd, "Reg_Domain");
1441 if (val) {
1442 if (strcasecmp(val, "Local") == 0) {
1443 dut->ap_reg_domain = REG_DOMAIN_LOCAL;
1444 } else if (strcasecmp(val, "Global") == 0) {
1445 dut->ap_reg_domain = REG_DOMAIN_GLOBAL;
1446 } else {
1447 send_resp(dut, conn, SIGMA_ERROR,
1448 "errorCode,Wrong value for Reg_Domain");
1449 return STATUS_SENT;
1450 }
1451 }
1452
1453 val = get_param(cmd, "NAME");
1454 if (val) {
1455 if (strcasecmp(val, "ap1mbo") == 0)
1456 dut->ap_name = 1;
1457 else if (strcasecmp(val, "ap2mbo") == 0)
1458 dut->ap_name = 2;
1459 else
1460 dut->ap_name = 0;
1461 }
1462
1463 val = get_param(cmd, "FT_OA");
1464 if (val) {
1465 if (strcasecmp(val, "Enable") == 0) {
1466 dut->ap_ft_oa = 1;
1467 } else if (strcasecmp(val, "Disable") == 0) {
1468 dut->ap_ft_oa = 0;
1469 } else {
1470 send_resp(dut, conn, SIGMA_ERROR,
1471 "errorCode,Wrong value for FT_OA");
1472 return STATUS_SENT;
1473 }
1474 }
1475
1476 val = get_param(cmd, "FT_DS");
1477 if (val) {
1478 if (strcasecmp(val, "Enable") == 0) {
1479 dut->ap_ft_ds = VALUE_ENABLED;
1480 } else if (strcasecmp(val, "Disable") == 0) {
1481 dut->ap_ft_ds = VALUE_DISABLED;
1482 } else {
1483 send_resp(dut, conn, SIGMA_ERROR,
1484 "errorCode,Unsupported value for FT_DS");
1485 return STATUS_SENT_ERROR;
1486 }
1487 }
1488
1489 val = get_param(cmd, "Cellular_Cap_Pref");
1490 if (val)
1491 dut->ap_cell_cap_pref = atoi(val);
1492
1493 val = get_param(cmd, "DOMAIN");
1494 if (val) {
1495 if (strlen(val) >= sizeof(dut->ap_mobility_domain)) {
1496 send_resp(dut, conn, SIGMA_ERROR,
1497 "errorCode,Too long DOMAIN");
1498 return STATUS_SENT;
1499 }
1500 snprintf(dut->ap_mobility_domain,
1501 sizeof(dut->ap_mobility_domain), "%s", val);
1502 }
1503
1504 val = get_param(cmd, "ft_bss_list");
1505 if (val) {
1506 char *mac_str;
1507 int i;
1508 char *saveptr;
1509 char *mac_list_str;
1510
1511 mac_list_str = strdup(val);
1512 if (!mac_list_str)
1513 return INVALID_SEND_STATUS;
1514 mac_str = strtok_r(mac_list_str, " ", &saveptr);
1515 for (i = 0; mac_str && i < MAX_FT_BSS_LIST; i++) {
1516 if (parse_mac_address(dut, mac_str,
1517 dut->ft_bss_mac_list[i]) < 0) {
1518 sigma_dut_print(dut, DUT_MSG_ERROR,
1519 "MAC Address not in proper format");
1520 break;
1521 }
1522 dut->ft_bss_mac_cnt++;
1523 mac_str = strtok_r(NULL, " ", &saveptr);
1524 }
1525 sigma_dut_print(dut, DUT_MSG_DEBUG,
1526 "Storing the following FT BSS MAC List");
1527 for (i = 0; i < dut->ft_bss_mac_cnt; i++) {
1528 sigma_dut_print(dut, DUT_MSG_DEBUG,
1529 "MAC[%d] %02x:%02x:%02x:%02x:%02x:%02x",
1530 i,
1531 dut->ft_bss_mac_list[i][0],
1532 dut->ft_bss_mac_list[i][1],
1533 dut->ft_bss_mac_list[i][2],
1534 dut->ft_bss_mac_list[i][3],
1535 dut->ft_bss_mac_list[i][4],
1536 dut->ft_bss_mac_list[i][5]);
1537 }
1538 free(mac_list_str);
1539 }
1540
1541 val = get_param(cmd, "OCESupport");
1542 if (val) {
1543 if (strcasecmp(val, "enable") == 0) {
1544 dut->ap_oce = VALUE_ENABLED;
1545 } else if (strcasecmp(val, "disable") == 0) {
1546 dut->ap_oce = VALUE_DISABLED;
1547 dut->ap_filsdscv = VALUE_DISABLED;
1548 } else {
1549 send_resp(dut, conn, SIGMA_INVALID,
1550 "errorCode,Unsupported OCE");
1551 return STATUS_SENT;
1552 }
1553 }
1554
1555 val = get_param(cmd, "FILSDscvInterval");
1556 if (val)
1557 dut->ap_fils_dscv_int = atoi(val);
1558
1559 val = get_param(cmd, "BroadcastSSID");
1560 if (val) {
1561 if (strcasecmp(val, "enable") == 0) {
1562 dut->ap_broadcast_ssid = VALUE_ENABLED;
1563 } else if (strcasecmp(val, "disable") == 0) {
1564 dut->ap_broadcast_ssid = VALUE_DISABLED;
1565 } else {
1566 send_resp(dut, conn, SIGMA_INVALID,
1567 "errorCode,Unsupported hidden SSID");
1568 return STATUS_SENT;
1569 }
1570 }
1571
1572 val = get_param(cmd, "FILSDscv");
1573 if (val) {
1574 if (strcasecmp(val, "enable") == 0) {
1575 dut->ap_filsdscv = VALUE_ENABLED;
1576 } else if (strcasecmp(val, "disable") == 0) {
1577 dut->ap_filsdscv = VALUE_DISABLED;
1578 } else {
1579 send_resp(dut, conn, SIGMA_INVALID,
1580 "errorCode,Unsupported FILSDscv");
1581 return STATUS_SENT;
1582 }
1583 }
1584
1585 val = get_param(cmd, "FILSHLP");
1586 if (val) {
1587 if (strcasecmp(val, "enable") == 0) {
1588 dut->ap_filshlp = VALUE_ENABLED;
1589 } else if (strcasecmp(val, "disable") == 0) {
1590 dut->ap_filshlp = VALUE_DISABLED;
1591 } else {
1592 send_resp(dut, conn, SIGMA_INVALID,
1593 "errorCode,Unsupported FILSHLP");
1594 return STATUS_SENT;
1595 }
1596 }
1597
1598 val = get_param(cmd, "NAIRealm");
1599 if (val) {
1600 dut->ap_nairealm_int = 1;
1601 if (strlen(val) > sizeof(dut->ap_nairealm) - 1)
1602 return INVALID_SEND_STATUS;
1603 snprintf(dut->ap_nairealm, sizeof(dut->ap_nairealm), "%s", val);
1604 }
1605
1606 val = get_param(cmd, "DeauthDisassocTx");
1607 if (val) {
1608 if (strcasecmp(val, "disable") == 0) {
1609 deauth_disassoc(dut, ifname, val);
1610 } else {
1611 send_resp(dut, conn, SIGMA_INVALID,
1612 "errorCode,Unsupported DeauthDisassocTx");
1613 return STATUS_SENT;
1614 }
1615 }
1616
1617 val = get_param(cmd, "RNR");
1618 if (val) {
1619 if (strcasecmp(val, "enable") == 0) {
1620 dut->ap_rnr = VALUE_ENABLED;
1621 } else if (strcasecmp(val, "disable") == 0) {
1622 dut->ap_rnr = VALUE_DISABLED;
1623 } else {
1624 send_resp(dut, conn, SIGMA_INVALID,
1625 "errorCode,Unsupported RNR");
1626 return STATUS_SENT;
1627 }
1628 }
1629
1630 val = get_param(cmd, "BLEChannelUtil");
1631 if (val)
1632 dut->ap_blechanutil = atoi(val);
1633
1634 val = get_param(cmd, "BLEAvailAdminCap");
1635 if (val)
1636 dut->ap_ble_admit_cap = atoi(val);
1637
1638 val = get_param(cmd, "DataPPDUDuration");
1639 if (val)
1640 dut->ap_datappdudura = atoi(val);
1641
1642 val = get_param(cmd, "AirTimeFract");
1643 if (val)
1644 dut->ap_airtimefract = atoi(val);
1645
1646 val = get_param(cmd, "dhcpServIPADDR");
1647 if (val) {
1648 if (strlen(val) > sizeof(dut->ap_dhcpserv_ipaddr) - 1)
1649 return INVALID_SEND_STATUS;
1650 snprintf(dut->ap_dhcpserv_ipaddr,
1651 sizeof(dut->ap_dhcpserv_ipaddr), "%s", val);
1652 dut->ap_dhcp_stop = 1;
1653 }
1654
1655 val = get_param(cmd, "ESP_IE");
1656 if (val) {
1657 if (strcasecmp(val, "enable") == 0) {
1658 dut->ap_esp = VALUE_ENABLED;
1659 } else if (strcasecmp(val, "disable") == 0) {
1660 dut->ap_esp = VALUE_DISABLED;
1661 } else {
1662 send_resp(dut, conn, SIGMA_INVALID,
1663 "errorCode,Unsupported ESP_IE");
1664 return STATUS_SENT;
1665 }
1666 }
1667
1668 val = get_param(cmd, "BAWinSize");
1669 if (val)
1670 dut->ap_bawinsize = atoi(val);
1671
1672 val = get_param(cmd, "BLEStaCount");
1673 if (val)
1674 dut->ap_blestacnt = atoi(val);
1675
1676 val = get_param(cmd, "PPDUTxType");
1677 if (val) {
1678 if (strcasecmp(val, "MU") == 0) {
1679 dut->ap_he_ppdu = PPDU_MU;
1680 } else if (strcasecmp(val, "HE-SU") == 0) {
1681 /* Do nothing */
1682 } else if (strcasecmp(val, "SU") == 0) {
1683 /* Do nothing */
1684 } else if (strcasecmp(val, "legacy") == 0) {
1685 /* Do nothing */
1686 } else if (strcasecmp(val, "ER") == 0) {
1687 /* Do nothing */
1688 } else if (strcasecmp(val, "TB") == 0) {
1689 /* Do nothing */
1690 } else {
1691 send_resp(dut, conn, SIGMA_ERROR,
1692 "errorCode,Unsupported PPDUTxType");
1693 return STATUS_SENT_ERROR;
1694 }
1695 }
1696
1697 val = get_param(cmd, "WscIEFragment");
1698 if (val && strcasecmp(val, "enable") == 0) {
1699 sigma_dut_print(dut, DUT_MSG_DEBUG,
1700 "Enable WSC IE fragmentation");
1701 dut->wsc_fragment = 1;
1702 }
1703
1704 val = get_param(cmd, "WpsVersion");
1705 if (val)
1706 dut->wps_forced_version = get_wps_forced_version(dut, val);
1707
1708 val = get_param(cmd, "WscEAPFragment");
1709 if (val && strcasecmp(val, "enable") == 0)
1710 dut->eap_fragment = 1;
1711
1712 val = get_param(cmd, "MSDUSize");
1713 if (val) {
1714 int mtu;
1715
1716 dut->amsdu_size = atoi(val);
1717 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
1718 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
1719 sigma_dut_print(dut, DUT_MSG_ERROR,
1720 "MSDUSize %d is above max %d or below min %d",
1721 dut->amsdu_size,
1722 IEEE80211_MAX_DATA_LEN_DMG,
1723 IEEE80211_SNAP_LEN_DMG);
1724 dut->amsdu_size = 0;
1725 return ERROR_SEND_STATUS;
1726 }
1727
1728 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
1729 sigma_dut_print(dut, DUT_MSG_DEBUG,
1730 "Setting amsdu_size to %d", mtu);
1731 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
1732 get_station_ifname(dut), mtu);
1733
1734 if (system(buf) != 0) {
1735 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
1736 buf);
1737 return ERROR_SEND_STATUS;
1738 }
1739 }
1740
1741 val = get_param(cmd, "BAckRcvBuf");
1742 if (val) {
1743 dut->back_rcv_buf = atoi(val);
1744 if (dut->back_rcv_buf == 0) {
1745 sigma_dut_print(dut, DUT_MSG_ERROR,
1746 "Failed to convert %s or value is 0",
1747 val);
1748 return ERROR_SEND_STATUS;
1749 }
1750
1751 sigma_dut_print(dut, DUT_MSG_DEBUG,
1752 "Setting BAckRcvBuf to %s", val);
1753 }
1754
1755 val = get_param(cmd, "ExtSchIE");
1756 if (val && !strcasecmp(val, "Enable")) {
1757 int num_allocs = MAX_ESE_ALLOCS;
1758
1759 if (sta_extract_60g_ese(dut, cmd, dut->ap_ese_allocs,
1760 &num_allocs)) {
1761 send_resp(dut, conn, SIGMA_INVALID,
1762 "errorCode,Invalid ExtSchIE");
1763 return STATUS_SENT;
1764 }
1765 dut->ap_num_ese_allocs = num_allocs;
1766 }
1767
1768 if (is_60g_sigma_dut(dut)) {
1769 unsigned int abft_len = 1; /* default is one slot */
1770
1771 val = get_param(cmd, "ABFTLRang");
1772 if (val) {
1773 sigma_dut_print(dut, DUT_MSG_DEBUG,
1774 "ABFTLRang parameter %s", val);
1775 if (strcasecmp(val, "Gt1") == 0)
1776 abft_len = 2; /* 2 slots in this case */
1777 }
1778
1779 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
1780 send_resp(dut, conn, SIGMA_ERROR,
1781 "ErrorCode,Can't set ABFT length");
1782 return STATUS_SENT;
1783 }
1784 }
1785
1786 val = get_param(cmd, "OFDMA");
1787 if (val) {
1788 if (strcasecmp(val, "UL") == 0) {
1789 dut->ap_he_ulofdma = VALUE_ENABLED;
1790 } else if (strcasecmp(val, "DL") == 0) {
1791 dut->ap_he_dlofdma = VALUE_ENABLED;
1792 } else if (strcasecmp(val, "DL-20and80") == 0) {
1793 dut->ap_he_dlofdma = VALUE_ENABLED;
1794 } else {
1795 send_resp(dut, conn, SIGMA_ERROR,
1796 "errorCode,Unsupported OFDMA value");
1797 return STATUS_SENT_ERROR;
1798 }
1799 }
1800
1801 val = get_param(cmd, "NumSoundDim");
1802 if (val)
1803 dut->ap_numsounddim = atoi(val);
1804
1805 val = get_param(cmd, "BCC");
1806 if (val) {
1807 if (strcasecmp(val, "enable") == 0) {
1808 dut->ap_bcc = VALUE_ENABLED;
1809 dut->ap_ldpc = VALUE_DISABLED;
1810 } else if (strcasecmp(val, "disable") == 0) {
1811 dut->ap_ldpc = VALUE_ENABLED;
1812 dut->ap_bcc = VALUE_DISABLED;
1813 } else {
1814 send_resp(dut, conn, SIGMA_ERROR,
1815 "errorCode,Unsupported BCC value");
1816 return STATUS_SENT_ERROR;
1817 }
1818 switch (get_driver_type(dut)) {
1819 case DRIVER_WCN:
1820 case DRIVER_LINUX_WCN:
1821 wcn_config_ap_ldpc(dut, ifname);
1822 break;
1823 default:
1824 break;
1825 }
1826 }
1827
1828 val = get_param(cmd, "FrgmntSupport");
1829 if (val) {
1830 if (strcasecmp(val, "enable") == 0) {
1831 dut->ap_he_frag = VALUE_ENABLED;
1832 } else if (strcasecmp(val, "disable") == 0) {
1833 dut->ap_he_frag = VALUE_DISABLED;
1834 } else {
1835 send_resp(dut, conn, SIGMA_ERROR,
1836 "errorCode,Unsupported FrgmntSupport value");
1837 return STATUS_SENT_ERROR;
1838 }
1839 }
1840
1841 val = get_param(cmd, "ADDBAReq_BufSize");
1842 if (val) {
1843 if (strcasecmp(val, "le64") == 0) {
1844 dut->ap_ba_bufsize = BA_BUFSIZE_64;
1845 } else if (strcasecmp(val, "gt64") == 0) {
1846 dut->ap_ba_bufsize = BA_BUFSIZE_256;
1847 } else {
1848 send_resp(dut, conn, SIGMA_ERROR,
1849 "errorCode,Unsupported ADDBAReq Buffer Size");
1850 return STATUS_SENT_ERROR;
1851 }
1852 }
1853
1854 val = get_param(cmd, "ADDBAResp_BufSize");
1855 if (val) {
1856 if (strcasecmp(val, "gt64") == 0) {
1857 dut->ap_ba_bufsize = BA_BUFSIZE_256;
1858 } else {
1859 send_resp(dut, conn, SIGMA_ERROR,
1860 "errorCode,Unsupported ADDBAResp Buffer Size");
1861 return STATUS_SENT_ERROR;
1862 }
1863 }
1864
1865 val = get_param(cmd, "MU_EDCA");
1866 if (val) {
1867 if (strcasecmp(val, "override") == 0) {
1868 dut->ap_mu_edca = VALUE_ENABLED;
1869 } else if (strcasecmp(val, "disable") == 0) {
1870 dut->ap_mu_edca = VALUE_DISABLED;
1871 } else {
1872 send_resp(dut, conn, SIGMA_ERROR,
1873 "errorCode,Unsupported mu_edca param value");
1874 return STATUS_SENT_ERROR;
1875 }
1876 }
1877
1878 val = get_param(cmd, "MIMO");
1879 if (val) {
1880 if (strcasecmp(val, "DL") == 0) {
1881 dut->ap_he_mimo = MIMO_DL;
1882 dut->he_sounding = VALUE_DISABLED;
1883 } else if (strcasecmp(val, "UL") == 0) {
1884 dut->ap_he_mimo = MIMO_UL;
1885 } else {
1886 send_resp(dut, conn, SIGMA_ERROR,
1887 "errorCode,Unsupported mimo param value");
1888 return STATUS_SENT_ERROR;
1889 }
1890 }
1891
1892 val = get_param(cmd, "HE_TXOPDurRTSThr");
1893 if (val) {
1894 if (strcasecmp(val, "enable") == 0) {
1895 dut->ap_he_rtsthrshld = VALUE_ENABLED;
1896 } else if (strcasecmp(val, "disable") == 0) {
1897 dut->ap_he_rtsthrshld = VALUE_DISABLED;
1898 } else {
1899 send_resp(dut, conn, SIGMA_ERROR,
1900 "errorCode,Unsupported HE_TXOPDurRTSThr value");
1901 return STATUS_SENT_ERROR;
1902 }
1903 }
1904
1905 val = get_param(cmd, "MBSSID");
1906 if (val) {
1907 if (strcasecmp(val, "enable") == 0) {
1908 dut->ap_mbssid = VALUE_ENABLED;
1909 } else if (strcasecmp(val, "disable") == 0) {
1910 dut->ap_mbssid = VALUE_DISABLED;
1911 } else {
1912 send_resp(dut, conn, SIGMA_ERROR,
1913 "errorCode,Unsupported MBSSID Value");
1914 return STATUS_SENT_ERROR;
1915 }
1916 }
1917
1918 val = get_param(cmd, "TWT_RespSupport");
1919 if (val) {
1920 if (strcasecmp(val, "enable") == 0) {
1921 dut->ap_twtresp = VALUE_ENABLED;
1922 } else if (strcasecmp(val, "disable") == 0) {
1923 dut->ap_twtresp = VALUE_DISABLED;
1924 } else {
1925 send_resp(dut, conn, SIGMA_ERROR,
1926 "errorCode,Unsupported TWT_RespSupport value");
1927 return STATUS_SENT_ERROR;
1928 }
1929 }
1930
1931 val = get_param(cmd, "MinMPDUStartSpacing");
1932 if (val)
1933 dut->he_mmss = atoi(val);
1934
1935 val = get_param(cmd, "SRCtrl_SRValue15Allowed");
1936 if (val)
1937 dut->he_srctrl_allow = atoi(val);
1938
1939 val = get_param(cmd, "ocvc");
1940 if (val)
1941 dut->ap_ocvc = atoi(val);
1942
1943 return SUCCESS_SEND_STATUS;
1944 }
1945
1946
ath_inject_frame(struct sigma_dut * dut,const char * ifname,int tid)1947 static void ath_inject_frame(struct sigma_dut *dut, const char *ifname, int tid)
1948 {
1949 char buf[256];
1950 int tid_to_dscp[] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
1951
1952 if (tid < 0 ||
1953 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
1954 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
1955 return;
1956 }
1957
1958 snprintf(buf, sizeof(buf),
1959 "wlanconfig %s list sta | grep : | cut -b 1-17 > %s",
1960 ifname, VI_QOS_TMP_FILE);
1961 if (system(buf) != 0)
1962 return;
1963
1964 snprintf(buf, sizeof(buf),
1965 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
1966 ifname, VI_QOS_TMP_FILE);
1967 if (system(buf) != 0)
1968 sigma_dut_print(dut, DUT_MSG_ERROR, "Retrieve HWaddr failed");
1969
1970 snprintf(buf, sizeof(buf), "sed -n '3,$p' %s >> %s",
1971 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
1972 if (system(buf) != 0) {
1973 sigma_dut_print(dut, DUT_MSG_ERROR,
1974 "Output redirection to VI_QOS_TMP_FILE failed");
1975 }
1976
1977 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
1978 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
1979 if (system(buf) != 0) {
1980 sigma_dut_print(dut, DUT_MSG_ERROR,
1981 "Append TID to VI_QOS_FILE failed ");
1982 }
1983
1984 snprintf(buf, sizeof(buf), "ethinject %s %s", ifname, VI_QOS_FILE);
1985 if (system(buf) != 0)
1986 sigma_dut_print(dut, DUT_MSG_ERROR, "Ethinject frame failed");
1987 }
1988
1989
ath_ap_send_addba_req(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)1990 static int ath_ap_send_addba_req(struct sigma_dut *dut, struct sigma_conn *conn,
1991 struct sigma_cmd *cmd)
1992 {
1993 const char *val;
1994 const char *ifname;
1995 char buf[256];
1996 int tid = 0;
1997
1998 ifname = get_main_ifname(dut);
1999 val = get_param(cmd, "TID");
2000 if (val) {
2001 tid = atoi(val);
2002 if (tid)
2003 ath_inject_frame(dut, ifname, tid);
2004 }
2005
2006 /* NOTE: This is the command sequence on Peregrine for ADDBA */
2007 run_iwpriv(dut, ifname, "setaddbaoper 1");
2008
2009 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4",
2010 ifname, tid);
2011 if (system(buf) != 0) {
2012 sigma_dut_print(dut, DUT_MSG_ERROR,
2013 "wifitool senddelba failed");
2014 }
2015
2016 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64",
2017 ifname, tid);
2018 if (system(buf) != 0) {
2019 sigma_dut_print(dut, DUT_MSG_ERROR,
2020 "wifitool sendaddba failed");
2021 }
2022
2023 return 1;
2024 }
2025
2026
mac80211_debug_enable_addba_req(struct sigma_dut * dut,int tid,const char * sta_mac,const char * dir_path,int * ret)2027 static int mac80211_debug_enable_addba_req(struct sigma_dut *dut, int tid,
2028 const char *sta_mac,
2029 const char *dir_path, int *ret)
2030 {
2031 DIR *dir;
2032 struct dirent *entry;
2033 char buf[128], path[128];
2034 int res;
2035 struct stat s;
2036
2037 *ret = 0;
2038
2039 dir = opendir(dir_path);
2040 if (!dir)
2041 return *ret;
2042
2043 while ((entry = readdir(dir))) {
2044 if (strcmp(entry->d_name, ".") == 0 ||
2045 strcmp(entry->d_name, "..") == 0)
2046 continue;
2047
2048 res = snprintf(path, sizeof(path) - 1, "%s/%s",
2049 dir_path, entry->d_name);
2050 if (res < 0 || res >= sizeof(path))
2051 continue;
2052
2053 if (strcmp(entry->d_name, sta_mac) == 0) {
2054 res = snprintf(buf, sizeof(buf),
2055 "%s/aggr_mode", path);
2056 if (res < 0 || res >= sizeof(buf) || stat(buf, &s) != 0)
2057 continue;
2058
2059 res = snprintf(buf, sizeof(buf),
2060 "%s/addba", path);
2061 if (res < 0 || res >= sizeof(buf) || stat(buf, &s) != 0)
2062 continue;
2063
2064 *ret = 1;
2065
2066 res = snprintf(buf, sizeof(buf),
2067 "echo 1 > %s/aggr_mode", path);
2068 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
2069 *ret = 0;
2070 sigma_dut_print(dut, DUT_MSG_ERROR,
2071 "Failed to set aggr mode for %s",
2072 sta_mac);
2073 }
2074
2075 res = snprintf(buf, sizeof(buf),
2076 "echo %d 32 > %s/addba", tid, path);
2077 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
2078 *ret = 0;
2079 sigma_dut_print(dut, DUT_MSG_ERROR,
2080 "Failed to set addbareq for %s",
2081 sta_mac);
2082 }
2083
2084 break;
2085 }
2086
2087 /* Recursively search subdirectories */
2088 if (!*ret)
2089 mac80211_debug_enable_addba_req(dut, tid, sta_mac, path,
2090 ret);
2091 }
2092
2093 closedir(dir);
2094
2095 return *ret;
2096 }
2097
2098
mac80211_ap_send_addba_req(struct sigma_dut * dut,struct sigma_cmd * cmd)2099 static int mac80211_ap_send_addba_req(struct sigma_dut *dut,
2100 struct sigma_cmd *cmd)
2101 {
2102 const char *val;
2103 int tid = 0, ret;
2104
2105 val = get_param(cmd, "TID");
2106 if (val)
2107 tid = atoi(val);
2108
2109 val = get_param(cmd, "sta_mac_address");
2110 if (!val) {
2111 sigma_dut_print(dut, DUT_MSG_ERROR,
2112 "Failed to parse station MAC address");
2113 return 0;
2114 }
2115
2116 mac80211_debug_enable_addba_req(dut, tid, val,
2117 "/sys/kernel/debug/ieee80211",
2118 &ret);
2119 return ret;
2120 }
2121
2122
cmd_ap_send_addba_req(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)2123 static enum sigma_cmd_result cmd_ap_send_addba_req(struct sigma_dut *dut,
2124 struct sigma_conn *conn,
2125 struct sigma_cmd *cmd)
2126 {
2127 /* const char *name = get_param(cmd, "NAME"); */
2128 /* const char *ifname = get_param(cmd, "INTERFACE"); */
2129 int ret;
2130
2131 switch (get_driver_type(dut)) {
2132 case DRIVER_ATHEROS:
2133 return ath_ap_send_addba_req(dut, conn, cmd);
2134 #ifdef __linux__
2135 case DRIVER_WIL6210:
2136 return send_addba_60g(dut, conn, cmd, "sta_mac_address");
2137 #endif /* __linux__ */
2138 case DRIVER_OPENWRT:
2139 switch (get_openwrt_driver_type()) {
2140 case OPENWRT_DRIVER_ATHEROS:
2141 return ath_ap_send_addba_req(dut, conn, cmd);
2142 default:
2143 send_resp(dut, conn, SIGMA_ERROR,
2144 "errorCode,ap_send_addba_req not supported with this driver");
2145 return 0;
2146 }
2147 case DRIVER_WCN:
2148 case DRIVER_LINUX_WCN:
2149 /* AP automatically sends ADDBA request after association. */
2150 sigma_dut_print(dut, DUT_MSG_INFO,
2151 "ap_send_addba_req command ignored");
2152 return 1;
2153 case DRIVER_MAC80211:
2154 ret = mac80211_ap_send_addba_req(dut, cmd);
2155 if (ret)
2156 return ret;
2157 /* fall through */
2158 default:
2159 send_resp(dut, conn, SIGMA_ERROR,
2160 "errorCode,ap_send_addba_req not supported with this driver");
2161 return 0;
2162 }
2163 }
2164
2165
get_sae_pk_key(const char * file_name)2166 static const char * get_sae_pk_key(const char *file_name)
2167 {
2168 if (strcasecmp(file_name, "saepk1.pem") == 0)
2169 return SAE_PK_KEY_1;
2170 if (strcasecmp(file_name, "saepk2.pem") == 0)
2171 return SAE_PK_KEY_2;
2172 if (strcasecmp(file_name, "saepkP256.pem") == 0)
2173 return SAE_PK_KEY_P256;
2174 if (strcasecmp(file_name, "saepkP384.pem") == 0)
2175 return SAE_PK_KEY_P384;
2176 if (strcasecmp(file_name, "saepkP521.pem") == 0)
2177 return SAE_PK_KEY_P521;
2178 return NULL;
2179 }
2180
2181
cmd_ap_set_security(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)2182 static enum sigma_cmd_result cmd_ap_set_security(struct sigma_dut *dut,
2183 struct sigma_conn *conn,
2184 struct sigma_cmd *cmd)
2185 {
2186 /* const char *name = get_param(cmd, "NAME"); */
2187 const char *val;
2188 unsigned int wlan_tag = 1;
2189 const char *security;
2190
2191 val = get_param(cmd, "WLAN_TAG");
2192 if (val)
2193 wlan_tag = atoi(val);
2194
2195 security = get_param(cmd, "Security");
2196
2197 if (wlan_tag > 1) {
2198 val = get_param(cmd, "KEYMGNT");
2199 if (!val)
2200 val = get_param(cmd, "KeyMgmtType");
2201 if (val) {
2202 if (strcasecmp(val, "NONE") == 0) {
2203 dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OPEN;
2204 } else if (strcasecmp(val, "OSEN") == 0 &&
2205 wlan_tag == 2) {
2206 /*
2207 * OSEN only supported on WLAN_TAG = 2 for now
2208 */
2209 dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OSEN;
2210 } else if (strcasecmp(val, "WPA2-PSK") == 0 ||
2211 (security &&
2212 strcasecmp(security, "PSK") == 0 &&
2213 strcasecmp(val, "WPA2") == 0)) {
2214 dut->ap_tag_key_mgmt[wlan_tag - 2] =
2215 AP2_WPA2_PSK;
2216 } else if (strcasecmp(val, "OWE") == 0 &&
2217 wlan_tag == 2) {
2218 dut->ap_tag_key_mgmt[wlan_tag - 2] =
2219 AP2_WPA2_OWE;
2220 } else {
2221 send_resp(dut, conn, SIGMA_INVALID,
2222 "errorCode,Unsupported KEYMGNT");
2223 return 0;
2224 }
2225 return 1;
2226 }
2227 }
2228
2229 val = get_param(cmd, "KEYMGNT");
2230 if (!val)
2231 val = get_param(cmd,"KeyMgmtType");
2232 if (val) {
2233 if (strcasecmp(val, "WPA2-PSK") == 0 ||
2234 (security && strcasecmp(security, "PSK") == 0 &&
2235 strcasecmp(val, "WPA2") == 0)) {
2236 dut->ap_key_mgmt = AP_WPA2_PSK;
2237 dut->ap_cipher = AP_CCMP;
2238 } else if (strcasecmp(val, "WPA2-EAP") == 0 ||
2239 strcasecmp(val, "WPA2-Ent") == 0) {
2240 dut->ap_key_mgmt = AP_WPA2_EAP;
2241 dut->ap_cipher = AP_CCMP;
2242 } else if (strcasecmp(val, "SuiteB") == 0) {
2243 dut->ap_key_mgmt = AP_SUITEB;
2244 dut->ap_cipher = AP_GCMP_256;
2245 dut->ap_pmf = AP_PMF_REQUIRED;
2246 } else if (strcasecmp(val, "WPA-PSK") == 0) {
2247 dut->ap_key_mgmt = AP_WPA_PSK;
2248 dut->ap_cipher = AP_TKIP;
2249 } else if (strcasecmp(val, "WPA-EAP") == 0 ||
2250 strcasecmp(val, "WPA-Ent") == 0) {
2251 dut->ap_key_mgmt = AP_WPA_EAP;
2252 dut->ap_cipher = AP_TKIP;
2253 } else if (strcasecmp(val, "WPA2-Mixed") == 0) {
2254 dut->ap_key_mgmt = AP_WPA2_EAP_MIXED;
2255 dut->ap_cipher = AP_CCMP_TKIP;
2256 } else if (strcasecmp(val, "WPA2-PSK-Mixed") == 0) {
2257 dut->ap_key_mgmt = AP_WPA2_PSK_MIXED;
2258 dut->ap_cipher = AP_CCMP_TKIP;
2259 } else if (strcasecmp(val, "WPA2-SAE") == 0 ||
2260 strcasecmp(val, "SAE") == 0) {
2261 dut->ap_key_mgmt = AP_WPA2_SAE;
2262 dut->ap_cipher = AP_CCMP;
2263 dut->ap_pmf = AP_PMF_REQUIRED;
2264 } else if (strcasecmp(val, "WPA2-PSK-SAE") == 0) {
2265 dut->ap_key_mgmt = AP_WPA2_PSK_SAE;
2266 dut->ap_cipher = AP_CCMP;
2267 dut->ap_pmf = AP_PMF_OPTIONAL;
2268 } else if (strcasecmp(val, "OWE") == 0) {
2269 dut->ap_key_mgmt = AP_WPA2_OWE;
2270 dut->ap_cipher = AP_CCMP;
2271 dut->ap_pmf = AP_PMF_REQUIRED;
2272 } else if (strcasecmp(val, "WPA2-ENT-OSEN") == 0) {
2273 dut->ap_key_mgmt = AP_WPA2_EAP_OSEN;
2274 dut->ap_cipher = AP_CCMP;
2275 dut->ap_pmf = AP_PMF_OPTIONAL;
2276 } else if (strcasecmp(val, "OSEN") == 0) {
2277 dut->ap_key_mgmt = AP_OSEN;
2278 dut->ap_cipher = AP_CCMP;
2279 } else if (strcasecmp(val, "FT-EAP") == 0) {
2280 dut->ap_key_mgmt = AP_WPA2_FT_EAP;
2281 dut->ap_cipher = AP_CCMP;
2282 dut->ap_pmf = AP_PMF_OPTIONAL;
2283 } else if (strcasecmp(val, "FT-PSK") == 0) {
2284 dut->ap_key_mgmt = AP_WPA2_FT_PSK;
2285 dut->ap_cipher = AP_CCMP;
2286 dut->ap_pmf = AP_PMF_OPTIONAL;
2287 } else if (strcasecmp(val, "WPA2-ENT-256") == 0) {
2288 dut->ap_key_mgmt = AP_WPA2_EAP_SHA256;
2289 dut->ap_cipher = AP_CCMP;
2290 dut->ap_pmf = AP_PMF_OPTIONAL;
2291 } else if (strcasecmp(val, "WPA2-PSK-256") == 0) {
2292 dut->ap_key_mgmt = AP_WPA2_PSK_SHA256;
2293 dut->ap_cipher = AP_CCMP;
2294 dut->ap_pmf = AP_PMF_OPTIONAL;
2295 } else if (strcasecmp(val, "WPA2-ENT-FT-EAP") == 0) {
2296 dut->ap_key_mgmt = AP_WPA2_ENT_FT_EAP;
2297 dut->ap_cipher = AP_CCMP;
2298 dut->ap_pmf = AP_PMF_OPTIONAL;
2299 } else if (strcasecmp(val, "NONE") == 0) {
2300 dut->ap_key_mgmt = AP_OPEN;
2301 dut->ap_cipher = AP_PLAIN;
2302 } else {
2303 send_resp(dut, conn, SIGMA_INVALID,
2304 "errorCode,Unsupported KEYMGNT");
2305 return 0;
2306 }
2307 }
2308
2309 val = get_param(cmd, "ECGroupID");
2310 if (val) {
2311 free(dut->ap_sae_groups);
2312 dut->ap_sae_groups = strdup(val);
2313 }
2314
2315 val = get_param(cmd, "AntiCloggingThreshold");
2316 if (val)
2317 dut->sae_anti_clogging_threshold = atoi(val);
2318
2319 val = get_param(cmd, "Reflection");
2320 if (val)
2321 dut->sae_reflection = strcasecmp(val, "SAE") == 0;
2322
2323 val = get_param(cmd, "InvalidSAEElement");
2324 if (val) {
2325 free(dut->sae_commit_override);
2326 dut->sae_commit_override = strdup(val);
2327 }
2328
2329 val = get_param(cmd, "SAEPasswords");
2330 if (val) {
2331 free(dut->ap_sae_passwords);
2332 dut->ap_sae_passwords = strdup(val);
2333 }
2334
2335 val = get_param(cmd, "SAE_Commit_StatusCode");
2336 if (val)
2337 dut->ap_sae_commit_status = atoi(val);
2338
2339 val = get_param(cmd, "SAE_PK_Omit");
2340 if (val)
2341 dut->ap_sae_pk_omit = get_enable_disable(val);
2342
2343 val = get_param(cmd, "SAE_Confirm_Immediate");
2344 if (val)
2345 dut->sae_confirm_immediate = get_enable_disable(val);
2346
2347 val = get_param(cmd, "sae_pwe");
2348 if (val) {
2349 if (strcasecmp(val, "h2e") == 0) {
2350 dut->sae_pwe = SAE_PWE_H2E;
2351 } else if (strcasecmp(val, "loop") == 0 ||
2352 strcasecmp(val, "looping") == 0) {
2353 dut->sae_pwe = SAE_PWE_LOOP;
2354 } else {
2355 send_resp(dut, conn, SIGMA_ERROR,
2356 "errorCode,Unsupported sae_pwe value");
2357 return STATUS_SENT_ERROR;
2358 }
2359 }
2360
2361 val = get_param(cmd, "sae_pk");
2362 if (val)
2363 dut->ap_sae_pk = atoi(val);
2364
2365 val = get_param(cmd, "SAE_PK_KeyPair");
2366 if (!val)
2367 val = get_param(cmd, "SAE_PK_KeyPairMism");
2368 if (val) {
2369 free(dut->ap_sae_pk_keypair);
2370 dut->ap_sae_pk_keypair = NULL;
2371
2372 val = get_sae_pk_key(val);
2373 if (val)
2374 dut->ap_sae_pk_keypair = strdup(val);
2375
2376 if (!dut->ap_sae_pk_keypair) {
2377 send_resp(dut, conn, SIGMA_ERROR,
2378 "errorCode,Unknown SAE_PK_KeyPair value");
2379 return STATUS_SENT_ERROR;
2380 }
2381 }
2382
2383 val = get_param(cmd, "SAE_PK_KeyPairSigOverride");
2384 if (val) {
2385 free(dut->ap_sae_pk_keypair_sig);
2386 dut->ap_sae_pk_keypair_sig = NULL;
2387
2388 val = get_sae_pk_key(val);
2389 if (val)
2390 dut->ap_sae_pk_keypair_sig = strdup(val);
2391
2392 if (!dut->ap_sae_pk_keypair_sig) {
2393 send_resp(dut, conn, SIGMA_ERROR,
2394 "errorCode,Unknown SAE_PK_KeyPairSigOverride value");
2395 return STATUS_SENT_ERROR;
2396 }
2397 }
2398
2399 val = get_param(cmd, "SAE_PK_Modifier");
2400 if (!val)
2401 val = get_param(cmd, "SAE_PK_ModifierMism");
2402 if (val) {
2403 free(dut->ap_sae_pk_modifier);
2404 dut->ap_sae_pk_modifier = strdup(val);
2405 }
2406
2407 val = get_param(cmd, "RSNXE_Content");
2408 if (val) {
2409 if (strncasecmp(val, "EapolM3:", 8) != 0) {
2410 send_resp(dut, conn, SIGMA_ERROR,
2411 "errorCode,Unsupported RSNXE_Content value");
2412 return STATUS_SENT_ERROR;
2413 }
2414 val += 8;
2415 free(dut->rsnxe_override_eapol);
2416 dut->rsnxe_override_eapol = strdup(val);
2417 }
2418
2419 val = get_param(cmd, "ENCRYPT");
2420 if (!val)
2421 val = get_param(cmd, "EncpType");
2422 if (val) {
2423 if (strcasecmp(val, "WEP") == 0) {
2424 dut->ap_cipher = AP_WEP;
2425 } else if (strcasecmp(val, "TKIP") == 0) {
2426 dut->ap_cipher = AP_TKIP;
2427 } else if (strcasecmp(val, "AES") == 0 ||
2428 strcasecmp(val, "AES-CCMP") == 0) {
2429 dut->ap_cipher = AP_CCMP;
2430 } else if (strcasecmp(val, "AES-GCMP") == 0) {
2431 dut->ap_cipher = AP_GCMP_128;
2432 } else {
2433 send_resp(dut, conn, SIGMA_INVALID,
2434 "errorCode,Unsupported ENCRYPT");
2435 return 0;
2436 }
2437 }
2438
2439 val = get_param(cmd, "PairwiseCipher");
2440 if (val) {
2441 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2442 dut->ap_cipher = AP_GCMP_256;
2443 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2444 dut->ap_cipher = AP_CCMP_256;
2445 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2446 dut->ap_cipher = AP_GCMP_128;
2447 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2448 dut->ap_cipher = AP_CCMP;
2449 } else if (strcasecmp(val, "AES-CCMP-128 AES-GCMP-256") == 0 ||
2450 strcasecmp(val, "AES-GCMP-256 AES-CCMP-128") == 0) {
2451 dut->ap_cipher = AP_CCMP_128_GCMP_256;
2452 } else {
2453 send_resp(dut, conn, SIGMA_INVALID,
2454 "errorCode,Unsupported PairwiseCipher");
2455 return 0;
2456 }
2457 }
2458
2459 val = get_param(cmd, "GroupCipher");
2460 if (val) {
2461 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2462 dut->ap_group_cipher = AP_GCMP_256;
2463 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2464 dut->ap_group_cipher = AP_CCMP_256;
2465 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2466 dut->ap_group_cipher = AP_GCMP_128;
2467 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2468 dut->ap_group_cipher = AP_CCMP;
2469 } else {
2470 send_resp(dut, conn, SIGMA_INVALID,
2471 "errorCode,Unsupported GroupCipher");
2472 return 0;
2473 }
2474 }
2475
2476 val = get_param(cmd, "GroupMgntCipher");
2477 if (val) {
2478 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2479 dut->ap_group_mgmt_cipher = AP_BIP_GMAC_256;
2480 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2481 dut->ap_group_mgmt_cipher = AP_BIP_CMAC_256;
2482 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2483 dut->ap_group_mgmt_cipher = AP_BIP_GMAC_128;
2484 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2485 dut->ap_group_mgmt_cipher = AP_BIP_CMAC_128;
2486 } else {
2487 send_resp(dut, conn, SIGMA_INVALID,
2488 "errorCode,Unsupported GroupMgntCipher");
2489 return 0;
2490 }
2491 }
2492
2493 val = get_param(cmd, "WEPKEY");
2494 if (val) {
2495 size_t len;
2496 if (dut->ap_cipher != AP_WEP) {
2497 send_resp(dut, conn, SIGMA_INVALID,
2498 "errorCode,Unexpected WEPKEY without WEP "
2499 "configuration");
2500 return 0;
2501 }
2502 len = strlen(val);
2503 if (len != 10 && len != 26) {
2504 send_resp(dut, conn, SIGMA_INVALID,
2505 "errorCode,Unexpected WEPKEY length");
2506 return 0;
2507 }
2508 snprintf(dut->ap_wepkey, sizeof(dut->ap_wepkey), "%s", val);
2509 }
2510
2511 val = get_param(cmd, "PSK");
2512 if (!val)
2513 val = get_param(cmd, "passphrase");
2514 if (val) {
2515 if (dut->ap_key_mgmt != AP_WPA2_SAE &&
2516 (dut->ap_akm_values & (AKM_WPA_PSK | AKM_SAE)) !=
2517 AKM_SAE &&
2518 strlen(val) > 64) {
2519 sigma_dut_print(dut, DUT_MSG_ERROR,
2520 "Too long PSK/passphtase");
2521 return -1;
2522 }
2523 if (strlen(val) > sizeof(dut->ap_passphrase) - 1)
2524 return -1;
2525 snprintf(dut->ap_passphrase, sizeof(dut->ap_passphrase),
2526 "%s", val);
2527 }
2528
2529 val = get_param(cmd, "PSKHEX");
2530 if (val) {
2531 if (strlen(val) != 64)
2532 return -1;
2533 strlcpy(dut->ap_psk, val, sizeof(dut->ap_psk));
2534 }
2535
2536 if (dut->program == PROGRAM_OCE && dut->dev_role == DEVROLE_STA_CFON)
2537 dut->ap_pmf = AP_PMF_OPTIONAL;
2538
2539 val = get_param(cmd, "PMF");
2540 if (val) {
2541 if (strcasecmp(val, "Disabled") == 0) {
2542 dut->ap_pmf = AP_PMF_DISABLED;
2543 } else if (strcasecmp(val, "Optional") == 0) {
2544 dut->ap_pmf = AP_PMF_OPTIONAL;
2545 } else if (strcasecmp(val, "Required") == 0) {
2546 dut->ap_pmf = AP_PMF_REQUIRED;
2547 } else {
2548 send_resp(dut, conn, SIGMA_INVALID,
2549 "errorCode,Unsupported PMF");
2550 return 0;
2551 }
2552 }
2553
2554 dut->ap_add_sha256 = 0;
2555 val = get_param(cmd, "SHA256AD");
2556 if (val == NULL)
2557 val = get_param(cmd, "SHA256");
2558 if (val) {
2559 if (strcasecmp(val, "Disabled") == 0) {
2560 } else if (strcasecmp(val, "Enabled") == 0) {
2561 dut->ap_add_sha256 = 1;
2562 } else {
2563 send_resp(dut, conn, SIGMA_INVALID,
2564 "errorCode,Unsupported SHA256");
2565 return 0;
2566 }
2567 }
2568
2569 val = get_param(cmd, "PreAuthentication");
2570 if (val) {
2571 if (strcasecmp(val, "disabled") == 0) {
2572 dut->ap_rsn_preauth = 0;
2573 } else if (strcasecmp(val, "enabled") == 0) {
2574 dut->ap_rsn_preauth = 1;
2575 } else {
2576 send_resp(dut, conn, SIGMA_INVALID,
2577 "errorCode,Unsupported PreAuthentication value");
2578 return 0;
2579 }
2580 }
2581
2582 val = get_param(cmd, "AKMSuiteType");
2583 if (val) {
2584 const char *in_pos = val;
2585
2586 dut->ap_akm_values = 0;
2587 while (*in_pos) {
2588 int akm = atoi(in_pos);
2589
2590 if (akm < 0 || akm >= 32) {
2591 send_resp(dut, conn, SIGMA_ERROR,
2592 "errorCode,Unsupported AKMSuiteType value");
2593 return STATUS_SENT;
2594 }
2595
2596 dut->ap_akm_values |= 1 << akm;
2597
2598 in_pos = strchr(in_pos, ';');
2599 if (!in_pos)
2600 break;
2601 while (*in_pos == ';')
2602 in_pos++;
2603 }
2604 dut->ap_akm = 1;
2605 if (dut->ap_akm_values & (1 << 14))
2606 dut->ap_add_sha384 = 1;
2607 if (dut->ap_akm_values & (1 << 15))
2608 dut->ap_add_sha384 = 1;
2609 }
2610
2611 if (dut->ap_key_mgmt == AP_OPEN && !dut->ap_akm_values) {
2612 dut->ap_hs2 = 0;
2613 dut->ap_pmf = AP_PMF_DISABLED;
2614 }
2615
2616 val = get_param(cmd, "PMKSACaching");
2617 if (val) {
2618 dut->ap_pmksa = 1;
2619 if (strcasecmp(val, "disabled") == 0) {
2620 dut->ap_pmksa_caching = 1;
2621 } else if (strcasecmp(val, "enabled") == 0) {
2622 dut->ap_pmksa_caching = 0;
2623 } else {
2624 send_resp(dut, conn, SIGMA_INVALID,
2625 "errorCode,Unsupported PMKSACaching value");
2626 return 0;
2627 }
2628 }
2629
2630 val = get_param(cmd, "BeaconProtection");
2631 if (val)
2632 dut->ap_beacon_prot = atoi(val);
2633
2634 val = get_param(cmd, "Transition_Disable");
2635 if (val) {
2636 if (atoi(val)) {
2637 val = get_param(cmd, "Transition_Disable_Index");
2638 if (!val) {
2639 send_resp(dut, conn, SIGMA_INVALID,
2640 "errorCode,Transition_Disable without Transition_Disable_Index");
2641 return STATUS_SENT;
2642 }
2643 dut->ap_transition_disable = 1 << atoi(val);
2644 } else {
2645 dut->ap_transition_disable = 0;
2646 }
2647 }
2648
2649 return 1;
2650 }
2651
2652
sta_cfon_set_wireless(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)2653 int sta_cfon_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
2654 struct sigma_cmd *cmd)
2655 {
2656 int status;
2657
2658 status = cmd_ap_set_wireless(dut, conn, cmd);
2659 if (status != 1)
2660 return status;
2661 status = cmd_ap_set_security(dut, conn, cmd);
2662 if (status != 1)
2663 return status;
2664 return cmd_ap_config_commit(dut, conn, cmd);
2665 }
2666
2667
cmd_ap_set_radius(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)2668 static enum sigma_cmd_result cmd_ap_set_radius(struct sigma_dut *dut,
2669 struct sigma_conn *conn,
2670 struct sigma_cmd *cmd)
2671 {
2672 /* const char *name = get_param(cmd, "NAME"); */
2673 const char *val;
2674 unsigned int wlan_tag = 1, radius_port = 0;
2675 char *radius_ipaddr = NULL, *radius_password = NULL;
2676
2677 val = get_param(cmd, "WLAN_TAG");
2678 if (val) {
2679 wlan_tag = atoi(val);
2680 if (wlan_tag != 1 && wlan_tag != 2) {
2681 send_resp(dut, conn, SIGMA_INVALID,
2682 "errorCode,Invalid WLAN_TAG");
2683 return 0;
2684 }
2685 }
2686
2687 val = get_param(cmd, "PORT");
2688 if (val)
2689 radius_port = atoi(val);
2690
2691 if (wlan_tag == 1) {
2692 if (radius_port)
2693 dut->ap_radius_port = radius_port;
2694 radius_ipaddr = dut->ap_radius_ipaddr;
2695 radius_password = dut->ap_radius_password;
2696 } else if (wlan_tag == 2) {
2697 if (radius_port)
2698 dut->ap2_radius_port = radius_port;
2699 radius_ipaddr = dut->ap2_radius_ipaddr;
2700 radius_password = dut->ap2_radius_password;
2701 }
2702
2703 val = get_param(cmd, "IPADDR");
2704 if (val) {
2705 if (strlen(val) > sizeof(dut->ap_radius_ipaddr) - 1)
2706 return -1;
2707 snprintf(radius_ipaddr, sizeof(dut->ap_radius_ipaddr),
2708 "%s", val);
2709 }
2710
2711 val = get_param(cmd, "PASSWORD");
2712 if (val) {
2713 if (strlen(val) > sizeof(dut->ap_radius_password) - 1)
2714 return -1;
2715 snprintf(radius_password,
2716 sizeof(dut->ap_radius_password), "%s", val);
2717 }
2718
2719 return 1;
2720 }
2721
2722
owrt_ap_set_qcawifi(struct sigma_dut * dut,const char * key,const char * val)2723 static void owrt_ap_set_qcawifi(struct sigma_dut *dut, const char *key,
2724 const char *val)
2725 {
2726 if (!val) {
2727 run_system_wrapper(dut, "uci delete wireless.qcawifi.%s", key);
2728 return;
2729 }
2730
2731 run_system(dut, "uci set wireless.qcawifi=qcawifi");
2732 run_system_wrapper(dut, "uci set wireless.qcawifi.%s=%s", key, val);
2733 }
2734
2735
owrt_ap_set_radio(struct sigma_dut * dut,int id,const char * key,const char * val)2736 static void owrt_ap_set_radio(struct sigma_dut *dut, int id,
2737 const char *key, const char *val)
2738 {
2739 char buf[100];
2740
2741 if (val == NULL) {
2742 snprintf(buf, sizeof(buf),
2743 "uci delete wireless.wifi%d.%s", id, key);
2744 run_system(dut, buf);
2745 return;
2746 }
2747
2748 snprintf(buf, sizeof(buf), "uci set wireless.wifi%d.%s=%s",
2749 id, key, val);
2750 run_system(dut, buf);
2751 }
2752
2753
owrt_ap_set_list_radio(struct sigma_dut * dut,int id,const char * key,const char * val)2754 static void owrt_ap_set_list_radio(struct sigma_dut *dut, int id,
2755 const char *key, const char *val)
2756 {
2757 char buf[256];
2758
2759 if (val == NULL) {
2760 snprintf(buf, sizeof(buf),
2761 "uci del_list wireless.wifi%d.%s", id, key);
2762 run_system(dut, buf);
2763 return;
2764 }
2765
2766 snprintf(buf, sizeof(buf), "uci add_list wireless.wifi%d.%s=%s",
2767 id, key, val);
2768 run_system(dut, buf);
2769 }
2770
2771
owrt_ap_set_vap(struct sigma_dut * dut,int id,const char * key,const char * val)2772 static void owrt_ap_set_vap(struct sigma_dut *dut, int id, const char *key,
2773 const char *val)
2774 {
2775 char buf[256];
2776
2777 if (val == NULL) {
2778 snprintf(buf, sizeof(buf),
2779 "uci delete wireless.@wifi-iface[%d].%s", id, key);
2780 run_system(dut, buf);
2781 return;
2782 }
2783
2784 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2785 id, key, val);
2786 run_system(dut, buf);
2787 }
2788
2789
owrt_ap_set_list_vap(struct sigma_dut * dut,int id,const char * key,const char * val)2790 static void owrt_ap_set_list_vap(struct sigma_dut *dut, int id,
2791 const char *key, const char *val)
2792 {
2793 char buf[1024];
2794
2795 if (val == NULL) {
2796 snprintf(buf, sizeof(buf),
2797 "uci del_list wireless.@wifi-iface[%d].%s", id, key);
2798 run_system(dut, buf);
2799 return;
2800 }
2801
2802 snprintf(buf, sizeof(buf),
2803 "uci add_list wireless.@wifi-iface[%d].%s=%s",
2804 id, key, val);
2805 run_system(dut, buf);
2806 }
2807
2808
owrt_ap_add_vap(struct sigma_dut * dut,int id,const char * key,const char * val)2809 static void owrt_ap_add_vap(struct sigma_dut *dut, int id, const char *key,
2810 const char *val)
2811 {
2812 char buf[256];
2813 int res;
2814
2815 if (val == NULL) {
2816 res = snprintf(buf, sizeof(buf),
2817 "uci delete wireless.@wifi-iface[%d].%s",
2818 id, key);
2819 if (res >= 0 && res < sizeof(buf))
2820 run_system(dut, buf);
2821 return;
2822 }
2823
2824 run_system(dut, "uci add wireless wifi-iface");
2825 res = snprintf(buf, sizeof(buf),
2826 "uci set wireless.@wifi-iface[%d].%s=%s",
2827 id, key, val);
2828 if (res >= 0 && res < sizeof(buf))
2829 run_system(dut, buf);
2830 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2831 id, "network", "lan");
2832 run_system(dut, buf);
2833 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2834 id, "mode", "ap");
2835 run_system(dut, buf);
2836 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s",
2837 id, "encryption", "none");
2838 run_system(dut, buf);
2839 }
2840
2841
2842 #define OPENWRT_MAX_NUM_RADIOS (MAX_RADIO + 1)
owrt_ap_config_radio(struct sigma_dut * dut)2843 static int owrt_ap_config_radio(struct sigma_dut *dut)
2844 {
2845 int radio_id[MAX_RADIO] = { 0, 1, 2 };
2846 int radio_count, radio_no;
2847 char buf[64];
2848
2849 for (radio_count = 0; radio_count < OPENWRT_MAX_NUM_RADIOS;
2850 radio_count++) {
2851 snprintf(buf, sizeof(buf), "%s%d", "wifi", radio_count);
2852 for (radio_no = 0; radio_no < MAX_RADIO; radio_no++) {
2853 if (!sigma_radio_ifname[radio_no] ||
2854 strcmp(sigma_radio_ifname[radio_no], buf) != 0)
2855 continue;
2856 owrt_ap_set_radio(dut, radio_count, "disabled", "0");
2857 owrt_ap_set_vap(dut, radio_count, "device", buf);
2858 radio_id[radio_no] = radio_count;
2859 }
2860 }
2861
2862 /* Hardware mode (11a/b/g/n/ac) & HT mode selection */
2863 switch (dut->ap_mode) {
2864 case AP_11g:
2865 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11g");
2866 break;
2867 case AP_11b:
2868 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11b");
2869 break;
2870 case AP_11ng:
2871 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng");
2872 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2873 break;
2874 case AP_11a:
2875 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11a");
2876 break;
2877 case AP_11na:
2878 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11na");
2879 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2880 break;
2881 case AP_11ac:
2882 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ac");
2883 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2884 break;
2885 case AP_11ax:
2886 if (dut->ap_channel >= 36) {
2887 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axa");
2888 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2889 } else {
2890 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axg");
2891 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2892 }
2893 break;
2894 case AP_inval:
2895 sigma_dut_print(dut, DUT_MSG_ERROR,
2896 "MODE NOT SPECIFIED!");
2897 return -1;
2898 default:
2899 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng");
2900 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2901 break;
2902 }
2903
2904 if (dut->ap_is_dual) {
2905 /* Hardware mode (11a/b/g/n/ac) & HT mode selection */
2906 switch (dut->ap_mode_1) {
2907 case AP_11g:
2908 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11g");
2909 break;
2910 case AP_11b:
2911 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11b");
2912 break;
2913 case AP_11ng:
2914 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng");
2915 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2916 break;
2917 case AP_11a:
2918 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11a");
2919 break;
2920 case AP_11na:
2921 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11na");
2922 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2923 break;
2924 case AP_11ac:
2925 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ac");
2926 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT80");
2927 break;
2928 case AP_11ax:
2929 if (dut->ap_channel >= 36) {
2930 owrt_ap_set_radio(dut, radio_id[1],
2931 "hwmode", "11axa");
2932 owrt_ap_set_radio(dut, radio_id[1],
2933 "htmode", "HT80");
2934 } else {
2935 owrt_ap_set_radio(dut, radio_id[1],
2936 "hwmode", "11axg");
2937 owrt_ap_set_radio(dut, radio_id[1],
2938 "htmode", "HT20");
2939 }
2940 break;
2941 case AP_inval:
2942 sigma_dut_print(dut, DUT_MSG_ERROR,
2943 "MODE NOT SPECIFIED!");
2944 return -1;
2945 default:
2946 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng");
2947 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20");
2948 break;
2949 }
2950
2951 }
2952
2953 /* Channel */
2954 snprintf(buf, sizeof(buf), "%d", dut->ap_channel);
2955 owrt_ap_set_radio(dut, radio_id[0], "channel", buf);
2956
2957 switch (dut->ap_chwidth) {
2958 case AP_20:
2959 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20");
2960 break;
2961 case AP_40:
2962 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT40");
2963 break;
2964 case AP_80:
2965 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80");
2966 break;
2967 case AP_160:
2968 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT160");
2969 break;
2970 case AP_80_80:
2971 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80_80");
2972 break;
2973 case AP_AUTO:
2974 default:
2975 break;
2976 }
2977
2978 if (dut->ap_channel == 140 || dut->ap_channel == 144) {
2979 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
2980 owrt_ap_set_radio(dut, radio_id[0], "set_ch_144", "3");
2981 }
2982
2983 if (dut->ap_is_dual) {
2984 snprintf(buf, sizeof(buf), "%d", dut->ap_channel_1);
2985 owrt_ap_set_radio(dut, radio_id[1], "channel", buf);
2986 }
2987
2988 /* Country Code */
2989 if (dut->ap_reg_domain == REG_DOMAIN_GLOBAL) {
2990 const char *country;
2991
2992 country = dut->ap_countrycode[0] ? dut->ap_countrycode : "US";
2993 snprintf(buf, sizeof(buf), "%s4", country);
2994 owrt_ap_set_radio(dut, radio_id[0], "country", buf);
2995 if (dut->ap_is_dual)
2996 owrt_ap_set_radio(dut, radio_id[1], "country", buf);
2997 } else if (dut->ap_countrycode[0]) {
2998 owrt_ap_set_radio(dut, radio_id[0], "country",
2999 dut->ap_countrycode);
3000 }
3001
3002 if (dut->ap_disable_protection == 1) {
3003 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'0 0'");
3004 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'1 0'");
3005 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'2 0'");
3006 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'3 0'");
3007 }
3008
3009 if (dut->ap_oce == VALUE_ENABLED &&
3010 get_driver_type(dut) == DRIVER_OPENWRT)
3011 owrt_ap_set_radio(dut, radio_id[0], "bcnburst", "1");
3012
3013 if (dut->ap_mbssid == VALUE_ENABLED)
3014 owrt_ap_set_qcawifi(dut, "mbss_ie_enable", "1");
3015
3016 if (dut->program == PROGRAM_HE) {
3017 owrt_ap_set_radio(dut, radio_id[0], "he_bsscolor", "'1 1'");
3018 if (dut->ap_is_dual)
3019 owrt_ap_set_radio(dut, radio_id[1], "he_bsscolor",
3020 "'2 1'");
3021 owrt_ap_set_qcawifi(dut, "ap_bss_color_collision_detection",
3022 "1");
3023 }
3024
3025 return 1;
3026 }
3027
3028
owrt_ap_config_vap_hs2(struct sigma_dut * dut,int vap_id)3029 static int owrt_ap_config_vap_hs2(struct sigma_dut *dut, int vap_id)
3030 {
3031 char buf[256];
3032
3033 snprintf(buf, sizeof(buf), "%d", dut->ap_hs2);
3034 owrt_ap_set_vap(dut, vap_id, "hs20", buf);
3035 owrt_ap_set_vap(dut, vap_id, "qbssload", "1");
3036 owrt_ap_set_vap(dut, vap_id, "hs20_deauth_req_timeout","3");
3037
3038 owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name",
3039 "'eng:Wi-Fi Alliance'");
3040
3041 owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name",
3042 "'chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f'");
3043
3044 if (dut->ap_wan_metrics == 1)
3045 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3046 "'01:2500:384:0:0:10'");
3047 else if (dut->ap_wan_metrics == 1)
3048 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3049 "'01:1500:384:20:20:10'");
3050 else if (dut->ap_wan_metrics == 2)
3051 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3052 "'01:1500:384:20:20:10'");
3053 else if (dut->ap_wan_metrics == 3)
3054 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3055 "'01:2000:1000:20:20:10'");
3056 else if (dut->ap_wan_metrics == 4)
3057 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3058 "'01:8000:1000:20:20:10'");
3059 else if (dut->ap_wan_metrics == 5)
3060 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics",
3061 "'01:9000:5000:20:20:10'");
3062
3063 if (dut->ap_conn_capab == 1) {
3064 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", "'1:0:0'");
3065 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3066 "'6:20:1'");
3067 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3068 "'6:22:0'");
3069 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3070 "'6:80:1'");
3071 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3072 "'6:443:1'");
3073 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3074 "'6:1723:0'");
3075 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3076 "'6:5060:0'");
3077 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3078 "'17:500:1'");
3079 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3080 "'17:5060:0'");
3081 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3082 "'17:4500:1'");
3083 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3084 "'50:0:1'");
3085 } else if (dut->ap_conn_capab == 2) {
3086 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3087 "'6:80:1'");
3088 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3089 "'6:443:1'");
3090 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3091 "'17:5060:1'");
3092 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3093 "'6:5060:1'");
3094 } else if (dut->ap_conn_capab == 3) {
3095 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3096 "'6:80:1'");
3097 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab",
3098 "'6:443:1'");
3099 }
3100
3101 if (dut->ap_oper_class == 1)
3102 snprintf(buf, sizeof(buf), "%s", "51");
3103 else if (dut->ap_oper_class == 2)
3104 snprintf(buf, sizeof(buf), "%s", "73");
3105 else if (dut->ap_oper_class == 3)
3106 snprintf(buf, sizeof(buf), "%s", "5173");
3107
3108 if (dut->ap_oper_class)
3109 owrt_ap_set_vap(dut, vap_id, "hs20_operating_class", buf);
3110
3111 if (dut->ap_osu_provider_list) {
3112 char *osu_friendly_name = NULL;
3113 char *osu_icon = NULL;
3114 char *osu_ssid = NULL;
3115 char *osu_nai = NULL;
3116 char *osu_service_desc = NULL;
3117 char *hs20_icon_filename = NULL;
3118 char hs20_icon[150];
3119 int osu_method;
3120
3121 hs20_icon_filename = "icon_red_zxx.png";
3122 if (dut->ap_osu_icon_tag == 2)
3123 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3124 snprintf(hs20_icon, sizeof(hs20_icon),
3125 "'128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s'",
3126 hs20_icon_filename);
3127 osu_icon = "icon_red_zxx.png";
3128 osu_ssid = "OSU";
3129 osu_friendly_name = "'kor:SP 빨강 테스트 전용'";
3130 osu_service_desc = "'kor:테스트 목적으로 무료 서비스'";
3131 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 :
3132 dut->ap_osu_method[0];
3133
3134 if (strlen(dut->ap_osu_server_uri[0]))
3135 owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri",
3136 dut->ap_osu_server_uri[0]);
3137 else
3138 owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri",
3139 "'https://osu-server.r2-testbed.wi-fi.org/'");
3140 switch (dut->ap_osu_provider_list) {
3141 case 1:
3142 case 101:
3143 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3144 "'eng:SP Red Test Only'");
3145 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3146 "'eng:Free service for test purpose'");
3147 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3148 hs20_icon);
3149
3150 hs20_icon_filename = "icon_red_eng.png";
3151 if (dut->ap_osu_icon_tag == 2)
3152 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3153
3154 snprintf(hs20_icon, sizeof(hs20_icon),
3155 "'160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s'",
3156 hs20_icon_filename);
3157 owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3158 "icon_red_eng.png");
3159 break;
3160 case 2:
3161 case 102:
3162 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3163 "'eng:Wireless Broadband Alliance'");
3164 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3165 "'eng:Free service for test purpose'");
3166 hs20_icon_filename = "icon_orange_zxx.png";
3167 if (dut->ap_osu_icon_tag == 2)
3168 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3169
3170 snprintf(hs20_icon, sizeof(hs20_icon),
3171 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3172 hs20_icon_filename);
3173 osu_icon = "icon_orange_zxx.png";
3174 osu_friendly_name = "'kor:와이어리스 브로드밴드 얼라이언스'";
3175 break;
3176 case 3:
3177 case 103:
3178 osu_friendly_name = "'spa:SP Red Test Only'";
3179 osu_service_desc = "'spa:Free service for test purpose'";
3180 break;
3181 case 4:
3182 case 104:
3183 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3184 "'eng:SP Orange Test Only'");
3185 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3186 "'eng:Free service for test purpose'");
3187 hs20_icon_filename = "icon_orange_eng.png";
3188 if (dut->ap_osu_icon_tag == 2)
3189 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3190
3191 snprintf(hs20_icon, sizeof(hs20_icon),
3192 "'160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s'",
3193 hs20_icon_filename);
3194 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3195 hs20_icon);
3196 osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3197
3198 hs20_icon_filename = "icon_orange_zxx.png";
3199 if (dut->ap_osu_icon_tag == 2)
3200 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3201
3202 snprintf(hs20_icon, sizeof(hs20_icon),
3203 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3204 hs20_icon_filename);
3205 osu_icon = "icon_orange_zxx.png";
3206 break;
3207 case 5:
3208 case 105:
3209 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3210 "'eng:SP Orange Test Only'");
3211 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3212 "'eng:Free service for test purpose'");
3213 osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3214
3215 hs20_icon_filename = "icon_orange_zxx.png";
3216 if (dut->ap_osu_icon_tag == 2)
3217 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3218
3219 snprintf(hs20_icon, sizeof(hs20_icon),
3220 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3221 hs20_icon_filename);
3222 osu_icon = "icon_orange_zxx.png";
3223 break;
3224 case 6:
3225 case 106:
3226 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3227 "'eng:SP Green Test Only'");
3228 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3229 "'kor:SP 초록 테스트 전용'");
3230
3231 hs20_icon_filename = "icon_green_zxx.png";
3232 if (dut->ap_osu_icon_tag == 2)
3233 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3234
3235 snprintf(hs20_icon, sizeof(hs20_icon),
3236 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'",
3237 hs20_icon_filename);
3238 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3239 hs20_icon);
3240
3241 owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3242 "'icon_green_zxx.png'");
3243 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 :
3244 dut->ap_osu_method[0];
3245
3246 snprintf(buf, sizeof(buf), "%d", osu_method);
3247 owrt_ap_set_vap(dut, vap_id, "osu_method_list", buf);
3248
3249 if (strlen(dut->ap_osu_server_uri[1]))
3250 owrt_ap_set_list_vap(dut, vap_id,
3251 "osu_server_uri",
3252 dut->ap_osu_server_uri[1]);
3253 else
3254 owrt_ap_set_list_vap(dut, vap_id,
3255 "osu_server_uri",
3256 "'https://osu-server.r2-testbed.wi-fi.org/'");
3257
3258 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3259 "'eng:SP Orange Test Only'");
3260
3261 hs20_icon_filename = "icon_orange_zxx.png";
3262 if (dut->ap_osu_icon_tag == 2)
3263 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3264
3265 snprintf(hs20_icon, sizeof(hs20_icon),
3266 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3267 hs20_icon_filename);
3268
3269 osu_icon = "icon_orange_zxx.png";
3270 osu_friendly_name = "'kor:SP 오렌지 테스트 전용'";
3271 osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 :
3272 dut->ap_osu_method[1];
3273 osu_service_desc = NULL;
3274 break;
3275 case 7:
3276 case 107:
3277 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3278 "'eng:SP Green Test Only'");
3279 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3280 "'eng:Free service for test purpose'");
3281
3282 hs20_icon_filename = "icon_green_eng.png";
3283 if (dut->ap_osu_icon_tag == 2)
3284 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3285
3286 snprintf(hs20_icon, sizeof(hs20_icon),
3287 "'160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s'",
3288 hs20_icon_filename);
3289 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon",
3290 hs20_icon);
3291
3292 owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3293 "'icon_green_eng.png'");
3294 osu_friendly_name = "'kor:SP 초록 테스트 전용'";
3295
3296 hs20_icon_filename = "icon_green_zxx.png";
3297 if (dut->ap_osu_icon_tag == 2)
3298 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3299
3300 snprintf(hs20_icon, sizeof(hs20_icon),
3301 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'",
3302 hs20_icon_filename);
3303 osu_icon = "icon_green_zxx.png";
3304 break;
3305 case 8:
3306 case 108:
3307 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3308 "'eng:SP Red Test Only'");
3309 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3310 "'eng:Free service for test purpose'");
3311 osu_ssid = "OSU-Encrypted";
3312 osu_nai = "'anonymous@hotspot.net'";
3313 break;
3314 case 9:
3315 case 109:
3316 osu_ssid = "OSU-OSEN";
3317 osu_nai = "'test-anonymous@wi-fi.org'";
3318 osu_friendly_name = "'eng:SP Orange Test Only'";
3319 hs20_icon_filename = "icon_orange_zxx.png";
3320 if (dut->ap_osu_icon_tag == 2)
3321 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
3322
3323 snprintf(hs20_icon, sizeof(hs20_icon),
3324 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'",
3325 hs20_icon_filename);
3326 osu_icon = "icon_orange_zxx.png";
3327 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 :
3328 dut->ap_osu_method[0];
3329 osu_service_desc = NULL;
3330 break;
3331 default:
3332 break;
3333 }
3334
3335 if (strlen(dut->ap_osu_ssid)) {
3336 if (dut->ap_tag_ssid[0][0] &&
3337 strcmp(dut->ap_tag_ssid[0],
3338 dut->ap_osu_ssid) != 0 &&
3339 strcmp(dut->ap_tag_ssid[0], osu_ssid) != 0) {
3340 sigma_dut_print(dut, DUT_MSG_ERROR,
3341 "OSU_SSID and WLAN_TAG2 SSID differ");
3342 return -2;
3343 }
3344
3345 snprintf(buf, sizeof(buf), "'\"%s\"'",
3346 dut->ap_osu_ssid);
3347 } else {
3348 snprintf(buf, sizeof(buf), "'\"%s\"'", osu_ssid);
3349 }
3350
3351 owrt_ap_set_vap(dut, vap_id, "osu_ssid", buf);
3352
3353
3354 if (osu_friendly_name)
3355 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name",
3356 osu_friendly_name);
3357 if (osu_service_desc)
3358 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc",
3359 osu_service_desc);
3360 if (osu_nai)
3361 owrt_ap_set_vap(dut, vap_id, "osu_nai", osu_nai);
3362
3363 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", hs20_icon);
3364
3365 if (osu_icon)
3366 owrt_ap_set_list_vap(dut, vap_id, "osu_icon",
3367 osu_icon);
3368
3369 if (dut->ap_osu_provider_list > 100) {
3370 owrt_ap_set_list_vap(dut, vap_id, "osu_method_list",
3371 "0");
3372 } else {
3373 snprintf(buf, sizeof(buf), "%d", osu_method);
3374 owrt_ap_set_list_vap(dut, vap_id, "osu_method_list",
3375 buf);
3376 }
3377 }
3378
3379 return 0;
3380 }
3381
3382
set_anqp_elem_value(struct sigma_dut * dut,const char * ifname,char * anqp_string,size_t str_size)3383 static int set_anqp_elem_value(struct sigma_dut *dut, const char *ifname,
3384 char *anqp_string, size_t str_size)
3385 {
3386 unsigned char bssid[ETH_ALEN];
3387 unsigned char dummy_mac[] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50 };
3388 int preference = 0xff;
3389
3390 if (get_hwaddr(ifname, bssid) < 0)
3391 return -1;
3392 snprintf(anqp_string, str_size,
3393 "272:3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x",
3394 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5],
3395 preference,
3396 dummy_mac[0], dummy_mac[1], dummy_mac[2],
3397 dummy_mac[3], dummy_mac[4], dummy_mac[5],
3398 preference - 1);
3399 return 0;
3400 }
3401
3402
get_hostapd_ifname(struct sigma_dut * dut)3403 const char * get_hostapd_ifname(struct sigma_dut *dut)
3404 {
3405 enum driver_type drv;
3406
3407 /* Use the configured hostapd ifname */
3408 if (dut->hostapd_ifname && if_nametoindex(dut->hostapd_ifname) > 0)
3409 return dut->hostapd_ifname;
3410
3411 /* Use configured main ifname */
3412 if (dut->main_ifname) {
3413 if (dut->use_5g && dut->main_ifname_5g &&
3414 if_nametoindex(dut->main_ifname_5g) > 0)
3415 return dut->main_ifname_5g;
3416 if (!dut->use_5g && dut->main_ifname_2g &&
3417 if_nametoindex(dut->main_ifname_2g) > 0)
3418 return dut->main_ifname_2g;
3419 if (if_nametoindex(dut->main_ifname) > 0)
3420 return dut->main_ifname;
3421 }
3422
3423 /* Return based on driver type (indirectly started hostapd) */
3424 drv = get_driver_type(dut);
3425 if (drv == DRIVER_ATHEROS) {
3426 if (dut->use_5g && if_nametoindex("ath1") > 0)
3427 return "ath1";
3428 return "ath0";
3429 }
3430
3431 if (drv == DRIVER_OPENWRT) {
3432 if (sigma_radio_ifname[0] &&
3433 strcmp(sigma_radio_ifname[0], "wifi2") == 0)
3434 return "ath2";
3435 if (sigma_radio_ifname[0] &&
3436 strcmp(sigma_radio_ifname[0], "wifi1") == 0)
3437 return "ath1";
3438 return "ath0";
3439 }
3440
3441 /* wlan1-is-likely-5-GHz design */
3442 if (dut->use_5g && if_nametoindex("wlan1") > 0)
3443 return "wlan1";
3444
3445 /* If nothing else matches, hope for the best and guess this is wlan0 */
3446 return "wlan0";
3447 }
3448
3449
get_if_name(struct sigma_dut * dut,char * ifname_str,size_t str_size,int wlan_tag)3450 static void get_if_name(struct sigma_dut *dut, char *ifname_str,
3451 size_t str_size, int wlan_tag)
3452 {
3453 const char *ifname;
3454 enum driver_type drv;
3455
3456 ifname = get_hostapd_ifname(dut);
3457 drv = get_driver_type(dut);
3458
3459 if (drv == DRIVER_OPENWRT && wlan_tag > 1) {
3460 /* Handle tagged-ifname only on OPENWRT for now */
3461 snprintf(ifname_str, str_size, "%s%d", ifname, wlan_tag - 1);
3462 } else if ((drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN) &&
3463 wlan_tag == 2) {
3464 snprintf(ifname_str, str_size, "%s_1", ifname);
3465 } else {
3466 snprintf(ifname_str, str_size, "%s", ifname);
3467 }
3468 }
3469
3470
sae_pw_id_used(struct sigma_dut * dut)3471 static int sae_pw_id_used(struct sigma_dut *dut)
3472 {
3473 return dut->ap_sae_passwords &&
3474 strchr(dut->ap_sae_passwords, ':');
3475 }
3476
3477
owrt_ap_config_vap(struct sigma_dut * dut)3478 static int owrt_ap_config_vap(struct sigma_dut *dut)
3479 {
3480 char buf[256], *temp;
3481 int vap_id = 0, vap_count, i, j, res;
3482 const char *ifname;
3483 char ifname2[50];
3484
3485 if (sigma_radio_ifname[0] &&
3486 strcmp(sigma_radio_ifname[0], "wifi2") == 0)
3487 ifname = "ath2";
3488 else if (sigma_radio_ifname[0] &&
3489 strcmp(sigma_radio_ifname[0], "wifi1") == 0)
3490 ifname = "ath1";
3491 else
3492 ifname = "ath0";
3493
3494 for (vap_count = 0; vap_count < OPENWRT_MAX_NUM_RADIOS; vap_count++) {
3495 snprintf(buf, sizeof(buf), "wifi%d", vap_count);
3496
3497 for (vap_id = 0; vap_id < MAX_RADIO; vap_id++) {
3498 if (sigma_radio_ifname[vap_id] &&
3499 strcmp(sigma_radio_ifname[vap_id], buf) == 0)
3500 break;
3501 }
3502 if (vap_id == MAX_RADIO)
3503 continue;
3504
3505 /* Single VAP configuration */
3506 if (!dut->ap_is_dual)
3507 vap_id = vap_count;
3508
3509 for (j = 0; j < MAX_WLAN_TAGS - 1; j++) {
3510 /*
3511 * We keep a separate array of ap_tag_ssid and
3512 * ap_tag_key_mgmt for tags starting from WLAN_TAG=2.
3513 * So j=0 => WLAN_TAG = 2
3514 */
3515 int wlan_tag = j + 2;
3516
3517 if (wlan_tag == 2 && dut->program == PROGRAM_WPA3 &&
3518 (dut->ap_interface_5g || dut->ap_interface_2g)) {
3519 res = snprintf(
3520 dut->ap_tag_ssid[wlan_tag - 2],
3521 sizeof(dut->ap_tag_ssid[wlan_tag - 2]),
3522 "%s-owe", dut->ap_ssid);
3523 if (res < 0 ||
3524 res >= sizeof(dut->ap_tag_ssid[wlan_tag -
3525 2]))
3526 dut->ap_tag_ssid[wlan_tag - 2][0] =
3527 '\0';
3528 }
3529
3530 if (dut->ap_tag_ssid[j][0] == '\0')
3531 continue;
3532
3533 snprintf(buf, sizeof(buf), "%s%d", "wifi", vap_count);
3534 owrt_ap_add_vap(dut, vap_count + (wlan_tag - 1),
3535 "device", buf);
3536 /* SSID */
3537 snprintf(buf, sizeof(buf), "\"%s\"",
3538 dut->ap_tag_ssid[j]);
3539 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3540 "ssid", buf);
3541
3542 if (dut->ap_key_mgmt == AP_WPA2_OWE &&
3543 dut->ap_tag_ssid[0][0] &&
3544 dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
3545 /* OWE transition mode */
3546 snprintf(buf, sizeof(buf), "%s", ifname);
3547 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3548 "owe_transition_ifname", buf);
3549 }
3550
3551 if (dut->ap_key_mgmt == AP_OPEN &&
3552 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3553 /* OWE transition mode */
3554 snprintf(buf, sizeof(buf), "%s", ifname);
3555 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3556 "owe_transition_ifname", buf);
3557 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3558 "hidden", "1");
3559 }
3560
3561 if (ap_ft_enabled(dut)) {
3562 unsigned char self_mac[ETH_ALEN];
3563 char mac_str[20];
3564
3565 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3566 "mobility_domain",
3567 dut->ap_mobility_domain);
3568 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3569 "ft_over_ds",
3570 dut->ap_ft_ds == VALUE_ENABLED ?
3571 "1" : "0");
3572 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3573 "ieee80211r", "1");
3574 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3575 "nasid", "nas1.example.com");
3576 if (get_hwaddr(sigma_radio_ifname[0],
3577 self_mac) < 0)
3578 return -1;
3579 snprintf(mac_str, sizeof(mac_str),
3580 "%02x:%02x:%02x:%02x:%02x:%02x",
3581 self_mac[0], self_mac[1], self_mac[2],
3582 self_mac[3], self_mac[4], self_mac[5]);
3583 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3584 "ap_macaddr", mac_str);
3585 snprintf(mac_str, sizeof(mac_str),
3586 "%02x%02x%02x%02x%02x%02x",
3587 self_mac[0], self_mac[1], self_mac[2],
3588 self_mac[3], self_mac[4], self_mac[5]);
3589 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3590 "r1_key_holder", mac_str);
3591 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3592 "ft_psk_generate_local", "1");
3593 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3594 "kh_key_hex",
3595 "000102030405060708090a0b0c0d0e0f");
3596 snprintf(mac_str, sizeof(mac_str),
3597 "%02x:%02x:%02x:%02x:%02x:%02x",
3598 dut->ft_bss_mac_list[0][0],
3599 dut->ft_bss_mac_list[0][1],
3600 dut->ft_bss_mac_list[0][2],
3601 dut->ft_bss_mac_list[0][3],
3602 dut->ft_bss_mac_list[0][4],
3603 dut->ft_bss_mac_list[0][5]);
3604 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3605 "ap2_macaddr", mac_str);
3606 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3607 "ap2_r1_key_holder", mac_str);
3608 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3609 "nasid2", "nas2.example.com");
3610 }
3611
3612 if (dut->ap_tag_key_mgmt[j] == AP2_OSEN &&
3613 wlan_tag == 2) {
3614 /* Only supported for WLAN_TAG=2 */
3615 owrt_ap_set_vap(dut, vap_count + 1, "osen",
3616 "1");
3617 snprintf(buf, sizeof(buf), "wpa2");
3618 owrt_ap_set_vap(dut, vap_count + 1,
3619 "encryption", buf);
3620 snprintf(buf, sizeof(buf), "%s",
3621 dut->ap2_radius_ipaddr);
3622 owrt_ap_set_vap(dut, vap_count + 1,
3623 "auth_server", buf);
3624 snprintf(buf, sizeof(buf), "%d",
3625 dut->ap2_radius_port);
3626 owrt_ap_set_vap(dut, vap_count + 1,
3627 "auth_port", buf);
3628 snprintf(buf, sizeof(buf), "%s",
3629 dut->ap2_radius_password);
3630 owrt_ap_set_vap(dut, vap_count + 1,
3631 "auth_secret", buf);
3632 } else if (dut->ap_tag_key_mgmt[j] == AP2_WPA2_PSK) {
3633 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3634 "encryption", "psk2+ccmp");
3635 snprintf(buf, sizeof(buf), "\"%s\"",
3636 dut->ap_passphrase);
3637 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3638 "key", buf);
3639 snprintf(buf, sizeof(buf), "%d", dut->ap_pmf);
3640 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3641 "ieee80211w", buf);
3642 } else if (dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3643 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3644 "owe", "1");
3645 snprintf(buf, sizeof(buf), "ccmp");
3646 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3647 "encryption", buf);
3648 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1),
3649 "ieee80211w", "2");
3650 if (dut->ap_sae_groups) {
3651 snprintf(buf, sizeof(buf), "\'%s\'",
3652 dut->ap_sae_groups);
3653 owrt_ap_set_list_vap(dut, vap_count +
3654 (wlan_tag - 1),
3655 "owe_groups", buf);
3656 }
3657
3658 if (dut->owe_ptk_workaround)
3659 owrt_ap_set_list_vap(
3660 dut, vap_count + (wlan_tag - 1),
3661 "owe_ptk_workaround", "1");
3662 }
3663 }
3664
3665 /* Now set anqp_elem and ft_oa for wlan_tag = 1 */
3666 if (dut->program == PROGRAM_MBO &&
3667 get_driver_type(dut) == DRIVER_OPENWRT) {
3668 unsigned char self_mac[ETH_ALEN];
3669 char mac_str[20];
3670 char anqp_string[200];
3671
3672 if (set_anqp_elem_value(dut, sigma_radio_ifname[0],
3673 anqp_string,
3674 sizeof(anqp_string)) < 0)
3675 return -1;
3676 owrt_ap_set_list_vap(dut, vap_count, "anqp_elem",
3677 anqp_string);
3678
3679 if (ap_ft_enabled(dut)) {
3680 owrt_ap_set_vap(dut, vap_count,
3681 "mobility_domain",
3682 dut->ap_mobility_domain);
3683 owrt_ap_set_vap(dut, vap_count,
3684 "ft_over_ds",
3685 dut->ap_ft_ds == VALUE_ENABLED ?
3686 "1" : "0");
3687 owrt_ap_set_vap(dut, vap_count,
3688 "ieee80211r", "1");
3689 owrt_ap_set_vap(dut, vap_count,
3690 "nasid", "nas1.example.com");
3691 get_hwaddr(sigma_radio_ifname[0], self_mac);
3692 snprintf(mac_str, sizeof(mac_str),
3693 "%02x:%02x:%02x:%02x:%02x:%02x",
3694 self_mac[0], self_mac[1], self_mac[2],
3695 self_mac[3], self_mac[4], self_mac[5]);
3696 owrt_ap_set_vap(dut, vap_count,
3697 "ap_macaddr", mac_str);
3698 snprintf(mac_str, sizeof(mac_str),
3699 "%02x%02x%02x%02x%02x%02x",
3700 self_mac[0], self_mac[1], self_mac[2],
3701 self_mac[3], self_mac[4], self_mac[5]);
3702 owrt_ap_set_vap(dut, vap_count,
3703 "r1_key_holder", mac_str);
3704 owrt_ap_set_vap(dut, vap_count,
3705 "ft_psk_generate_local", "1");
3706 owrt_ap_set_vap(dut, vap_count,
3707 "kh_key_hex",
3708 "000102030405060708090a0b0c0d0e0f");
3709 snprintf(mac_str, sizeof(mac_str),
3710 "%02x:%02x:%02x:%02x:%02x:%02x",
3711 dut->ft_bss_mac_list[0][0],
3712 dut->ft_bss_mac_list[0][1],
3713 dut->ft_bss_mac_list[0][2],
3714 dut->ft_bss_mac_list[0][3],
3715 dut->ft_bss_mac_list[0][4],
3716 dut->ft_bss_mac_list[0][5]);
3717 owrt_ap_set_vap(dut, vap_count,
3718 "ap2_macaddr", mac_str);
3719 owrt_ap_set_vap(dut, vap_count,
3720 "ap2_r1_key_holder", mac_str);
3721 owrt_ap_set_vap(dut, vap_count,
3722 "nasid2", "nas2.example.com");
3723 }
3724 }
3725
3726 if (dut->ap_oce == VALUE_ENABLED &&
3727 get_driver_type(dut) == DRIVER_OPENWRT) {
3728 owrt_ap_set_vap(dut, vap_id, "oce", "1");
3729 owrt_ap_set_vap(dut, vap_id, "qbssload", "1");
3730 owrt_ap_set_vap(dut, vap_id, "bpr_enable", "1");
3731
3732 if (dut->ap_80plus80 == 1)
3733 owrt_ap_set_vap(dut, vap_id, "cfreq2", "5775");
3734
3735 if (dut->ap_akm == 1) {
3736 owrt_ap_set_vap(dut, vap_id, "wpa_group_rekey",
3737 "3600");
3738 owrt_ap_set_vap(dut, vap_id, "key", "12345678");
3739 owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3740 "1");
3741 owrt_ap_set_vap(dut, vap_id, "fils_cache_id",
3742 "1234");
3743 owrt_ap_set_vap(dut, vap_id,
3744 "erp_send_reauth_start", "1");
3745 }
3746
3747 if (dut->ap_filshlp == VALUE_ENABLED) {
3748 struct ifreq ifr;
3749 char *ifname;
3750 int s;
3751 struct sockaddr_in *ipaddr;
3752
3753 s = socket(AF_INET, SOCK_DGRAM, 0);
3754 if (s < 0) {
3755 sigma_dut_print(dut, DUT_MSG_ERROR,
3756 "Failed to open socket");
3757 return -1;
3758 }
3759 ifr.ifr_addr.sa_family = AF_INET;
3760
3761 memset(&ifr, 0, sizeof(ifr));
3762 ifname = "br-lan";
3763 strlcpy(ifr.ifr_name, ifname,
3764 sizeof(ifr.ifr_name));
3765 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
3766 perror("ioctl");
3767 close(s);
3768 return -1;
3769 }
3770
3771 ipaddr = (struct sockaddr_in*)&ifr.ifr_addr;
3772 snprintf(buf, sizeof(buf), "%s",
3773 inet_ntoa(ipaddr->sin_addr));
3774 owrt_ap_set_vap(dut, vap_id, "own_ip_addr",
3775 buf);
3776 snprintf(buf, sizeof(buf), "%s",
3777 dut->ap_dhcpserv_ipaddr);
3778 owrt_ap_set_vap(dut, vap_id, "dhcp_server",
3779 buf);
3780 owrt_ap_set_vap(dut, vap_id,
3781 "dhcp_rapid_commit_proxy", "1");
3782 owrt_ap_set_vap(dut, vap_id,
3783 "fils_hlp_wait_time", "300");
3784 }
3785
3786 if (dut->ap_filsdscv == VALUE_ENABLED) {
3787 owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3788 "1");
3789 owrt_ap_set_vap(dut, vap_id, "fils_fd_period",
3790 "20");
3791 }
3792 }
3793
3794 if (dut->ap_filsdscv == VALUE_DISABLED) {
3795 owrt_ap_set_vap(dut, vap_id, "ieee80211ai", "0");
3796 owrt_ap_set_vap(dut, vap_id, "fils_fd_period", "0");
3797 }
3798
3799 if (dut->ap_oce == VALUE_DISABLED &&
3800 get_driver_type(dut) == DRIVER_OPENWRT) {
3801 owrt_ap_set_vap(dut, vap_id, "oce", "0");
3802 owrt_ap_set_vap(dut, vap_id, "qbssload", "0");
3803 owrt_ap_set_vap(dut, vap_id, "bpr_enable", "0");
3804
3805 if (dut->ap_filsdscv == VALUE_DISABLED) {
3806 owrt_ap_set_vap(dut, vap_id, "ieee80211ai",
3807 "0");
3808 owrt_ap_set_vap(dut, vap_id, "fils_fd_period",
3809 "0");
3810 }
3811
3812 if (dut->device_type == AP_testbed)
3813 owrt_ap_set_vap(dut, vap_id, "mbo", "1");
3814 }
3815
3816 /* NAIRealm */
3817 if (dut->ap_nairealm_int == 1) {
3818 snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_nairealm);
3819 owrt_ap_set_vap(dut, vap_id, "fils_realm", buf);
3820 owrt_ap_set_vap(dut, vap_id, "erp_domain", buf);
3821 }
3822
3823 /* SSID */
3824 snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_ssid);
3825 owrt_ap_set_vap(dut, vap_count, "ssid", buf);
3826
3827 /* Encryption */
3828 switch (dut->ap_key_mgmt) {
3829 case AP_OPEN:
3830 if (dut->ap_cipher == AP_WEP) {
3831 owrt_ap_set_vap(dut, vap_count, "encryption",
3832 "wep-mixed");
3833 owrt_ap_set_vap(dut, vap_count, "key",
3834 dut->ap_wepkey);
3835 } else {
3836 owrt_ap_set_vap(dut, vap_count, "encryption",
3837 "none");
3838 }
3839 if (dut->ap_key_mgmt == AP_OPEN &&
3840 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
3841 /* OWE transition mode */
3842 snprintf(ifname2, sizeof(ifname2), "%s1",
3843 ifname);
3844 owrt_ap_set_vap(dut, vap_count,
3845 "owe_transition_ifname",
3846 ifname2);
3847 }
3848 break;
3849 case AP_WPA2_PSK:
3850 case AP_WPA2_PSK_MIXED:
3851 case AP_WPA_PSK:
3852 case AP_WPA2_SAE:
3853 case AP_WPA2_PSK_SAE:
3854 if (dut->ap_key_mgmt == AP_WPA2_PSK ||
3855 dut->ap_key_mgmt == AP_WPA2_PSK_SAE) {
3856 snprintf(buf, sizeof(buf), "psk2");
3857 } else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) {
3858 snprintf(buf, sizeof(buf), "psk-mixed");
3859 } else if (dut->ap_key_mgmt == AP_WPA2_SAE) {
3860 snprintf(buf, sizeof(buf), "ccmp");
3861 } else {
3862 snprintf(buf, sizeof(buf), "psk");
3863 }
3864
3865 if (dut->ap_key_mgmt != AP_WPA2_SAE) {
3866 if (dut->ap_cipher == AP_CCMP_TKIP)
3867 strlcat(buf, "+ccmp+tkip", sizeof(buf));
3868 else if (dut->ap_cipher == AP_TKIP)
3869 strlcat(buf, "+tkip", sizeof(buf));
3870 else if (dut->ap_cipher == AP_GCMP_128)
3871 strlcat(buf, "+gcmp", sizeof(buf));
3872 else
3873 strlcat(buf, "+ccmp", sizeof(buf));
3874 }
3875
3876 owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3877
3878 if (!dut->ap_passphrase[0] && dut->ap_psk[0]) {
3879 snprintf(buf, sizeof(buf), "\"%s\"",
3880 dut->ap_psk);
3881 owrt_ap_set_vap(dut, vap_count, "key", buf);
3882 } else {
3883 snprintf(buf, sizeof(buf), "\"%s\"",
3884 dut->ap_passphrase);
3885 owrt_ap_set_vap(dut, vap_count, "key", buf);
3886 }
3887
3888 if (dut->ap_key_mgmt == AP_WPA2_SAE ||
3889 dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
3890 owrt_ap_set_vap(dut, vap_count, "sae", "1");
3891 else
3892 owrt_ap_set_vap(dut, vap_count, "sae", "0");
3893
3894 if (dut->ap_key_mgmt == AP_WPA2_SAE && dut->ap_sae_pk &&
3895 dut->ap_sae_pk_keypair_sig) {
3896 snprintf(buf, sizeof(buf), "%s|pk=%s:%s:%s",
3897 dut->ap_passphrase,
3898 dut->ap_sae_pk_modifier,
3899 dut->ap_sae_pk_keypair,
3900 dut->ap_sae_pk_keypair_sig);
3901 owrt_ap_set_vap(dut, vap_count, "sae_password",
3902 buf);
3903 } else if (dut->ap_key_mgmt == AP_WPA2_SAE &&
3904 dut->ap_sae_pk) {
3905 snprintf(buf, sizeof(buf), "%s|pk=%s:%s",
3906 dut->ap_passphrase,
3907 dut->ap_sae_pk_modifier,
3908 dut->ap_sae_pk_keypair);
3909 owrt_ap_set_vap(dut, vap_count, "sae_password",
3910 buf);
3911 } else if (dut->ap_key_mgmt == AP_WPA2_SAE) {
3912 snprintf(buf, sizeof(buf), "%s",
3913 dut->ap_passphrase);
3914 owrt_ap_set_vap(dut, vap_count, "sae_password",
3915 buf);
3916 } else {
3917 snprintf(buf, sizeof(buf), "%s",
3918 dut->ap_passphrase);
3919 owrt_ap_set_vap(dut, vap_count,
3920 "wpa_passphrase", buf);
3921 }
3922 break;
3923 case AP_WPA2_EAP:
3924 case AP_WPA2_EAP_MIXED:
3925 case AP_WPA_EAP:
3926 if (dut->ap_key_mgmt == AP_WPA2_EAP) {
3927 snprintf(buf, sizeof(buf), "wpa2");
3928 } else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) {
3929 snprintf(buf, sizeof(buf), "wpa-mixed");
3930 } else {
3931 snprintf(buf, sizeof(buf), "wpa");
3932 }
3933
3934 if (dut->ap_cipher == AP_CCMP_TKIP)
3935 strlcat(buf, "+ccmp+tkip", sizeof(buf));
3936 else if (dut->ap_cipher == AP_TKIP)
3937 strlcat(buf, "+tkip", sizeof(buf));
3938 else
3939 strlcat(buf, "+ccmp", sizeof(buf));
3940
3941 owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3942 snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr);
3943 owrt_ap_set_vap(dut, vap_count, "auth_server", buf);
3944 snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port);
3945 owrt_ap_set_vap(dut, vap_count, "auth_port", buf);
3946 snprintf(buf, sizeof(buf), "%s",
3947 dut->ap_radius_password);
3948 owrt_ap_set_vap(dut, vap_count, "auth_secret", buf);
3949 break;
3950 case AP_WPA2_EAP_OSEN:
3951 case AP_OSEN:
3952 case AP_WPA2_FT_EAP:
3953 case AP_WPA2_FT_PSK:
3954 case AP_WPA2_EAP_SHA256:
3955 case AP_WPA2_PSK_SHA256:
3956 case AP_WPA2_ENT_FT_EAP:
3957 /* TODO */
3958 break;
3959 case AP_SUITEB:
3960 owrt_ap_set_vap(dut, vap_count, "suite_b", "192");
3961 snprintf(buf, sizeof(buf), "gcmp");
3962 owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3963 snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr);
3964 owrt_ap_set_vap(dut, vap_count, "auth_server", buf);
3965 snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port);
3966 owrt_ap_set_vap(dut, vap_count, "auth_port", buf);
3967 snprintf(buf, sizeof(buf), "%s",
3968 dut->ap_radius_password);
3969 owrt_ap_set_vap(dut, vap_count, "auth_secret", buf);
3970 snprintf(buf, sizeof(buf), "%d",
3971 dut->ap_group_mgmt_cipher);
3972 owrt_ap_set_vap(dut, vap_count, "group_mgmt_cipher",
3973 buf);
3974 break;
3975 case AP_WPA2_OWE:
3976 owrt_ap_set_vap(dut, vap_count, "owe", "1");
3977 snprintf(buf, sizeof(buf), "ccmp");
3978 owrt_ap_set_vap(dut, vap_count, "encryption", buf);
3979 if (dut->ap_sae_groups) {
3980 snprintf(buf, sizeof(buf), "\'%s\'",
3981 dut->ap_sae_groups);
3982 owrt_ap_set_list_vap(dut, vap_count,
3983 "owe_groups", buf);
3984 }
3985
3986 if (dut->owe_ptk_workaround)
3987 owrt_ap_set_list_vap(dut, vap_count,
3988 "owe_ptk_workaround", "1");
3989
3990 if (dut->ap_key_mgmt == AP_WPA2_OWE &&
3991 dut->ap_tag_ssid[0][0] &&
3992 dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
3993 /* OWE transition mode */
3994 snprintf(ifname2, sizeof(ifname2), "%s1",
3995 ifname);
3996 owrt_ap_set_vap(dut, vap_count,
3997 "owe_transition_ifname",
3998 ifname2);
3999 owrt_ap_set_vap(dut, vap_count, "hidden", "1");
4000 }
4001 break;
4002 }
4003
4004 if (!dut->ap_is_dual)
4005 break;
4006 }
4007
4008 if (dut->ap_is_dual)
4009 return 1;
4010
4011 /* PMF */
4012 snprintf(buf, sizeof(buf), "%d", dut->ap_pmf);
4013 owrt_ap_set_vap(dut, vap_id, "ieee80211w", buf);
4014
4015 /* Add SHA256 */
4016 snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha256);
4017 owrt_ap_set_vap(dut, vap_id, "add_sha256", buf);
4018
4019 /* Add SHA384 for akmsuitetype 15 */
4020 if (dut->ap_akm == 1) {
4021 snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha384);
4022 owrt_ap_set_vap(dut, vap_id, "add_sha384", buf);
4023 }
4024
4025 /* Enable RSN preauthentication, if asked to */
4026 snprintf(buf, sizeof(buf), "%d", dut->ap_rsn_preauth);
4027 owrt_ap_set_vap(dut, vap_id, "rsn_preauth", buf);
4028
4029 /* Hotspot 2.0 */
4030 if (dut->ap_hs2) {
4031 int ret;
4032
4033 ret = owrt_ap_config_vap_hs2(dut, vap_id);
4034 if (ret)
4035 return ret;
4036 }
4037
4038 /* Interworking */
4039 if (dut->ap_interworking) {
4040 snprintf(buf, sizeof(buf), "%d", dut->ap_access_net_type);
4041 owrt_ap_set_vap(dut, vap_id, "access_network_type", buf);
4042 snprintf(buf, sizeof(buf), "%d", dut->ap_internet);
4043 owrt_ap_set_vap(dut, vap_id, "internet", buf);
4044 snprintf(buf, sizeof(buf), "%d", dut->ap_venue_group);
4045 owrt_ap_set_vap(dut, vap_id, "venue_group", buf);
4046 snprintf(buf, sizeof(buf), "%d", dut->ap_venue_type);
4047 owrt_ap_set_vap(dut, vap_id, "venue_type", buf);
4048 snprintf(buf, sizeof(buf), "%s", dut->ap_hessid);
4049 owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4050
4051 if (dut->ap_gas_cb_delay > 0) {
4052 snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay);
4053 owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf);
4054 }
4055
4056 if (dut->ap_roaming_cons[0]) {
4057 char *rcons, *temp_ptr;
4058
4059 rcons = strdup(dut->ap_roaming_cons);
4060 if (rcons == NULL)
4061 return -1;
4062
4063 temp_ptr = strchr(rcons, ';');
4064
4065 if (temp_ptr)
4066 *temp_ptr++ = '\0';
4067
4068 owrt_ap_set_list_vap(dut, vap_id, "roaming_consortium",
4069 rcons);
4070
4071 if (temp_ptr)
4072 owrt_ap_set_list_vap(dut, vap_id,
4073 "roaming_consortium",
4074 temp_ptr);
4075
4076 free(rcons);
4077 }
4078 }
4079
4080 if (dut->ap_venue_name) {
4081 owrt_ap_set_list_vap(dut, vap_id, "venue_name",
4082 "'P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"'");
4083 owrt_ap_set_list_vap(dut, vap_id, "venue_name",
4084 "\'"ANQP_VENUE_NAME_1_CHI"\'");
4085 }
4086
4087 if (dut->ap_net_auth_type == 1) {
4088 owrt_ap_set_list_vap(dut, vap_id, "network_auth_type",
4089 "'00https://tandc-server.wi-fi.org'");
4090 } else if (dut->ap_net_auth_type == 2) {
4091 owrt_ap_set_list_vap(dut, vap_id, "network_auth_type", "'01'");
4092 }
4093
4094 if (dut->ap_nai_realm_list == 1) {
4095 owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4096 "'0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]'");
4097 owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4098 "'0,wi-fi.org;example.com,13[5:6]'");
4099
4100 } else if (dut->ap_nai_realm_list == 2) {
4101 owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4102 "'0,wi-fi.org,21[2:4][5:7]'");
4103 } else if (dut->ap_nai_realm_list == 3) {
4104 owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4105 "'0,cisco.com;wi-fi.org,21[2:4][5:7]'");
4106 owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4107 "'0,wi-fi.org;example.com,13[5:6]'");
4108 } else if (dut->ap_nai_realm_list == 4) {
4109 owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4110 "'0,mail.example.com,21[2:4][5:7],13[5:6]'");
4111 } else if (dut->ap_nai_realm_list == 5) {
4112 owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4113 "'0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]'");
4114 } else if (dut->ap_nai_realm_list == 6) {
4115 owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4116 "'0,wi-fi.org;mail.example.com,21[2:4][5:7]'");
4117 } else if (dut->ap_nai_realm_list == 7) {
4118 owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4119 "'0,wi-fi.org,13[5:6]'");
4120 owrt_ap_set_list_vap(dut, vap_id, "nai_realm",
4121 "'0,wi-fi.org,21[2:4][5:7]'");
4122 }
4123
4124 if (dut->ap_domain_name_list[0])
4125 owrt_ap_set_list_vap(dut, vap_id, "domain_name",
4126 dut->ap_domain_name_list);
4127
4128 if (dut->ap_ip_addr_type_avail)
4129 owrt_ap_set_vap(dut, vap_id, "ipaddr_type_availability",
4130 "'0c'");
4131
4132 temp = buf;
4133
4134 *temp++ = '\'';
4135
4136 for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) {
4137 if (i)
4138 *temp++ = ';';
4139
4140 snprintf(temp,
4141 sizeof(dut->ap_plmn_mcc[i]) +
4142 sizeof(dut->ap_plmn_mnc[i]) + 1,
4143 "%s,%s",
4144 dut->ap_plmn_mcc[i],
4145 dut->ap_plmn_mnc[i]);
4146
4147 temp += strlen(dut->ap_plmn_mcc[i]) +
4148 strlen(dut->ap_plmn_mnc[i]) + 1;
4149 }
4150
4151 *temp++ = '\'';
4152 *temp++ = '\0';
4153
4154 if (i)
4155 owrt_ap_set_vap(dut, vap_id, "anqp_3gpp_cell_net", buf);
4156
4157 if (dut->ap_qos_map_set == 1)
4158 owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_1);
4159 else if (dut->ap_qos_map_set == 2)
4160 owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_2);
4161
4162 /* Proxy-ARP */
4163 snprintf(buf, sizeof(buf), "%d", dut->ap_proxy_arp);
4164 owrt_ap_set_vap(dut, vap_id, "proxyarp", buf);
4165
4166 /* DGAF */
4167 snprintf(buf, sizeof(buf), "%d", dut->ap_dgaf_disable);
4168 /* parse to hostapd */
4169 owrt_ap_set_vap(dut, vap_id, "disable_dgaf", buf);
4170 /* parse to wifi driver */
4171 owrt_ap_set_vap(dut, vap_id, "dgaf_disable", buf);
4172
4173 /* HCBSSLoad */
4174 if (dut->ap_bss_load) {
4175 unsigned int bssload = 0;
4176
4177 if (dut->ap_bss_load == 1) {
4178 /* STA count: 1, CU: 50, AAC: 65535 */
4179 bssload = 0x0132ffff;
4180 } else if (dut->ap_bss_load == 2) {
4181 /* STA count: 1, CU: 200, AAC: 65535 */
4182 bssload = 0x01c8ffff;
4183 } else if (dut->ap_bss_load == 3) {
4184 /* STA count: 1, CU: 75, AAC: 65535 */
4185 bssload = 0x014bffff;
4186 }
4187
4188 snprintf(buf, sizeof(buf), "%d", bssload);
4189 owrt_ap_set_vap(dut, vap_id, "hcbssload", buf);
4190 }
4191
4192 /* L2TIF */
4193 if (dut->ap_l2tif)
4194 owrt_ap_set_vap(dut, vap_id, "l2tif", "1");
4195
4196 if (dut->ap_disable_protection == 1)
4197 owrt_ap_set_vap(dut, vap_id, "enablertscts", "0");
4198
4199 if (dut->ap_txBF) {
4200 owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "1");
4201 owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "1");
4202 if (dut->program == PROGRAM_HE) {
4203 owrt_ap_set_vap(dut, vap_id, "he_subfer", "1");
4204 owrt_ap_set_vap(dut, vap_id, "cwmenable", "0");
4205 }
4206 } else {
4207 owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0");
4208 owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0");
4209 if (dut->program == PROGRAM_HE)
4210 owrt_ap_set_vap(dut, vap_id, "he_subfer", "0");
4211 }
4212
4213 if (dut->ap_mu_txBF) {
4214 owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "1");
4215 if (dut->program == PROGRAM_HE) {
4216 owrt_ap_set_vap(dut, vap_id, "he_mubfer", "1");
4217 owrt_ap_set_vap(dut, vap_id, "he_mubfee", "1");
4218 }
4219 } else {
4220 owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "0");
4221 if (dut->program == PROGRAM_HE) {
4222 owrt_ap_set_vap(dut, vap_id, "he_mubfer", "0");
4223 owrt_ap_set_vap(dut, vap_id, "he_mubfee", "0");
4224 }
4225 }
4226
4227 if (dut->ap_tx_stbc) {
4228 /* STBC and beamforming are mutually exclusive features */
4229 owrt_ap_set_vap(dut, vap_id, "implicitbf", "0");
4230 }
4231
4232 /* enable dfsmode */
4233 snprintf(buf, sizeof(buf), "%d", dut->ap_dfs_mode);
4234 owrt_ap_set_vap(dut, vap_id, "doth", buf);
4235
4236 if (dut->program == PROGRAM_LOC && dut->ap_interworking) {
4237 char anqpval[1024];
4238
4239 owrt_ap_set_vap(dut, vap_id, "interworking", "1");
4240
4241 if (dut->ap_lci == 1 && strlen(dut->ap_tag_ssid[0]) == 0) {
4242 snprintf(anqpval, sizeof(anqpval),
4243 "'265:0010%s%s060101'",
4244 dut->ap_val_lci, dut->ap_infoz);
4245 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4246 }
4247
4248 if (dut->ap_lcr == 1) {
4249 snprintf(anqpval, sizeof(anqpval),
4250 "'266:0000b2555302ae%s'",
4251 dut->ap_val_lcr);
4252 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4253 }
4254
4255 if (dut->ap_fqdn_held == 1 && dut->ap_fqdn_supl == 1)
4256 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem",
4257 "'267:00110168656c642e6578616d706c652e636f6d0011027375706c2e6578616d706c652e636f6d'");
4258 }
4259
4260 if (dut->program == PROGRAM_MBO) {
4261 owrt_ap_set_vap(dut, vap_id, "interworking", "1");
4262 owrt_ap_set_vap(dut, vap_id, "mbo", "1");
4263 owrt_ap_set_vap(dut, vap_id, "rrm", "1");
4264 owrt_ap_set_vap(dut, vap_id, "mbo_cell_conn_pref", "1");
4265
4266 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem",
4267 "'272:34108cfdf0020df1f7000000733000030101'");
4268 snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay);
4269 owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf);
4270 }
4271
4272 if (ap_ft_enabled(dut)) {
4273 unsigned char self_mac[ETH_ALEN];
4274 char mac_str[20];
4275
4276 owrt_ap_set_vap(dut, vap_id, "ft_over_ds",
4277 dut->ap_ft_ds == VALUE_ENABLED ? "1" : "0");
4278 owrt_ap_set_vap(dut, vap_id, "ieee80211r", "1");
4279 if (get_hwaddr(sigma_radio_ifname[0], self_mac) < 0)
4280 return -1;
4281 snprintf(mac_str, sizeof(mac_str),
4282 "%02x:%02x:%02x:%02x:%02x:%02x",
4283 self_mac[0], self_mac[1], self_mac[2],
4284 self_mac[3], self_mac[4], self_mac[5]);
4285 owrt_ap_set_vap(dut, vap_id, "ap_macaddr", mac_str);
4286 snprintf(mac_str, sizeof(mac_str),
4287 "%02x:%02x:%02x:%02x:%02x:%02x",
4288 self_mac[0], self_mac[1], self_mac[2],
4289 self_mac[3], self_mac[4], self_mac[5]);
4290 owrt_ap_set_vap(dut, vap_id, "r1_key_holder", mac_str);
4291 owrt_ap_set_vap(dut, vap_id, "ft_psk_generate_local", "1");
4292 owrt_ap_set_vap(dut, vap_id, "kh_key_hex",
4293 "000102030405060708090a0b0c0d0e0f");
4294 snprintf(mac_str, sizeof(mac_str),
4295 "%02x:%02x:%02x:%02x:%02x:%02x",
4296 dut->ft_bss_mac_list[0][0],
4297 dut->ft_bss_mac_list[0][1],
4298 dut->ft_bss_mac_list[0][2],
4299 dut->ft_bss_mac_list[0][3],
4300 dut->ft_bss_mac_list[0][4],
4301 dut->ft_bss_mac_list[0][5]);
4302 owrt_ap_set_vap(dut, vap_id, "ap2_macaddr", mac_str);
4303 owrt_ap_set_vap(dut, vap_id, "mobility_domain",
4304 dut->ap_mobility_domain);
4305 owrt_ap_set_vap(dut, vap_id, "ap2_r1_key_holder", mac_str);
4306 }
4307
4308 if ((ap_ft_enabled(dut) && dut->ap_name == 0) ||
4309 (ap_ft_enabled(dut) && dut->ap_name == 2)) {
4310 owrt_ap_set_vap(dut, vap_id, "nasid2", "nas2.example.com");
4311 owrt_ap_set_vap(dut, vap_id, "nasid", "nas1.example.com");
4312 }
4313
4314 if (ap_ft_enabled(dut) && dut->ap_name == 1) {
4315 owrt_ap_set_vap(dut, vap_id, "nasid2", "nas1.example.com");
4316 owrt_ap_set_vap(dut, vap_id, "nasid", "nas2.example.com");
4317 }
4318
4319 if (dut->ap_broadcast_ssid == VALUE_DISABLED)
4320 owrt_ap_set_vap(dut, vap_id, "hidden", "1");
4321
4322 /* Enable/disable PMKSA caching, if asked to */
4323 if (dut->ap_pmksa == 1) {
4324 snprintf(buf, sizeof(buf), "%d", dut->ap_pmksa_caching);
4325 owrt_ap_set_vap(dut, vap_id, "disable_pmksa_caching", buf);
4326 }
4327
4328 if (dut->ap_beacon_prot)
4329 owrt_ap_set_vap(dut, vap_id, "beacon_prot", "1");
4330
4331 if (dut->ap_transition_disable) {
4332 snprintf(buf, sizeof(buf), "0x%02x",
4333 dut->ap_transition_disable);
4334 owrt_ap_set_vap(dut, vap_id, "transition_disable", buf);
4335 }
4336
4337 if (dut->rsne_override) {
4338 snprintf(buf, sizeof(buf), "%s", dut->rsne_override);
4339 owrt_ap_set_vap(dut, vap_count, "own_ie_override", buf);
4340 }
4341
4342 if (dut->rsnxe_override_eapol)
4343 owrt_ap_set_vap(dut, vap_count, "rsnxe_override_eapol",
4344 dut->rsnxe_override_eapol);
4345
4346 if (dut->sae_commit_override) {
4347 snprintf(buf, sizeof(buf), "%s", dut->sae_commit_override);
4348 owrt_ap_set_vap(dut, vap_count, "sae_commit_override", buf);
4349 }
4350
4351 if (dut->ap_sae_groups) {
4352 snprintf(buf, sizeof(buf), "\'%s\'", dut->ap_sae_groups);
4353 owrt_ap_set_list_vap(dut, vap_count, "sae_groups", buf);
4354 }
4355
4356 if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) {
4357 const char *sae_pwe = NULL;
4358
4359 if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut))
4360 sae_pwe = "3";
4361 else if (dut->sae_pwe == SAE_PWE_LOOP)
4362 sae_pwe = "0";
4363 else if (dut->sae_pwe == SAE_PWE_H2E)
4364 sae_pwe = "1";
4365 else if (dut->sae_h2e_default)
4366 sae_pwe = "2";
4367 if (sae_pwe)
4368 owrt_ap_set_vap(dut, vap_count, "sae_pwe", sae_pwe);
4369 }
4370
4371 if (dut->sae_anti_clogging_threshold >= 0) {
4372 snprintf(buf, sizeof(buf), "%d",
4373 dut->sae_anti_clogging_threshold);
4374 owrt_ap_set_vap(dut, vap_count, "sae_anti_clogging_threshold",
4375 buf);
4376 }
4377
4378 if (dut->sae_reflection)
4379 owrt_ap_set_vap(dut, vap_count, "sae_reflection_attack", "1");
4380 if (dut->ap_sae_commit_status >= 0) {
4381 snprintf(buf, sizeof(buf), "%d", dut->ap_sae_commit_status);
4382 owrt_ap_set_vap(dut, vap_count, "sae_commit_status", buf);
4383 }
4384 if (dut->ap_sae_pk_omit)
4385 owrt_ap_set_vap(dut, vap_count, "sae_pk_omit", "1");
4386 if (dut->sae_confirm_immediate)
4387 owrt_ap_set_vap(dut, vap_count, "sae_confirm_immediate", "2");
4388
4389 if (dut->ap_he_dlofdma == VALUE_ENABLED && dut->ap_he_ppdu == PPDU_MU) {
4390 dut->ap_txBF = 0;
4391 dut->ap_mu_txBF = 0;
4392 owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0");
4393 owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0");
4394 owrt_ap_set_vap(dut, vap_id, "he_subfer", "0");
4395 }
4396
4397 if (dut->program == PROGRAM_HE &&
4398 (dut->ap_txBF || dut->ap_he_ulofdma == VALUE_ENABLED ||
4399 dut->ap_he_mimo == MIMO_DL)) {
4400 switch (dut->ap_chwidth) {
4401 case AP_20:
4402 owrt_ap_set_vap(dut, vap_id, "chwidth", "0");
4403 break;
4404 case AP_40:
4405 owrt_ap_set_vap(dut, vap_id, "chwidth", "1");
4406 break;
4407 case AP_80:
4408 owrt_ap_set_vap(dut, vap_id, "chwidth", "2");
4409 break;
4410 case AP_160:
4411 owrt_ap_set_vap(dut, vap_id, "chwidth", "3");
4412 break;
4413 case AP_80_80:
4414 owrt_ap_set_vap(dut, vap_id, "chwidth", "3");
4415 break;
4416 case AP_AUTO:
4417 default:
4418 break;
4419 }
4420 }
4421
4422 if (dut->ap_ocvc == 1)
4423 owrt_ap_set_vap(dut, vap_count, "ocv", "1");
4424 else if (dut->ap_ocvc == 0)
4425 owrt_ap_set_vap(dut, vap_count, "ocv", "0");
4426
4427 return 1;
4428 }
4429
4430
owrt_ap_config_vap_anqp(struct sigma_dut * dut)4431 static int owrt_ap_config_vap_anqp(struct sigma_dut *dut)
4432 {
4433 char anqpval[1024];
4434 unsigned char addr[6];
4435 unsigned char addr2[6];
4436 struct ifreq ifr;
4437 char *ifname;
4438 int s;
4439 int vap_id = 0;
4440
4441 s = socket(AF_INET, SOCK_DGRAM, 0);
4442 if (s < 0) {
4443 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open socket");
4444 return -1;
4445 }
4446
4447 memset(&ifr, 0, sizeof(ifr));
4448 ifname = "ath0";
4449 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
4450 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
4451 perror("ioctl");
4452 close(s);
4453 return -1;
4454 }
4455 memcpy(addr, ifr.ifr_hwaddr.sa_data, 6);
4456
4457 memset(&ifr, 0, sizeof(ifr));
4458 ifname = "ath01";
4459 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
4460 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
4461 perror("ioctl");
4462 close(s);
4463 return -1;
4464 }
4465 close(s);
4466 memcpy(addr2, ifr.ifr_hwaddr.sa_data, 6);
4467
4468 snprintf(anqpval, sizeof(anqpval),
4469 "'265:0010%s%s060101070d00%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'",
4470 dut->ap_val_lci, dut->ap_infoz,
4471 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
4472 addr2[0], addr2[1], addr2[2], addr2[3], addr2[4], addr2[5]);
4473
4474 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval);
4475 return 0;
4476 }
4477
4478
owrt_ap_post_config_commit(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)4479 static int owrt_ap_post_config_commit(struct sigma_dut *dut,
4480 struct sigma_conn *conn,
4481 struct sigma_cmd *cmd)
4482 {
4483 int ap_security = 0;
4484 int i;
4485
4486 for (i = 0; i < MAX_WLAN_TAGS - 1; i++) {
4487 if (dut->ap_tag_key_mgmt[i] != AP2_OPEN)
4488 ap_security = 1;
4489 }
4490 if (dut->ap_key_mgmt != AP_OPEN)
4491 ap_security = 1;
4492 if (ap_security) {
4493 /* allow some time for hostapd to start before returning
4494 * success */
4495 usleep(500000);
4496
4497 if (run_hostapd_cli(dut, "ping") != 0) {
4498 send_resp(dut, conn, SIGMA_ERROR,
4499 "errorCode,Failed to talk to hostapd");
4500 return 0;
4501 }
4502 }
4503
4504 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
4505 ath_ap_set_params(dut);
4506
4507 /* Send response */
4508 return 1;
4509 }
4510
4511
cmd_owrt_ap_config_commit(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)4512 static int cmd_owrt_ap_config_commit(struct sigma_dut *dut,
4513 struct sigma_conn *conn,
4514 struct sigma_cmd *cmd)
4515 {
4516 if (dut->program == PROGRAM_DPP &&
4517 get_driver_type(dut) == DRIVER_OPENWRT) {
4518 wpa_command(dut->hostapd_ifname, "DPP_BOOTSTRAP_REMOVE *");
4519 wpa_command(dut->hostapd_ifname, "DPP_PKEX_REMOVE *");
4520 }
4521
4522 /* Stop the AP */
4523 run_system(dut, "wifi down");
4524
4525 /* Reset the wireless configuration */
4526 run_system(dut, "rm -rf /etc/config/wireless");
4527 switch (get_openwrt_driver_type()) {
4528 case OPENWRT_DRIVER_ATHEROS:
4529 run_system(dut, "wifi detect qcawifi > /etc/config/wireless");
4530 break;
4531 default:
4532 run_system(dut, "wifi detect > /etc/config/wireless");
4533 break;
4534 }
4535
4536 /* Configure Radio & VAP, commit the config */
4537 if (owrt_ap_config_radio(dut) < 0)
4538 return ERROR_SEND_STATUS;
4539 if (owrt_ap_config_vap(dut) < 0)
4540 return ERROR_SEND_STATUS;
4541 run_system(dut, "uci commit");
4542
4543 /* Start AP */
4544 run_system(dut, "wifi up");
4545 if (dut->program != PROGRAM_MBO &&
4546 dut->ap_lci == 1 && dut->ap_interworking &&
4547 strlen(dut->ap_tag_ssid[0]) > 0) {
4548 /*
4549 * MBO has a different ANQP element value which is set in
4550 * owrt_ap_config_vap().
4551 */
4552 owrt_ap_config_vap_anqp(dut);
4553 run_system(dut, "uci commit");
4554 run_system(dut, "wifi");
4555 }
4556
4557 return owrt_ap_post_config_commit(dut, conn, cmd);
4558 }
4559
4560
cmd_owrt_ap_hs2_reset(struct sigma_dut * dut)4561 static void cmd_owrt_ap_hs2_reset(struct sigma_dut *dut)
4562 {
4563 unsigned char bssid[6];
4564 char buf[100];
4565 char *ifname, *radio_name;
4566 int vap_id = 0;
4567
4568 if (sigma_radio_ifname[0] &&
4569 strcmp(sigma_radio_ifname[0], "wifi2") == 0) {
4570 ifname = "ath2";
4571 radio_name = "wifi2";
4572 vap_id = 2;
4573 } else if (sigma_radio_ifname[0] &&
4574 strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
4575 ifname = "ath1";
4576 radio_name = "wifi1";
4577 vap_id = 1;
4578 } else {
4579 ifname = "ath0";
4580 radio_name = "wifi0";
4581 vap_id = 0;
4582 }
4583
4584 if (!get_hwaddr(ifname, bssid)) {
4585 snprintf(buf, sizeof(buf), "%s", bssid);
4586 owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4587 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4588 "%02x:%02x:%02x:%02x:%02x:%02x",
4589 bssid[0], bssid[1], bssid[2], bssid[3],
4590 bssid[4], bssid[5]);
4591 } else {
4592 if (!get_hwaddr(radio_name, bssid)) {
4593 snprintf(buf, sizeof(buf), "%s", dut->ap_hessid);
4594 owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4595 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4596 "%02x:%02x:%02x:%02x:%02x:%02x",
4597 bssid[0], bssid[1], bssid[2], bssid[3],
4598 bssid[4], bssid[5]);
4599 } else {
4600 /* Select & enable/disable radios */
4601 if (sigma_radio_ifname[0] &&
4602 strcmp(sigma_radio_ifname[0], "wifi2") == 0) {
4603 /* We want to use wifi2 */
4604 owrt_ap_set_radio(dut, 0, "disabled", "1");
4605 owrt_ap_set_radio(dut, 1, "disabled", "1");
4606 owrt_ap_set_radio(dut, 2, "disabled", "0");
4607 owrt_ap_set_vap(dut, vap_id, "device", "wifi2");
4608 } else if (sigma_radio_ifname[0] &&
4609 strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
4610 /* We want to use wifi1 */
4611 owrt_ap_set_radio(dut, 0, "disabled", "1");
4612 owrt_ap_set_radio(dut, 1, "disabled", "0");
4613 owrt_ap_set_vap(dut, vap_id, "device", "wifi1");
4614 } else {
4615 /* We want to use wifi0 */
4616 owrt_ap_set_radio(dut, 0, "disabled", "0");
4617 owrt_ap_set_radio(dut, 1, "disabled", "1");
4618 owrt_ap_set_vap(dut, vap_id, "device", "wifi0");
4619 }
4620
4621 run_system(dut, "uci commit");
4622 run_system(dut, "wifi up");
4623
4624 if (!get_hwaddr(radio_name, bssid)) {
4625 snprintf(buf, sizeof(buf), "%s",
4626 dut->ap_hessid);
4627 owrt_ap_set_vap(dut, vap_id, "hessid", buf);
4628 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
4629 "%02x:%02x:%02x:%02x:%02x:%02x",
4630 bssid[0], bssid[1], bssid[2], bssid[3],
4631 bssid[4], bssid[5]);
4632 }
4633 }
4634 }
4635 }
4636
4637
cmd_ap_reboot(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)4638 static enum sigma_cmd_result cmd_ap_reboot(struct sigma_dut *dut,
4639 struct sigma_conn *conn,
4640 struct sigma_cmd *cmd)
4641 {
4642 switch (get_driver_type(dut)) {
4643 case DRIVER_ATHEROS:
4644 run_system(dut, "apdown");
4645 sleep(1);
4646 run_system(dut, "reboot");
4647 break;
4648 case DRIVER_OPENWRT:
4649 run_system(dut, "wifi down");
4650 sleep(1);
4651 run_system(dut, "reboot");
4652 break;
4653 default:
4654 sigma_dut_print(dut, DUT_MSG_INFO, "Ignore ap_reboot command");
4655 break;
4656 }
4657
4658 return 1;
4659 }
4660
4661
ascii2hexstr(const char * str,char * hex)4662 int ascii2hexstr(const char *str, char *hex)
4663 {
4664 int i, length;
4665
4666 length = strlen(str);
4667
4668 for (i = 0; i < length; i++)
4669 snprintf(hex + i * 2, 3, "%X", str[i]);
4670
4671 hex[length * 2] = '\0';
4672 return 1;
4673 }
4674
4675
kill_process(struct sigma_dut * dut,char * proc_name,unsigned char is_proc_instance_one,int sig)4676 static int kill_process(struct sigma_dut *dut, char *proc_name,
4677 unsigned char is_proc_instance_one, int sig)
4678 {
4679 #ifdef __linux__
4680 struct dirent *dp, *dp_in;
4681 const char *direc = "/proc/";
4682 char buf[100];
4683 DIR *dir = opendir(direc);
4684 DIR *dir_in;
4685 FILE *fp;
4686 char *pid, *temp;
4687 char *saveptr;
4688 int ret = -1, res;
4689
4690 if (dir == NULL)
4691 return ret;
4692
4693 while ((dp = readdir(dir)) != NULL) {
4694 if (dp->d_type != DT_DIR)
4695 continue;
4696
4697 res = snprintf(buf, sizeof(buf), "%s%s", direc, dp->d_name);
4698 if (res < 0 || res >= sizeof(buf))
4699 continue;
4700 dir_in = opendir(buf);
4701 if (dir_in == NULL)
4702 continue;
4703 dp_in = readdir(dir_in);
4704 closedir(dir_in);
4705 if (dp_in == NULL)
4706 continue;
4707 res = snprintf(buf, sizeof(buf), "%s%s/stat",
4708 direc, dp->d_name);
4709 if (res < 0 || res >= sizeof(buf))
4710 continue;
4711 fp = fopen(buf, "r");
4712 if (fp == NULL)
4713 continue;
4714 if (fgets(buf, 100, fp) == NULL)
4715 buf[0] = '\0';
4716 fclose(fp);
4717 pid = strtok_r(buf, " ", &saveptr);
4718 temp = strtok_r(NULL, " ", &saveptr);
4719 if (pid && temp &&
4720 strncmp(temp, proc_name, strlen(proc_name)) == 0) {
4721 sigma_dut_print(dut, DUT_MSG_INFO,
4722 "killing %s process with PID %s",
4723 proc_name, pid);
4724 snprintf(buf, sizeof(buf), "kill -%d %d", sig,
4725 atoi(pid));
4726 run_system(dut, buf);
4727 ret = 0;
4728 if (is_proc_instance_one)
4729 break;
4730 }
4731 }
4732
4733 closedir(dir);
4734
4735 return ret;
4736 #else /* __linux__ */
4737 return -1;
4738 #endif /* __linux__ */
4739 }
4740
4741
run_ndc(struct sigma_dut * dut,char * buf)4742 static int run_ndc(struct sigma_dut *dut, char *buf)
4743 {
4744 sigma_dut_print(dut, DUT_MSG_INFO, "CMD NDC:: %s", buf);
4745 sleep(2);
4746 return run_system(dut, buf);
4747 }
4748
4749
sigma_write_cfg(struct sigma_dut * dut,const char * pfile,const char * field,const char * value)4750 static int sigma_write_cfg(struct sigma_dut *dut, const char *pfile,
4751 const char *field, const char *value)
4752 {
4753 FILE *fcfg, *ftmp;
4754 char buf[MAX_CONF_LINE_LEN + 1];
4755 int len, found = 0, res;
4756
4757 /* Open the configuration file */
4758 fcfg = fopen(pfile, "r");
4759 if (!fcfg) {
4760 sigma_dut_print(dut, DUT_MSG_ERROR,
4761 "Failed to open hostapd conf file");
4762 return -1;
4763 }
4764
4765 snprintf(buf, sizeof(buf), "%s~", pfile);
4766 /* Open a temporary file */
4767 ftmp = fopen(buf, "w+");
4768 if (!ftmp) {
4769 fclose(fcfg);
4770 sigma_dut_print(dut, DUT_MSG_ERROR,
4771 "Failed to open temp buf");
4772 return -1;
4773 }
4774
4775 /* Read the values from the configuration file */
4776 len = strlen(field);
4777 while (fgets(buf, MAX_CONF_LINE_LEN, fcfg)) {
4778 char *pline = buf;
4779
4780 /* commented line */
4781 if (buf[0] == '#')
4782 pline++;
4783
4784 /* Identify the configuration parameter to be updated */
4785 if (!found && strncmp(pline, field, len) == 0 &&
4786 pline[len] == '=') {
4787 snprintf(buf, sizeof(buf), "%s=%s\n", field, value);
4788 found = 1;
4789 sigma_dut_print(dut, DUT_MSG_INFO,
4790 "Updated hostapd conf file");
4791 }
4792
4793 fprintf(ftmp, "%s", buf);
4794 }
4795
4796 if (!found) {
4797 /* Configuration line not found */
4798 /* Add the new line at the end of file */
4799 fprintf(ftmp, "%s=%s\n", field, value);
4800 sigma_dut_print(dut, DUT_MSG_INFO,
4801 "Adding a new line in hostapd conf file");
4802 }
4803
4804 fclose(fcfg);
4805 fclose(ftmp);
4806
4807 snprintf(buf, sizeof(buf), "%s~", pfile);
4808
4809 /* Restore the updated configuration file */
4810 res = rename(buf, pfile);
4811
4812 /* Remove the temporary file. Ignore the return value */
4813 unlink(buf);
4814
4815 /* chmod is needed because open() may not set permissions properly
4816 * depending on the current umask */
4817 if (chmod(pfile, 0660) < 0) {
4818 unlink(pfile);
4819 sigma_dut_print(dut, DUT_MSG_ERROR,
4820 "Error changing permissions");
4821 return -1;
4822 }
4823
4824 if (res < 0) {
4825 sigma_dut_print(dut, DUT_MSG_ERROR,
4826 "Error restoring conf file");
4827 return -1;
4828 }
4829
4830 return 0;
4831 }
4832
4833
cmd_wcn_ap_config_commit(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)4834 static int cmd_wcn_ap_config_commit(struct sigma_dut *dut,
4835 struct sigma_conn *conn,
4836 struct sigma_cmd *cmd)
4837 {
4838 char buf[100];
4839 struct stat s;
4840 int num_tries = 0, ret;
4841
4842 if (kill_process(dut, "(netd)", 1, SIGKILL) == 0 ||
4843 system("killall netd") == 0) {
4844 /* Avoid Error: Error connecting (Connection refused)
4845 * Wait some time to allow netd to reinitialize.
4846 */
4847 usleep(1500000);
4848 }
4849
4850 while (num_tries < 10) {
4851 ret = run_ndc(dut, "ndc softap stopap");
4852 num_tries++;
4853 if (WIFEXITED(ret))
4854 ret = WEXITSTATUS(ret);
4855 /* On success, NDC exits with 0 */
4856 if (ret == 0)
4857 break;
4858 sigma_dut_print(dut, DUT_MSG_INFO,
4859 "Try No. %d: ndc softap stopap failed, exit code %d",
4860 num_tries, ret);
4861 }
4862
4863 if (ret != 0)
4864 sigma_dut_print(dut, DUT_MSG_ERROR,
4865 "ndc softap stopap command failed for 10 times - giving up");
4866
4867 #ifdef ANDROID
4868 /* Unload/Load driver to cleanup the state of the driver */
4869 system("rmmod -f wlan");
4870 usleep(500000);
4871 system("insmod /system/lib/modules/wlan.ko");
4872 #else /* ANDROID */
4873 run_ndc(dut, "ndc softap qccmd set enable_softap=0");
4874 run_ndc(dut, "ndc softap qccmd set enable_softap=1");
4875 #endif /* ANDROID */
4876
4877 switch (dut->ap_mode) {
4878 case AP_11g:
4879 run_ndc(dut, "ndc softap qccmd set hw_mode=g-only");
4880 break;
4881 case AP_11b:
4882 run_ndc(dut, "ndc softap qccmd set hw_mode=b-only");
4883 break;
4884 case AP_11ng:
4885 run_ndc(dut, "ndc softap qccmd set hw_mode=n");
4886 break;
4887 case AP_11a:
4888 run_ndc(dut, "ndc softap qccmd set hw_mode=a-only");
4889 break;
4890 case AP_11na:
4891 run_ndc(dut, "ndc softap qccmd set hw_mode=n");
4892 break;
4893 case AP_11ac:
4894 run_ndc(dut, "ndc softap qccmd set hw_mode=ac");
4895 break;
4896 default:
4897 break;
4898 }
4899
4900 snprintf(buf, sizeof(buf), "ndc softap qccmd set channel=%d",
4901 dut->ap_channel);
4902 run_ndc(dut, buf);
4903
4904 /*
4905 * ndc doesn't support double quotes as SSID string, so re-write
4906 * hostapd configuration file to update SSID.
4907 */
4908 if (dut->ap_ssid[0] != '\0')
4909 sigma_write_cfg(dut, ANDROID_CONFIG_FILE, "ssid", dut->ap_ssid);
4910
4911 switch (dut->ap_key_mgmt) {
4912 case AP_OPEN:
4913 if (dut->ap_cipher == AP_WEP) {
4914 run_ndc(dut, "ndc softap qccmd set security_mode=1");
4915 snprintf(buf, sizeof(buf),
4916 "ndc softap qccmd set wep_key0=%s",
4917 dut->ap_wepkey);
4918 run_ndc(dut, buf);
4919 } else {
4920 run_ndc(dut, "ndc softap qccmd set security_mode=0");
4921 }
4922 break;
4923 case AP_WPA2_PSK:
4924 case AP_WPA2_PSK_MIXED:
4925 case AP_WPA_PSK:
4926 if (dut->ap_key_mgmt == AP_WPA2_PSK)
4927 run_ndc(dut, "ndc softap qccmd set security_mode=3");
4928 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
4929 run_ndc(dut, "ndc softap qccmd set security_mode=4");
4930 else
4931 run_ndc(dut, "ndc softap qccmd set security_mode=2");
4932
4933 /*
4934 * ndc doesn't support some special characters as passphrase,
4935 * so re-write hostapd configuration file to update Passphrase.
4936 */
4937 if (dut->ap_passphrase[0] != '\0')
4938 sigma_write_cfg(dut, ANDROID_CONFIG_FILE,
4939 "wpa_passphrase", dut->ap_passphrase);
4940
4941 if (dut->ap_cipher == AP_CCMP_TKIP)
4942 run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4943 "TKIP CCMP");
4944 else if (dut->ap_cipher == AP_TKIP)
4945 run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4946 "TKIP");
4947 else
4948 run_ndc(dut, "ndc softap qccmd set wpa_pairwise="
4949 "CCMP &");
4950 break;
4951 case AP_WPA2_SAE:
4952 case AP_WPA2_PSK_SAE:
4953 case AP_WPA2_EAP:
4954 case AP_WPA2_EAP_MIXED:
4955 case AP_WPA_EAP:
4956 case AP_SUITEB:
4957 case AP_WPA2_OWE:
4958 case AP_WPA2_EAP_OSEN:
4959 case AP_OSEN:
4960 case AP_WPA2_FT_EAP:
4961 case AP_WPA2_FT_PSK:
4962 case AP_WPA2_EAP_SHA256:
4963 case AP_WPA2_PSK_SHA256:
4964 case AP_WPA2_ENT_FT_EAP:
4965 /* Not supported */
4966 break;
4967 }
4968
4969 switch (dut->ap_pmf) {
4970 case AP_PMF_DISABLED:
4971 run_ndc(dut, "ndc softap qccmd set ieee80211w=0");
4972 break;
4973 case AP_PMF_OPTIONAL:
4974 run_ndc(dut, "ndc softap qccmd set ieee80211w=1");
4975 if (dut->ap_add_sha256)
4976 run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256");
4977 else
4978 run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK");
4979 break;
4980 case AP_PMF_REQUIRED:
4981 run_ndc(dut, "ndc softap qccmd set ieee80211w=2");
4982 run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK-SHA256");
4983 break;
4984 }
4985
4986 if (dut->ap_countrycode[0]) {
4987 snprintf(buf, sizeof(buf),
4988 "ndc softap qccmd set country_code=%s",
4989 dut->ap_countrycode);
4990 run_ndc(dut, buf);
4991 }
4992
4993 if (dut->ap_regulatory_mode == AP_80211D_MODE_ENABLED)
4994 run_ndc(dut, "ndc softap qccmd set ieee80211d=1");
4995
4996 if (dut->ap_dfs_mode == AP_DFS_MODE_ENABLED)
4997 run_ndc(dut, "ndc softap qccmd set ieee80211h=1");
4998
4999 run_ndc(dut, "ndc softap startap");
5000
5001 snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl,
5002 get_main_ifname(dut));
5003 num_tries = 0;
5004 while (num_tries < 10 && (ret = stat(buf, &s) != 0)) {
5005 run_ndc(dut, "ndc softap stopap");
5006 run_ndc(dut, "ndc softap startap");
5007 num_tries++;
5008 }
5009
5010 if (num_tries == 10) {
5011 sigma_dut_print(dut, DUT_MSG_INFO, "Tried 10 times with ctrl "
5012 "iface %s :: reboot the APDUT", buf);
5013 return ret;
5014 }
5015
5016 sigma_dut_print(dut, DUT_MSG_INFO, "setting ip addr %s mask %s",
5017 ap_inet_addr, ap_inet_mask);
5018 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up",
5019 get_main_ifname(dut), ap_inet_addr, ap_inet_mask);
5020 if (system(buf) != 0) {
5021 sigma_dut_print(dut, DUT_MSG_ERROR,
5022 "Failed to intialize the interface");
5023 return -1;
5024 }
5025
5026 return 1;
5027 }
5028
5029
append_hostapd_conf_hs2(struct sigma_dut * dut,FILE * f)5030 static int append_hostapd_conf_hs2(struct sigma_dut *dut, FILE *f)
5031 {
5032 fprintf(f, "hs20=1\nhs20_deauth_req_timeout=3\n"
5033 "disable_dgaf=%d\n", dut->ap_dgaf_disable);
5034
5035 if (dut->ap_oper_name) {
5036 fprintf(f, "hs20_oper_friendly_name=eng:Wi-Fi Alliance\n");
5037 fprintf(f, "hs20_oper_friendly_name=chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f\n");
5038 }
5039
5040 if (dut->ap_wan_metrics == 1)
5041 fprintf(f, "hs20_wan_metrics=01:2500:384:0:0:10\n");
5042 else if (dut->ap_wan_metrics == 2)
5043 fprintf(f, "hs20_wan_metrics=01:1500:384:20:20:10\n");
5044 else if (dut->ap_wan_metrics == 3)
5045 fprintf(f, "hs20_wan_metrics=01:2000:1000:20:20:10\n");
5046 else if (dut->ap_wan_metrics == 4)
5047 fprintf(f, "hs20_wan_metrics=01:8000:1000:20:20:10\n");
5048 else if (dut->ap_wan_metrics == 5)
5049 fprintf(f, "hs20_wan_metrics=01:9000:5000:20:20:10\n");
5050
5051 if (dut->ap_conn_capab == 1) {
5052 fprintf(f, "hs20_conn_capab=1:0:0\n");
5053 fprintf(f, "hs20_conn_capab=6:20:1\n");
5054 fprintf(f, "hs20_conn_capab=6:22:0\n");
5055 fprintf(f, "hs20_conn_capab=6:80:1\n");
5056 fprintf(f, "hs20_conn_capab=6:443:1\n");
5057 fprintf(f, "hs20_conn_capab=6:1723:0\n");
5058 fprintf(f, "hs20_conn_capab=6:5060:0\n");
5059 fprintf(f, "hs20_conn_capab=17:500:1\n");
5060 fprintf(f, "hs20_conn_capab=17:5060:0\n");
5061 fprintf(f, "hs20_conn_capab=17:4500:1\n");
5062 fprintf(f, "hs20_conn_capab=50:0:1\n");
5063 } else if (dut->ap_conn_capab == 2) {
5064 fprintf(f, "hs20_conn_capab=6:80:1\n");
5065 fprintf(f, "hs20_conn_capab=6:443:1\n");
5066 fprintf(f, "hs20_conn_capab=17:5060:1\n");
5067 fprintf(f, "hs20_conn_capab=6:5060:1\n");
5068 } else if (dut->ap_conn_capab == 3) {
5069 fprintf(f, "hs20_conn_capab=6:80:1\n");
5070 fprintf(f, "hs20_conn_capab=6:443:1\n");
5071 } else if (dut->ap_conn_capab == 4) {
5072 fprintf(f, "hs20_conn_capab=6:80:1\n");
5073 fprintf(f, "hs20_conn_capab=6:443:1\n");
5074 fprintf(f, "hs20_conn_capab=6:5060:1\n");
5075 fprintf(f, "hs20_conn_capab=17:5060:1\n");
5076 }
5077
5078 if (dut->ap_oper_class == 1)
5079 fprintf(f, "hs20_operating_class=51\n");
5080 else if (dut->ap_oper_class == 2)
5081 fprintf(f, "hs20_operating_class=73\n");
5082 else if (dut->ap_oper_class == 3)
5083 fprintf(f, "hs20_operating_class=5173\n");
5084
5085 if (dut->ap_osu_provider_list) {
5086 char *osu_friendly_name = NULL;
5087 char *osu_icon = NULL;
5088 char *osu_ssid = NULL;
5089 char *osu_nai = NULL;
5090 char *osu_nai2 = NULL;
5091 char *osu_service_desc = NULL;
5092 char *hs20_icon_filename = NULL;
5093 char hs20_icon[150];
5094 int osu_method;
5095
5096 hs20_icon_filename = "icon_red_zxx.png";
5097 if (dut->ap_osu_icon_tag == 2)
5098 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5099 snprintf(hs20_icon, sizeof(hs20_icon),
5100 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s",
5101 hs20_icon_filename);
5102 osu_icon = "icon_red_zxx.png";
5103 osu_ssid = "OSU";
5104 osu_friendly_name = "kor:SP 빨강 테스트 전용";
5105 osu_service_desc = "kor:테스트 목적으로 무료 서비스";
5106 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0];
5107
5108 if (strlen(dut->ap_osu_server_uri[0]))
5109 fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[0]);
5110 else
5111 fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
5112
5113 switch (dut->ap_osu_provider_list) {
5114 case 1:
5115 case 101:
5116 fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
5117 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5118 hs20_icon_filename = "icon_red_eng.png";
5119 if (dut->ap_osu_icon_tag == 2)
5120 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5121 fprintf(f, "hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s\n",
5122 hs20_icon_filename);
5123 fprintf(f, "osu_icon=icon_red_eng.png\n");
5124 break;
5125 case 2:
5126 case 102:
5127 fprintf(f, "osu_friendly_name=eng:Wireless Broadband Alliance\n");
5128 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5129 hs20_icon_filename = "icon_orange_zxx.png";
5130 if (dut->ap_osu_icon_tag == 2)
5131 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5132 snprintf(hs20_icon, sizeof(hs20_icon),
5133 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5134 hs20_icon_filename);
5135 osu_icon = "icon_orange_zxx.png";
5136 osu_friendly_name = "kor:와이어리스 브로드밴드 얼라이언스";
5137 break;
5138 case 3:
5139 case 103:
5140 osu_friendly_name = "spa:SP Red Test Only";
5141 osu_service_desc = "spa:Free service for test purpose";
5142 break;
5143 case 4:
5144 case 104:
5145 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5146 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5147 hs20_icon_filename = "icon_orange_eng.png";
5148 if (dut->ap_osu_icon_tag == 2)
5149 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5150 fprintf(f, "hs20_icon=160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s\n",
5151 hs20_icon_filename);
5152 fprintf(f, "osu_icon=icon_orange_eng.png\n");
5153 osu_friendly_name = "kor:SP 오렌지 테스트 전용";
5154
5155 hs20_icon_filename = "icon_orange_zxx.png";
5156 if (dut->ap_osu_icon_tag == 2)
5157 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5158 snprintf(hs20_icon, sizeof(hs20_icon),
5159 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5160 hs20_icon_filename);
5161 osu_icon = "icon_orange_zxx.png";
5162 break;
5163 case 5:
5164 case 105:
5165 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5166 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5167 osu_friendly_name = "kor:SP 오렌지 테스트 전용";
5168 hs20_icon_filename = "icon_orange_zxx.png";
5169 if (dut->ap_osu_icon_tag == 2)
5170 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5171 snprintf(hs20_icon, sizeof(hs20_icon),
5172 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5173 hs20_icon_filename);
5174 osu_icon = "icon_orange_zxx.png";
5175 break;
5176 case 6:
5177 case 106:
5178 fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n");
5179 fprintf(f, "osu_friendly_name=kor:SP 초록 테스트 전용\n");
5180 hs20_icon_filename = "icon_green_zxx.png";
5181 if (dut->ap_osu_icon_tag == 2)
5182 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5183 fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s\n",
5184 hs20_icon_filename);
5185 fprintf(f, "osu_icon=icon_green_zxx.png\n");
5186 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 : dut->ap_osu_method[0];
5187 fprintf(f, "osu_method_list=%d\n", osu_method);
5188
5189 if (strlen(dut->ap_osu_server_uri[1]))
5190 fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]);
5191 else
5192 fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
5193 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5194 hs20_icon_filename = "icon_orange_zxx.png";
5195 if (dut->ap_osu_icon_tag == 2)
5196 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5197 snprintf(hs20_icon, sizeof(hs20_icon),
5198 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5199 hs20_icon_filename);
5200 osu_icon = "icon_orange_zxx.png";
5201 osu_friendly_name = "kor:SP 오렌지 테스트 전용";
5202 osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 : dut->ap_osu_method[1];
5203 osu_service_desc = NULL;
5204 break;
5205 case 7:
5206 case 107:
5207 fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n");
5208 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5209 hs20_icon_filename = "icon_green_eng.png";
5210 if (dut->ap_osu_icon_tag == 2)
5211 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5212 fprintf(f, "hs20_icon=160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s\n",
5213 hs20_icon_filename);
5214 fprintf(f, "osu_icon=icon_green_eng.png\n");
5215 osu_friendly_name = "kor:SP 초록 테스트 전용";
5216
5217 hs20_icon_filename = "icon_green_zxx.png";
5218 if (dut->ap_osu_icon_tag == 2)
5219 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5220 snprintf(hs20_icon, sizeof(hs20_icon),
5221 "128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s",
5222 hs20_icon_filename);
5223 osu_icon = "icon_green_zxx.png";
5224 break;
5225 case 8:
5226 case 108:
5227 fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
5228 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n");
5229 osu_ssid = "OSU-Encrypted";
5230 osu_nai = "anonymous@hotspot.net";
5231 break;
5232 case 9:
5233 case 109:
5234 osu_ssid = "OSU-OSEN";
5235 osu_nai = "test-anonymous@wi-fi.org";
5236 osu_friendly_name = "eng:SP Orange Test Only";
5237 hs20_icon_filename = "icon_orange_zxx.png";
5238 if (dut->ap_osu_icon_tag == 2)
5239 hs20_icon_filename = "wifi-abgn-logo_270x73.png";
5240 snprintf(hs20_icon, sizeof(hs20_icon),
5241 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s",
5242 hs20_icon_filename);
5243 osu_icon = "icon_orange_zxx.png";
5244 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0];
5245 osu_service_desc = NULL;
5246 break;
5247 case 10:
5248 case 110:
5249 /* OSU Provider #1 */
5250 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n");
5251 fprintf(f, "osu_friendly_name=kor:SP 오렌지 테스트 전용\n");
5252 fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/icon_orange_zxx.png\n");
5253 fprintf(f, "osu_icon=icon_orange_zxx.png\n");
5254 osu_method = (dut->ap_osu_method[0] == 0xFF) ?
5255 1 : dut->ap_osu_method[0];
5256 fprintf(f, "osu_method_list=%d\n", osu_method);
5257 fprintf(f, "osu_nai=test-anonymous@wi-fi.org\n");
5258 switch (dut->ap_osu_provider_nai_list) {
5259 case 3:
5260 fprintf(f,
5261 "osu_nai2=test-anonymous@wi-fi.org\n");
5262 break;
5263 case 4:
5264 fprintf(f, "osu_nai2=random@hotspot.net\n");
5265 break;
5266 }
5267
5268 /* OSU Provider #2 */
5269 /* SP Red from defaults */
5270 if (strlen(dut->ap_osu_server_uri[1]))
5271 fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]);
5272 else
5273 fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n");
5274 fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n");
5275 snprintf(hs20_icon, sizeof(hs20_icon),
5276 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/icon_red_zxx.png");
5277 osu_method = (dut->ap_osu_method[1] == 0xFF) ?
5278 1 : dut->ap_osu_method[1];
5279 osu_service_desc = NULL;
5280 osu_nai = "anonymous@hotspot.net";
5281 break;
5282 default:
5283 break;
5284 }
5285
5286 switch (dut->ap_osu_provider_nai_list) {
5287 case 1:
5288 osu_nai2 = "anonymous@hotspot.net";
5289 break;
5290 case 2:
5291 osu_nai2 = "test-anonymous@wi-fi.org";
5292 break;
5293 case 3:
5294 /* OSU Provider NAI #1 written above */
5295 /* OSU Provider NAI #2 */
5296 osu_nai2 = "anonymous@hotspot.net";
5297 break;
5298 case 4:
5299 /* OSU Provider NAI #1 written above */
5300 /* OSU Provider NAI #2 */
5301 osu_nai2 = "anonymous@hotspot.net";
5302 break;
5303 }
5304
5305 if (strlen(dut->ap_osu_ssid)) {
5306 if (dut->ap_tag_ssid[0][0] &&
5307 strcmp(dut->ap_tag_ssid[0], dut->ap_osu_ssid) &&
5308 strcmp(dut->ap_tag_ssid[0], osu_ssid)) {
5309 sigma_dut_print(dut, DUT_MSG_ERROR,
5310 "OSU_SSID and "
5311 "WLAN_TAG2 SSID differ");
5312 return -2;
5313 }
5314 fprintf(f, "osu_ssid=\"%s\"\n", dut->ap_osu_ssid);
5315 } else
5316 fprintf(f, "osu_ssid=\"%s\"\n", osu_ssid);
5317
5318
5319 if (osu_friendly_name)
5320 fprintf(f, "osu_friendly_name=%s\n", osu_friendly_name);
5321
5322 if (osu_service_desc)
5323 fprintf(f, "osu_service_desc=%s\n", osu_service_desc);
5324
5325 if (osu_nai)
5326 fprintf(f, "osu_nai=%s\n", osu_nai);
5327 if (osu_nai2)
5328 fprintf(f, "osu_nai2=%s\n", osu_nai2);
5329
5330 fprintf(f, "hs20_icon=%s\n", hs20_icon);
5331
5332 if (osu_icon)
5333 fprintf(f, "osu_icon=%s\n", osu_icon);
5334
5335 if (dut->ap_osu_provider_list > 100)
5336 fprintf(f, "osu_method_list=0\n");
5337 else
5338 fprintf(f, "osu_method_list=%d\n", osu_method);
5339 }
5340
5341 switch (dut->ap_venue_url) {
5342 case 1:
5343 fprintf(f,
5344 "venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5345 "venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/directory/index.html\n");
5346 break;
5347 case 2:
5348 fprintf(f,
5349 "venue_url=1:https://the-great-mall.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5350 "venue_url=2:https://abercrombie.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5351 "venue_url=3:https://adidas.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5352 "venue_url=4:https://aeropostale.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5353 "venue_url=5:https://agaci.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5354 "venue_url=6:https://aldo-shoes.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5355 "venue_url=7:https://american-eagle-outfitters.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5356 "venue_url=8:https://anderson-bakery.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5357 "venue_url=9:https://banana-republic-factory-store.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5358 "venue_url=10:https://bed-bath-and-beyond.r2m-testbed.wi-fi.org/floorplans/index.html\n"
5359 );
5360 break;
5361 }
5362
5363 switch (dut->ap_advice_of_charge) {
5364 case 1:
5365 fprintf(f, "anqp_elem=278:" ADV_OF_CHARGE_1 "\n");
5366 break;
5367 }
5368
5369 switch (dut->ap_oper_icon_metadata) {
5370 case 1:
5371 fprintf(f,
5372 "hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/icon_red_eng.png\n"
5373 "operator_icon=icon_red_eng.png\n");
5374 break;
5375 }
5376
5377 switch (dut->ap_tnc_file_name) {
5378 case 1:
5379 fprintf(f, "hs20_t_c_filename=tandc-id1-content.txt\n");
5380 break;
5381 }
5382
5383 if (dut->ap_tnc_time_stamp)
5384 fprintf(f, "hs20_t_c_timestamp=%u\n", dut->ap_tnc_time_stamp);
5385
5386 return 0;
5387 }
5388
5389
write_ap_roaming_cons(FILE * f,const char * list)5390 static void write_ap_roaming_cons(FILE *f, const char *list)
5391 {
5392 char *buf, *pos, *end;
5393
5394 if (list == NULL || list[0] == '\0')
5395 return;
5396
5397 buf = strdup(list);
5398 if (buf == NULL)
5399 return;
5400
5401 pos = buf;
5402 while (pos && *pos) {
5403 end = strchr(pos, ';');
5404 if (end)
5405 *end++ = '\0';
5406 fprintf(f, "roaming_consortium=%s\n", pos);
5407 pos = end;
5408 }
5409
5410 free(buf);
5411 }
5412
5413
append_hostapd_conf_interworking(struct sigma_dut * dut,FILE * f)5414 static int append_hostapd_conf_interworking(struct sigma_dut *dut, FILE *f)
5415 {
5416 int i;
5417 char buf[100], *temp;
5418
5419 if (dut->ap_gas_cb_delay > 0)
5420 fprintf(f, "gas_comeback_delay=%d\n",
5421 dut->ap_gas_cb_delay);
5422
5423 fprintf(f, "interworking=1\n"
5424 "access_network_type=%d\n"
5425 "internet=%d\n"
5426 "asra=0\n"
5427 "esr=0\n"
5428 "uesa=0\n"
5429 "venue_group=%d\n"
5430 "venue_type=%d\n",
5431 dut->ap_access_net_type,
5432 dut->ap_internet,
5433 dut->ap_venue_group,
5434 dut->ap_venue_type);
5435 if (dut->ap_hessid[0])
5436 fprintf(f, "hessid=%s\n", dut->ap_hessid);
5437
5438 write_ap_roaming_cons(f, dut->ap_roaming_cons);
5439
5440 if (dut->ap_venue_name) {
5441 fprintf(f, "venue_name=P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"\n");
5442 fprintf(f, "venue_name=%s\n", ANQP_VENUE_NAME_1_CHI);
5443 }
5444
5445 if (dut->ap_net_auth_type == 1)
5446 fprintf(f, "network_auth_type=00https://tandc-server.wi-fi.org\n");
5447 else if (dut->ap_net_auth_type == 2)
5448 fprintf(f, "network_auth_type=01\n");
5449
5450 if (dut->ap_nai_realm_list == 1) {
5451 fprintf(f, "nai_realm=0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]\n");
5452 fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n");
5453 } else if (dut->ap_nai_realm_list == 2) {
5454 fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n");
5455 } else if (dut->ap_nai_realm_list == 3) {
5456 fprintf(f, "nai_realm=0,cisco.com;wi-fi.org,21[2:4][5:7]\n");
5457 fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n");
5458 } else if (dut->ap_nai_realm_list == 4) {
5459 fprintf(f, "nai_realm=0,mail.example.com,21[2:4][5:7],13[5:6]\n");
5460 } else if (dut->ap_nai_realm_list == 5) {
5461 fprintf(f, "nai_realm=0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]\n");
5462 } else if (dut->ap_nai_realm_list == 6) {
5463 fprintf(f, "nai_realm=0,wi-fi.org;mail.example.com,21[2:4][5:7]\n");
5464 } else if (dut->ap_nai_realm_list == 7) {
5465 fprintf(f, "nai_realm=0,wi-fi.org,13[5:6]\n");
5466 fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n");
5467 }
5468
5469 if (dut->ap_domain_name_list[0]) {
5470 fprintf(f, "domain_name=%s\n",
5471 dut->ap_domain_name_list);
5472 }
5473
5474 if (dut->ap_ip_addr_type_avail == 1) {
5475 fprintf(f, "ipaddr_type_availability=0c\n");
5476 }
5477
5478 temp = buf;
5479 for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0];
5480 i++) {
5481 if (i)
5482 *temp++ = ';';
5483
5484 snprintf(temp,
5485 sizeof(dut->ap_plmn_mcc[i]) +
5486 sizeof(dut->ap_plmn_mnc[i]) + 1,
5487 "%s,%s",
5488 dut->ap_plmn_mcc[i],
5489 dut->ap_plmn_mnc[i]);
5490
5491 temp += strlen(dut->ap_plmn_mcc[i]) +
5492 strlen(dut->ap_plmn_mnc[i]) + 1;
5493 }
5494 if (i)
5495 fprintf(f, "anqp_3gpp_cell_net=%s\n", buf);
5496
5497 if (dut->ap_qos_map_set == 1)
5498 fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_1);
5499 else if (dut->ap_qos_map_set == 2)
5500 fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_2);
5501
5502 return 0;
5503 }
5504
5505
ath_ap_append_hostapd_conf(struct sigma_dut * dut)5506 static int ath_ap_append_hostapd_conf(struct sigma_dut *dut)
5507 {
5508 FILE *f;
5509
5510 if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
5511 system("killall hostapd") == 0) {
5512 int i;
5513
5514 /* Wait some time to allow hostapd to complete cleanup before
5515 * starting a new process */
5516 for (i = 0; i < 10; i++) {
5517 usleep(500000);
5518 if (system("pidof hostapd") != 0)
5519 break;
5520 }
5521 }
5522
5523 f = fopen("/tmp/secath0", "a");
5524 if (f == NULL)
5525 return -2;
5526
5527 if (dut->ap_hs2 && append_hostapd_conf_hs2(dut, f)) {
5528 fclose(f);
5529 return -2;
5530 }
5531
5532 if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) {
5533 fclose(f);
5534 return -2;
5535 }
5536
5537 fflush(f);
5538 fclose(f);
5539 return ath_ap_start_hostapd(dut);
5540 }
5541
5542
ath_ap_start_hostapd(struct sigma_dut * dut)5543 static int ath_ap_start_hostapd(struct sigma_dut *dut)
5544 {
5545 if (dut->ap_tag_key_mgmt[0] == AP2_OSEN)
5546 run_system(dut, "hostapd -B /tmp/secath0 /tmp/secath1 -e /etc/wpa2/entropy");
5547 else
5548 run_system(dut, "hostapd -B /tmp/secath0 -e /etc/wpa2/entropy");
5549
5550 return 0;
5551 }
5552
5553
5554 #define LE16(a) ((((a) & 0xff) << 8) | (((a) >> 8) & 0xff))
5555
cmd_ath_ap_anqpserver_start(struct sigma_dut * dut)5556 static int cmd_ath_ap_anqpserver_start(struct sigma_dut *dut)
5557 {
5558 FILE *f;
5559 int nai_realm = 0, domain_name = 0, oper_name = 0, venue_name = 0,
5560 wan_metrics = 0, conn_cap = 0, ipaddr_avail = 0, cell_net = 0;
5561 char buf[100];
5562 int i;
5563
5564 f = fopen("/root/anqpserver.conf", "w");
5565 if (f == NULL)
5566 return -1;
5567
5568 if (dut->ap_nai_realm_list == 1) {
5569 nai_realm = 1;
5570 fprintf(f, "dyn_nai_home_realm=encoding=00realm=mail.example.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=cisco.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=wi-fi.org;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=example.com;eap_method=0Dauth_id=05auth_val=06encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
5571 } else if (dut->ap_nai_realm_list == 2) {
5572 nai_realm = 1;
5573 fprintf(f, "dyn_nai_home_realm=encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
5574 } else if (dut->ap_nai_realm_list == 3) {
5575 nai_realm = 1;
5576 fprintf(f, "dyn_nai_home_realm=encoding=00realm=cisco.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=wi-fi.org;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=example.com;eap_method=0Dauth_id=05auth_val=06encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n");
5577 } else if (dut->ap_nai_realm_list == 4) {
5578 nai_realm = 1;
5579 fprintf(f, "dyn_nai_home_realm=encoding=00realm=mail.example.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=mail.example.com;eap_method=0Dauth_id=05auth_val=06\n");
5580 } else
5581 sigma_dut_print(dut, DUT_MSG_INFO, "not setting nai_realm");
5582
5583 if (dut->ap_domain_name_list[0]) {
5584 char *next, *start, *dnbuf, *dn1, *anqp_dn;
5585 int len, dn_len_max;
5586 dnbuf = strdup(dut->ap_domain_name_list);
5587 if (dnbuf == NULL) {
5588 fclose(f);
5589 return 0;
5590 }
5591
5592 len = strlen(dnbuf);
5593 dn_len_max = 50 + len*2;
5594 anqp_dn = malloc(dn_len_max);
5595 if (anqp_dn == NULL) {
5596 free(dnbuf);
5597 fclose(f);
5598 return -1;
5599 }
5600 start = dnbuf;
5601 dn1 = anqp_dn;
5602 while (start && *start) {
5603 char *hexstr;
5604
5605 next = strchr(start, ',');
5606 if (next)
5607 *next++ = '\0';
5608
5609 len = strlen(start);
5610 hexstr = malloc(len * 2 + 1);
5611 if (hexstr == NULL) {
5612 free(dnbuf);
5613 free(anqp_dn);
5614 fclose(f);
5615 return -1;
5616 }
5617 ascii2hexstr(start, hexstr);
5618 snprintf(dn1, dn_len_max, "%02x%s", len, hexstr);
5619 free(hexstr);
5620 dn1 += 2 + len * 2;
5621 dn_len_max -= 2 + len * 2;
5622 start = next;
5623 }
5624 free(dnbuf);
5625 if (dut->ap_gas_cb_delay) {
5626 fprintf(f, "dyn_domain_name=0c01%04x%s",
5627 LE16((unsigned int) strlen(anqp_dn)), anqp_dn);
5628 domain_name = 1;
5629 } else
5630 fprintf(f, "domain_name=0c01%04x%s",
5631 LE16((unsigned int) strlen(anqp_dn)), anqp_dn);
5632 free(anqp_dn);
5633 } else
5634 sigma_dut_print(dut, DUT_MSG_INFO, "not setting domain_name");
5635
5636 sigma_dut_print(dut, DUT_MSG_INFO, "not setting roaming_consortium");
5637
5638 if (dut->ap_oper_name) {
5639 if (dut->ap_gas_cb_delay) {
5640 fprintf(f, "dyn_oper_friendly_name="
5641 ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n");
5642 oper_name = 1;
5643 } else
5644 fprintf(f, "oper_friendly_name="
5645 ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n");
5646 } else
5647 sigma_dut_print(dut, DUT_MSG_INFO, "not setting oper_name");
5648
5649 if (dut->ap_venue_name) {
5650 if (dut->ap_gas_cb_delay) {
5651 fprintf(f, "dyn_venue_name=" ANQP_VENUE_NAME_1 "\n");
5652 venue_name = 1;
5653 } else
5654 fprintf(f, "venue_name=" ANQP_VENUE_NAME_1 "\n");
5655 } else
5656 sigma_dut_print(dut, DUT_MSG_ERROR, "not setting venue_name");
5657
5658 if (dut->ap_wan_metrics) {
5659 if (dut->ap_gas_cb_delay) {
5660 fprintf(f, "dyn_wan_metrics=" ANQP_HS20_WAN_METRICS_1 "\n");
5661 wan_metrics = 1;
5662 } else
5663 fprintf(f, "wan_metrics=" ANQP_HS20_WAN_METRICS_1
5664 "\n");
5665 } else
5666 sigma_dut_print(dut, DUT_MSG_ERROR, "not setting wan_metrics");
5667
5668 if (dut->ap_conn_capab) {
5669 if (dut->ap_gas_cb_delay) {
5670 fprintf(f, "dyn_conn_capability="
5671 ANQP_HS20_CONNECTION_CAPABILITY_1 "\n");
5672 conn_cap = 1;
5673 } else
5674 fprintf(f, "conn_capability="
5675 ANQP_HS20_CONNECTION_CAPABILITY_1 "\n");
5676 } else
5677 sigma_dut_print(dut, DUT_MSG_ERROR,
5678 "not setting conn_capability");
5679
5680 if (dut->ap_ip_addr_type_avail) {
5681 if (dut->ap_gas_cb_delay) {
5682 fprintf(f, "dyn_ipaddr_type=" ANQP_IP_ADDR_TYPE_1
5683 "\n");
5684 ipaddr_avail = 1;
5685 } else
5686 fprintf(f, "ipaddr_type=" ANQP_IP_ADDR_TYPE_1 "\n");
5687 } else
5688 sigma_dut_print(dut, DUT_MSG_ERROR,
5689 "not setting ipaddr_type_avail");
5690
5691 for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) {
5692 snprintf(buf + i * 6, sizeof(buf) - i * 6, "%c%c%c%c%c%c",
5693 dut->ap_plmn_mcc[i][1],
5694 dut->ap_plmn_mcc[i][0],
5695 dut->ap_plmn_mnc[i][2] == '\0' ?
5696 'f' : dut->ap_plmn_mnc[i][2],
5697 dut->ap_plmn_mcc[i][2],
5698 dut->ap_plmn_mnc[i][1],
5699 dut->ap_plmn_mnc[i][0]);
5700 }
5701 if (i) {
5702 uint16_t ie_len = (i * 3) + 5;
5703 if (dut->ap_gas_cb_delay) {
5704 fprintf(f, "dyn_cell_net=0801");
5705 cell_net = 1;
5706 } else
5707 fprintf(f, "cell_net=0801");
5708 fprintf(f, "%04x", LE16(ie_len));
5709 fprintf(f, "00"); /* version */
5710 fprintf(f, "%02x", (i * 3) + 3); /* user data hdr length */
5711 fprintf(f, "00"); /* plmn list */
5712 fprintf(f, "%02x", (i * 3) + 1); /* length of plmn list */
5713 fprintf(f, "%02x", i); /* number of plmns */
5714 fprintf(f, "%s\n", buf); /* plmns */
5715 } else
5716 sigma_dut_print(dut, DUT_MSG_ERROR,
5717 "not setting 3gpp_cellular_network");
5718
5719 if (nai_realm || domain_name || oper_name || venue_name ||
5720 wan_metrics || conn_cap || ipaddr_avail || cell_net) {
5721 fprintf(f, "anqp_attach=");
5722 if (venue_name)
5723 fprintf(f, "00000104%4.4x", dut->ap_gas_cb_delay);
5724 if (nai_realm)
5725 fprintf(f, "00000107%4.4x", dut->ap_gas_cb_delay);
5726 if (cell_net)
5727 fprintf(f, "00000108%4.4x", dut->ap_gas_cb_delay);
5728 if (domain_name)
5729 fprintf(f, "0000010c%4.4x", dut->ap_gas_cb_delay);
5730 if (oper_name)
5731 fprintf(f, "00010003%4.4x", dut->ap_gas_cb_delay);
5732 if (wan_metrics)
5733 fprintf(f, "00010004%4.4x", dut->ap_gas_cb_delay);
5734 if (conn_cap)
5735 fprintf(f, "00010005%4.4x", dut->ap_gas_cb_delay);
5736 fprintf(f, "00010006%4.4x", dut->ap_gas_cb_delay);
5737 fprintf(f, "\n");
5738 }
5739
5740 fclose(f);
5741
5742 run_system(dut, "anqpserver -i ath0 &");
5743 if (!dut->ap_anqpserver_on)
5744 run_system(dut, "killall anqpserver");
5745
5746 return 1;
5747 }
5748
5749
cmd_ath_ap_radio_config(struct sigma_dut * dut)5750 static void cmd_ath_ap_radio_config(struct sigma_dut *dut)
5751 {
5752 char buf[100];
5753
5754 run_system(dut, "cfg -a AP_STARTMODE=standard");
5755
5756 if (sigma_radio_ifname[0] &&
5757 strcmp(sigma_radio_ifname[0], "wifi1") == 0) {
5758 run_system(dut, "cfg -a AP_RADIO_ID=1");
5759 switch (dut->ap_mode) {
5760 case AP_11g:
5761 run_system(dut, "cfg -a AP_CHMODE_2=11G");
5762 break;
5763 case AP_11b:
5764 run_system(dut, "cfg -a AP_CHMODE_2=11B");
5765 break;
5766 case AP_11ng:
5767 run_system(dut, "cfg -a AP_CHMODE_2=11NGHT20");
5768 break;
5769 case AP_11a:
5770 run_system(dut, "cfg -a AP_CHMODE_2=11A");
5771 break;
5772 case AP_11na:
5773 run_system(dut, "cfg -a AP_CHMODE_2=11NAHT20");
5774 break;
5775 case AP_11ac:
5776 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5777 break;
5778 default:
5779 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5780 break;
5781 }
5782
5783 switch (dut->ap_rx_streams) {
5784 case 1:
5785 run_system(dut, "cfg -a RX_CHAINMASK_2=1");
5786 break;
5787 case 2:
5788 run_system(dut, "cfg -a RX_CHAINMASK_2=3");
5789 break;
5790 case 3:
5791 run_system(dut, "cfg -a RX_CHAINMASK_2=7");
5792 break;
5793 }
5794
5795 switch (dut->ap_tx_streams) {
5796 case 1:
5797 run_system(dut, "cfg -a TX_CHAINMASK_2=1");
5798 break;
5799 case 2:
5800 run_system(dut, "cfg -a TX_CHAINMASK_2=3");
5801 break;
5802 case 3:
5803 run_system(dut, "cfg -a TX_CHAINMASK_2=7");
5804 break;
5805 }
5806
5807 switch (dut->ap_chwidth) {
5808 case AP_20:
5809 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT20");
5810 break;
5811 case AP_40:
5812 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT40");
5813 break;
5814 case AP_80:
5815 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5816 break;
5817 case AP_160:
5818 case AP_AUTO:
5819 default:
5820 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
5821 break;
5822 }
5823
5824 if (dut->ap_tx_stbc) {
5825 run_system(dut, "cfg -a TX_STBC_2=1");
5826 }
5827
5828 snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH_2=%d",
5829 dut->ap_channel);
5830
5831 if (dut->ap_is_dual) {
5832 switch (dut->ap_mode_1) {
5833 case AP_11g:
5834 run_system(dut, "cfg -a AP_CHMODE=11G");
5835 break;
5836 case AP_11b:
5837 run_system(dut, "cfg -a AP_CHMODE=11B");
5838 break;
5839 case AP_11ng:
5840 run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5841 break;
5842 case AP_11a:
5843 run_system(dut, "cfg -a AP_CHMODE=11A");
5844 break;
5845 case AP_11na:
5846 run_system(dut, "cfg -a AP_CHMODE=11NAHT20");
5847 break;
5848 case AP_11ac:
5849 run_system(dut, "cfg -a AP_CHMODE=11ACVHT80");
5850 break;
5851 default:
5852 run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5853 break;
5854 }
5855 snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d",
5856 dut->ap_channel_1);
5857 }
5858 run_system(dut, buf);
5859 } else {
5860 run_system(dut, "cfg -a AP_RADIO_ID=0");
5861 switch (dut->ap_mode) {
5862 case AP_11g:
5863 run_system(dut, "cfg -a AP_CHMODE=11G");
5864 break;
5865 case AP_11b:
5866 run_system(dut, "cfg -a AP_CHMODE=11B");
5867 break;
5868 case AP_11ng:
5869 run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5870 break;
5871 case AP_11a:
5872 run_system(dut, "cfg -a AP_CHMODE=11A");
5873 break;
5874 case AP_11na:
5875 run_system(dut, "cfg -a AP_CHMODE=11NAHT20");
5876 break;
5877 case AP_11ac:
5878 run_system(dut, "cfg -a AP_CHMODE=11ACVHT80");
5879 break;
5880 default:
5881 run_system(dut, "cfg -a AP_CHMODE=11NGHT20");
5882 break;
5883 }
5884 snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d",
5885 dut->ap_channel);
5886 run_system(dut, buf);
5887 }
5888
5889 if (dut->ap_sgi80 == 1) {
5890 run_system(dut, "cfg -a SHORTGI=1");
5891 run_system(dut, "cfg -a SHORTGI_2=1");
5892 } else if (dut->ap_sgi80 == 0) {
5893 run_system(dut, "cfg -a SHORTGI=0");
5894 run_system(dut, "cfg -a SHORTGI_2=0");
5895 }
5896
5897 if (dut->ap_ldpc == VALUE_ENABLED)
5898 run_system(dut, "cfg -a LDPC=1");
5899 else if (dut->ap_ldpc == VALUE_DISABLED)
5900 run_system(dut, "cfg -a LDPC=0");
5901 }
5902
5903
ath_disable_txbf(struct sigma_dut * dut,const char * intf)5904 void ath_disable_txbf(struct sigma_dut *dut, const char *intf)
5905 {
5906 run_iwpriv(dut, intf, "vhtsubfee 0");
5907 run_iwpriv(dut, intf, "vhtsubfer 0");
5908 run_iwpriv(dut, intf, "vhtmubfee 0");
5909 run_iwpriv(dut, intf, "vhtmubfer 0");
5910 }
5911
5912
ath_set_assoc_disallow(struct sigma_dut * dut,const char * ifname,const char * val)5913 static void ath_set_assoc_disallow(struct sigma_dut *dut, const char *ifname,
5914 const char *val)
5915 {
5916 if (strcasecmp(val, "enable") == 0) {
5917 run_iwpriv(dut, ifname, "mbo_asoc_dis 1");
5918 } else if (strcasecmp(val, "disable") == 0) {
5919 run_iwpriv(dut, ifname, "mbo_asoc_dis 0");
5920 } else {
5921 sigma_dut_print(dut, DUT_MSG_ERROR,
5922 "Unsupported assoc_disallow");
5923 }
5924 }
5925
5926
apply_mbo_pref_ap_list(struct sigma_dut * dut)5927 static void apply_mbo_pref_ap_list(struct sigma_dut *dut)
5928 {
5929 int i;
5930 int least_pref = 1 << 8;
5931 char ifname[20];
5932 uint8_t self_mac[ETH_ALEN];
5933 char buf[200];
5934 int ap_ne_class, ap_ne_pref, ap_ne_op_ch;
5935
5936 get_if_name(dut, ifname, sizeof(ifname), 1);
5937 get_hwaddr(ifname, self_mac);
5938
5939 /* Clear off */
5940 snprintf(buf, sizeof(buf),
5941 "wifitool %s setbssidpref 00:00:00:00:00:00 0 0 0",
5942 ifname);
5943 run_system(dut, buf);
5944
5945 /* Find the least preference number */
5946 for (i = 0; i < dut->mbo_pref_ap_cnt; i++) {
5947 unsigned char *mac_addr = dut->mbo_pref_aps[i].mac_addr;
5948
5949 ap_ne_class = 1;
5950 ap_ne_pref = 255;
5951 ap_ne_op_ch = 1;
5952 if (dut->mbo_pref_aps[i].ap_ne_pref != -1)
5953 ap_ne_pref = dut->mbo_pref_aps[i].ap_ne_pref;
5954 if (dut->mbo_pref_aps[i].ap_ne_class != -1)
5955 ap_ne_class = dut->mbo_pref_aps[i].ap_ne_class;
5956 if (dut->mbo_pref_aps[i].ap_ne_op_ch != -1)
5957 ap_ne_op_ch = dut->mbo_pref_aps[i].ap_ne_op_ch;
5958
5959 if (ap_ne_pref < least_pref)
5960 least_pref = ap_ne_pref;
5961 snprintf(buf, sizeof(buf),
5962 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d",
5963 ifname, mac_addr[0], mac_addr[1], mac_addr[2],
5964 mac_addr[3], mac_addr[4], mac_addr[5],
5965 ap_ne_pref, ap_ne_class, ap_ne_op_ch);
5966 run_system(dut, buf);
5967 }
5968
5969 /* Now add the self AP Address */
5970 if (dut->mbo_self_ap_tuple.ap_ne_class == -1) {
5971 if (dut->ap_channel <= 11)
5972 ap_ne_class = 81;
5973 else
5974 ap_ne_class = 115;
5975 } else {
5976 ap_ne_class = dut->mbo_self_ap_tuple.ap_ne_class;
5977 }
5978
5979 if (dut->mbo_self_ap_tuple.ap_ne_op_ch == -1)
5980 ap_ne_op_ch = dut->ap_channel;
5981 else
5982 ap_ne_op_ch = dut->mbo_self_ap_tuple.ap_ne_op_ch;
5983
5984 if (dut->mbo_self_ap_tuple.ap_ne_pref == -1)
5985 ap_ne_pref = least_pref - 1;
5986 else
5987 ap_ne_pref = dut->mbo_self_ap_tuple.ap_ne_pref;
5988
5989 snprintf(buf, sizeof(buf),
5990 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d",
5991 ifname, self_mac[0], self_mac[1], self_mac[2],
5992 self_mac[3], self_mac[4], self_mac[5],
5993 ap_ne_pref,
5994 ap_ne_class,
5995 ap_ne_op_ch);
5996 run_system(dut, buf);
5997 }
5998
5999
mubrp_commands(struct sigma_dut * dut,const char * ifname)6000 static void mubrp_commands(struct sigma_dut *dut, const char *ifname)
6001 {
6002 run_iwpriv(dut, ifname, "he_subfer 1");
6003 run_iwpriv(dut, ifname, "he_mubfer 1");
6004 /* To enable MU_AX with MU_BRP trigger */
6005 run_iwpriv(dut, ifname, "he_sounding_mode 13");
6006 /* Sets g_force_1x1_peer to 1 which should be reset to zero for non MU
6007 * test cases */
6008 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 118 1",
6009 ifname);
6010 /* Disable DL OFDMA */
6011 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 11 0",
6012 ifname);
6013 }
6014
6015
ath_ap_set_params(struct sigma_dut * dut)6016 static void ath_ap_set_params(struct sigma_dut *dut)
6017 {
6018 const char *basedev = "wifi0";
6019 const char *basedev_radio = "wifi1";
6020 const char *ifname = get_main_ifname(dut);
6021 char *ifname_dual = NULL;
6022 int i;
6023 char buf[300];
6024 unsigned int he_mcsnssmap = dut->he_mcsnssmap;
6025
6026 if (sigma_radio_ifname[0])
6027 basedev = sigma_radio_ifname[0];
6028
6029 if (dut->ap_is_dual == 1) {
6030 basedev = sigma_radio_ifname[0];
6031 basedev_radio = sigma_radio_ifname[1];
6032 if (sigma_radio_ifname[0] &&
6033 strcmp(sigma_radio_ifname[0], "wifi0") == 0) {
6034 ifname = "ath0";
6035 ifname_dual = "ath1";
6036 } else {
6037 ifname = "ath1";
6038 ifname_dual = "ath0";
6039 }
6040 }
6041
6042 if (dut->ap_countrycode[0]) {
6043 run_iwpriv(dut, basedev, "setCountry %s", dut->ap_countrycode);
6044 sigma_dut_print(dut, DUT_MSG_INFO, "Set countrycode");
6045 }
6046
6047 for (i = 0; i < NUM_AP_AC; i++) {
6048 if (dut->ap_qos[i].ac) {
6049 run_iwpriv(dut, ifname, "cwmin %d 0 %d", i,
6050 dut->ap_qos[i].cwmin);
6051 run_iwpriv(dut, ifname, "cwmax %d 0 %d", i,
6052 dut->ap_qos[i].cwmax);
6053 run_iwpriv(dut, ifname, "aifs %d 0 %d", i,
6054 dut->ap_qos[i].aifs);
6055 run_iwpriv(dut, ifname, "txoplimit %d 0 %d", i,
6056 dut->ap_qos[i].txop);
6057 run_iwpriv(dut, ifname, "acm %d 0 %d", i,
6058 dut->ap_qos[i].acm);
6059 }
6060 }
6061
6062 for (i = 0; i < NUM_AP_AC; i++) {
6063 if (dut->ap_sta_qos[i].ac) {
6064 run_iwpriv(dut, ifname, "cwmin %d 1 %d", i,
6065 dut->ap_sta_qos[i].cwmin);
6066 run_iwpriv(dut, ifname, "cwmax %d 1 %d", i,
6067 dut->ap_sta_qos[i].cwmax);
6068 run_iwpriv(dut, ifname, "aifs %d 1 %d", i,
6069 dut->ap_sta_qos[i].aifs);
6070 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", i,
6071 dut->ap_sta_qos[i].txop);
6072 run_iwpriv(dut, ifname, "acm %d 1 %d", i,
6073 dut->ap_sta_qos[i].acm);
6074 }
6075 }
6076
6077 if (dut->ap_disable_protection == 1) {
6078 run_iwpriv(dut, ifname, "enablertscts 0");
6079 sigma_dut_print(dut, DUT_MSG_INFO, "Disabled rtscts");
6080 }
6081
6082 if (dut->ap_ldpc == VALUE_ENABLED)
6083 run_iwpriv(dut, ifname, "ldpc 3");
6084 else if (dut->ap_ldpc == VALUE_DISABLED)
6085 run_iwpriv(dut, ifname, "ldpc 0");
6086
6087 if (dut->ap_ampdu == VALUE_ENABLED) {
6088 run_iwpriv(dut, ifname, "ampdu 1");
6089 } else if (dut->ap_ampdu == VALUE_DISABLED) {
6090 run_iwpriv(dut, ifname, "ampdu 0");
6091 if (dut->program == PROGRAM_HE) {
6092 run_iwpriv(dut, ifname, "setaddbaoper 1");
6093 run_system_wrapper(dut, "wifitool %s refusealladdbas 1",
6094 ifname);
6095 if (dut->ap_amsdu == VALUE_ENABLED) {
6096 /* disable the limit for A-MSDU */
6097 run_system_wrapper(dut,
6098 "wifitool %s setUnitTestCmd 0x48 2 46 1",
6099 ifname);
6100 }
6101 }
6102 }
6103
6104 if (dut->ap_ampdu_exp) {
6105 if (dut->program == PROGRAM_VHT) {
6106 run_iwpriv(dut, ifname, "vhtmaxampdu %d",
6107 dut->ap_ampdu_exp);
6108 } else {
6109 /* 11N */
6110 run_iwpriv(dut, ifname, "maxampdu %d",
6111 dut->ap_ampdu_exp);
6112 }
6113 }
6114
6115 if (dut->ap_noack == VALUE_ENABLED) {
6116 run_iwpriv(dut, ifname, "noackpolicy 0 0 1");
6117 run_iwpriv(dut, ifname, "noackpolicy 1 0 1");
6118 run_iwpriv(dut, ifname, "noackpolicy 2 0 1");
6119 run_iwpriv(dut, ifname, "noackpolicy 3 0 1");
6120 } else if (dut->ap_noack == VALUE_DISABLED) {
6121 run_iwpriv(dut, ifname, "noackpolicy 0 0 0");
6122 run_iwpriv(dut, ifname, "noackpolicy 1 0 0");
6123 run_iwpriv(dut, ifname, "noackpolicy 2 0 0");
6124 run_iwpriv(dut, ifname, "noackpolicy 3 0 0");
6125 }
6126
6127 if (dut->device_type == AP_testbed && dut->ap_vhtmcs_map)
6128 run_iwpriv(dut, ifname, "vht_mcsmap 0x%04x",
6129 dut->ap_vhtmcs_map);
6130
6131 if (dut->ap_amsdu == VALUE_ENABLED)
6132 run_iwpriv(dut, ifname, "amsdu 2");
6133 else if (dut->ap_amsdu == VALUE_DISABLED)
6134 run_iwpriv(dut, ifname, "amsdu 1");
6135
6136 if (dut->ap_rx_amsdu == VALUE_ENABLED)
6137 run_iwpriv(dut, basedev_radio, "rx_amsdu 1");
6138 else if (dut->ap_rx_amsdu == VALUE_DISABLED)
6139 run_iwpriv(dut, basedev_radio, "rx_amsdu 0");
6140
6141 /* Command sequence to generate single VHT AMSDU and MPDU */
6142 if (dut->ap_addba_reject != VALUE_NOT_SET &&
6143 dut->ap_ampdu == VALUE_DISABLED &&
6144 dut->ap_amsdu == VALUE_ENABLED) {
6145 run_iwpriv(dut, ifname, "setaddbaoper 1");
6146
6147 snprintf(buf, sizeof(buf),
6148 "wifitool %s senddelba 1 0 1 4", ifname);
6149 if (system(buf) != 0) {
6150 sigma_dut_print(dut, DUT_MSG_ERROR,
6151 "wifitool senddelba failed");
6152 }
6153
6154 snprintf(buf, sizeof(buf), "wifitool %s sendsingleamsdu 1 0",
6155 ifname);
6156 if (system(buf) != 0) {
6157 sigma_dut_print(dut, DUT_MSG_ERROR,
6158 "wifitool sendsingleamsdu failed");
6159 }
6160
6161 run_iwpriv(dut, ifname, "amsdu 10");
6162 }
6163
6164 if (dut->ap_mode == AP_11ac) {
6165 int chwidth, nss;
6166
6167 switch (dut->ap_chwidth) {
6168 case AP_20:
6169 chwidth = 0;
6170 break;
6171 case AP_40:
6172 chwidth = 1;
6173 break;
6174 case AP_80:
6175 chwidth = 2;
6176 break;
6177 case AP_160:
6178 chwidth = 3;
6179 break;
6180 case AP_80_80:
6181 chwidth = 3;
6182 break;
6183 default:
6184 chwidth = 0;
6185 break;
6186 }
6187
6188 switch (dut->ap_tx_streams) {
6189 case 1:
6190 nss = 1;
6191 break;
6192 case 2:
6193 nss = 2;
6194 break;
6195 case 3:
6196 nss = 3;
6197 break;
6198 case 4:
6199 nss = 4;
6200 break;
6201 default:
6202 nss = 3;
6203 break;
6204 }
6205
6206 if (dut->ap_fixed_rate) {
6207 if (nss == 4)
6208 ath_disable_txbf(dut, ifname);
6209
6210 /* Set the nss */
6211 run_iwpriv(dut, ifname, "nss %d", nss);
6212
6213 /* Set the channel width */
6214 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
6215
6216 /* Set the VHT MCS */
6217 run_iwpriv(dut, ifname, "vhtmcs %d", dut->ap_mcs);
6218 }
6219 }
6220
6221 if (dut->ap_dyn_bw_sig == VALUE_ENABLED)
6222 run_iwpriv(dut, ifname, "cwmenable 1");
6223 else if (dut->ap_dyn_bw_sig == VALUE_DISABLED)
6224 run_iwpriv(dut, ifname, "cwmenable 0");
6225
6226 if (dut->ap_sig_rts == VALUE_ENABLED) {
6227 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname);
6228 if (system(buf) != 0) {
6229 sigma_dut_print(dut, DUT_MSG_ERROR,
6230 "iwconfig rts 64 failed");
6231 }
6232 } else if (dut->ap_sig_rts == VALUE_DISABLED) {
6233 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname);
6234 if (system(buf) != 0) {
6235 sigma_dut_print(dut, DUT_MSG_ERROR,
6236 "iwconfig rts 2347 failed");
6237 }
6238 }
6239
6240 if (dut->ap_hs2) {
6241 run_iwpriv(dut, ifname, "qbssload 1");
6242 sigma_dut_print(dut, DUT_MSG_INFO, "Enabled qbssload");
6243 }
6244
6245 if (dut->ap_bss_load && dut->ap_bss_load != -1) {
6246 unsigned int bssload = 0;
6247
6248 if (dut->ap_bss_load == 1) {
6249 /* STA count: 1, CU: 50, AAC: 65535 */
6250 bssload = 0x0132ffff;
6251 } else if (dut->ap_bss_load == 2) {
6252 /* STA count: 1, CU: 200, AAC: 65535 */
6253 bssload = 0x01c8ffff;
6254 } else if (dut->ap_bss_load == 3) {
6255 /* STA count: 1, CU: 75, AAC: 65535 */
6256 bssload = 0x014bffff;
6257 }
6258
6259 run_iwpriv(dut, ifname, "hcbssload %u", bssload);
6260 } else if (dut->ap_bss_load == 0) {
6261 run_iwpriv(dut, ifname, "qbssload 0");
6262 sigma_dut_print(dut, DUT_MSG_INFO, "Disabled qbssload");
6263 }
6264
6265 if (dut->ap_dgaf_disable) {
6266 run_iwpriv(dut, ifname, "dgaf_disable 1");
6267 sigma_dut_print(dut, DUT_MSG_INFO, "Enabled dgaf_disable");
6268 }
6269
6270 if (dut->ap_l2tif) {
6271 run_iwpriv(dut, ifname, "l2tif 1");
6272 snprintf(buf, sizeof(buf),
6273 "echo 1 > /sys/class/net/br0/brif/ath0/hotspot_l2tif");
6274 if (system(buf) != 0)
6275 sigma_dut_print(dut, DUT_MSG_ERROR,
6276 "l2tif br failed");
6277
6278 snprintf(buf, sizeof(buf),
6279 "echo 1 > /sys/class/net/br0/brif/eth0/hotspot_wan");
6280 if (system(buf) != 0)
6281 sigma_dut_print(dut, DUT_MSG_ERROR,
6282 "l2tif brif failed");
6283 sigma_dut_print(dut, DUT_MSG_INFO, "Enabled l2tif");
6284 }
6285
6286 if (dut->ap_ndpa_frame == 0) {
6287 snprintf(buf, sizeof(buf),
6288 "wifitool %s beeliner_fw_test 117 192", ifname);
6289 if (system(buf) != 0) {
6290 sigma_dut_print(dut, DUT_MSG_ERROR,
6291 "wifitool beeliner_fw_test 117 192 failed");
6292 }
6293 snprintf(buf, sizeof(buf),
6294 "wifitool %s beeliner_fw_test 118 192", ifname);
6295 if (system(buf) != 0) {
6296 sigma_dut_print(dut, DUT_MSG_ERROR,
6297 "wifitool beeliner_fw_test 117 192 failed");
6298 }
6299 } else if (dut->ap_ndpa_frame == 1) {
6300 /* Driver default - no changes needed */
6301 } else if (dut->ap_ndpa_frame == 2) {
6302 snprintf(buf, sizeof(buf),
6303 "wifitool %s beeliner_fw_test 115 1", ifname);
6304 if (system(buf) != 0) {
6305 sigma_dut_print(dut, DUT_MSG_ERROR,
6306 "wifitool beeliner_fw_test 117 192 failed");
6307 }
6308 snprintf(buf, sizeof(buf),
6309 "wifitool %s beeliner_fw_test 116 1", ifname);
6310 if (system(buf) != 0) {
6311 sigma_dut_print(dut, DUT_MSG_ERROR,
6312 "wifitool beeliner_fw_test 117 192 failed");
6313 }
6314 }
6315
6316 if (dut->ap_rtt == 1)
6317 run_iwpriv(dut, ifname, "enable_rtt 1");
6318
6319 if (dut->ap_lci == 1)
6320 run_iwpriv(dut, ifname, "enable_lci 1");
6321
6322 if (dut->ap_lcr == 1)
6323 run_iwpriv(dut, ifname, "enable_lcr 1");
6324
6325 if (dut->ap_rrm == 1)
6326 run_iwpriv(dut, ifname, "enable_rmm 1");
6327
6328 if (dut->ap_lci == 1 || dut->ap_lcr == 1) {
6329 run_system(dut, "wpc -l /tmp/lci_cfg.txt");
6330 }
6331
6332 if (dut->ap_neighap >= 1 && dut->ap_lci == 0) {
6333 FILE *f;
6334
6335 f = fopen("/tmp/nbr_report.txt", "w");
6336 if (!f) {
6337 sigma_dut_print(dut, DUT_MSG_ERROR,
6338 "Failed to open /tmp/nbr_report.txt");
6339 return;
6340 }
6341
6342 fprintf(f,
6343 "ap_1 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x2a 0x00\n",
6344 dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1],
6345 dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3],
6346 dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5],
6347 dut->ap_val_opchannel[0]);
6348 fclose(f);
6349
6350 f = fopen("/tmp/ftmrr.txt", "w");
6351 if (!f) {
6352 sigma_dut_print(dut, DUT_MSG_ERROR,
6353 "Failed to open /tmp/ftmrr.txt");
6354 return;
6355 }
6356
6357 fprintf(f,
6358 "ap_1 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x2a 0x00\n",
6359 dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1],
6360 dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3],
6361 dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5],
6362 dut->ap_val_opchannel[0]);
6363 fclose(f);
6364 }
6365
6366 if (dut->ap_neighap >= 2 && dut->ap_lci == 0) {
6367 FILE *f;
6368
6369 f = fopen("/tmp/nbr_report.txt", "a");
6370 if (!f) {
6371 sigma_dut_print(dut, DUT_MSG_ERROR,
6372 "Failed to open /tmp/nbr_report.txt");
6373 return;
6374 }
6375 fprintf(f,
6376 "ap_2 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x6a 0x00\n",
6377 dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1],
6378 dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3],
6379 dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5],
6380 dut->ap_val_opchannel[1]);
6381 fclose(f);
6382
6383 f = fopen("/tmp/ftmrr.txt", "a");
6384 if (!f) {
6385 sigma_dut_print(dut, DUT_MSG_ERROR,
6386 "Failed to open /tmp/ftmrr.txt");
6387 return;
6388 }
6389 fprintf(f,
6390 "ap_2 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x6a 0x00\n",
6391 dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1],
6392 dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3],
6393 dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5],
6394 dut->ap_val_opchannel[1]);
6395 fclose(f);
6396 }
6397
6398 if (dut->ap_neighap >= 3 && dut->ap_lci == 0) {
6399 FILE *f;
6400
6401 f = fopen("/tmp/nbr_report.txt", "a");
6402 if (!f) {
6403 sigma_dut_print(dut, DUT_MSG_ERROR,
6404 "Failed to open /tmp/nbr_report.txt");
6405 return;
6406 }
6407
6408 fprintf(f,
6409 "ap_3 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x9b 0x00\n",
6410 dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1],
6411 dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3],
6412 dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5],
6413 dut->ap_val_opchannel[2]);
6414 fclose(f);
6415
6416 f = fopen("/tmp/ftmrr.txt", "a");
6417 if (!f) {
6418 sigma_dut_print(dut, DUT_MSG_ERROR,
6419 "Failed to open /tmp/ftmrr.txt");
6420 return;
6421 }
6422
6423 fprintf(f,
6424 "ap_3 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x9b 0x00\n",
6425 dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1],
6426 dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3],
6427 dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5],
6428 dut->ap_val_opchannel[2]);
6429 fclose(f);
6430 }
6431
6432 if (dut->ap_neighap) {
6433 run_iwpriv(dut, ifname, "enable_rtt 1");
6434 run_iwpriv(dut, ifname, "enable_lci 1");
6435 run_iwpriv(dut, ifname, "enable_lcr 1");
6436 run_iwpriv(dut, ifname, "enable_rrm 1");
6437 }
6438
6439 if (dut->ap_scan == 1) {
6440 run_iwpriv(dut, ifname, "scanentryage 600");
6441 snprintf(buf, sizeof(buf), "iwlist %s scan", ifname);
6442 run_system(dut, buf);
6443 }
6444
6445 if (dut->ap_set_bssidpref) {
6446 snprintf(buf, sizeof(buf),
6447 "wifitool %s setbssidpref 00:00:00:00:00:00 0 00 00",
6448 ifname);
6449 if (system(buf) != 0) {
6450 sigma_dut_print(dut, DUT_MSG_ERROR,
6451 "wifitool clear bssidpref failed");
6452 }
6453 }
6454
6455 if (dut->wnm_bss_max_feature != VALUE_NOT_SET) {
6456 int feature_enable;
6457
6458 feature_enable = dut->wnm_bss_max_feature == VALUE_ENABLED;
6459 run_iwpriv(dut, ifname, "wnm %d", feature_enable);
6460 run_iwpriv(dut, ifname, "wnm_bss %d", feature_enable);
6461 if (feature_enable) {
6462 const char *extra = "";
6463
6464 if (dut->wnm_bss_max_protection != VALUE_NOT_SET) {
6465 if (dut->wnm_bss_max_protection ==
6466 VALUE_ENABLED)
6467 extra = " 1";
6468 else
6469 extra = " 0";
6470 }
6471 snprintf(buf, sizeof(buf),
6472 "wlanconfig %s wnm setbssmax %d%s",
6473 ifname, dut->wnm_bss_max_idle_time, extra);
6474 run_system(dut, buf);
6475 }
6476 }
6477
6478 if (dut->program == PROGRAM_MBO) {
6479 apply_mbo_pref_ap_list(dut);
6480 run_iwpriv(dut, ifname, "mbo_cel_pref %d",
6481 dut->ap_cell_cap_pref);
6482 run_iwpriv(dut, ifname, "mbocap 0x40");
6483 ath_set_assoc_disallow(dut, ifname, "disable");
6484 }
6485
6486 if (dut->ap_oce == VALUE_ENABLED)
6487 run_iwpriv(dut, ifname, "set_bpr_enable 1");
6488
6489 if (dut->ap_oce == VALUE_ENABLED && dut->ap_channel <= 11) {
6490 run_iwpriv(dut, ifname, "prb_rate 5500");
6491 run_iwpriv(dut, ifname, "set_bcn_rate 5500");
6492 }
6493
6494 if (dut->ap_oce == VALUE_DISABLED)
6495 run_iwpriv(dut, ifname, "set_bpr_enable 0");
6496
6497 if (dut->ap_oce == VALUE_DISABLED && dut->ap_channel <= 11) {
6498 run_iwpriv(dut, ifname, "mgmt_rate 1000");
6499 run_iwpriv(dut, ifname, "set_bcn_rate 1000");
6500 }
6501
6502 if (dut->ap_bcnint)
6503 run_iwpriv(dut, ifname, "bintval %d", dut->ap_bcnint);
6504
6505 if (dut->ap_filsdscv == VALUE_DISABLED)
6506 run_iwpriv(dut, ifname, "enable_fils 0 0");
6507
6508 if (dut->ap_filshlp == VALUE_ENABLED)
6509 run_iwpriv(dut, ifname, "oce_hlp 1");
6510 else if (dut->ap_filshlp == VALUE_DISABLED)
6511 run_iwpriv(dut, ifname, "oce_hlp 0");
6512
6513 /* When RNR is enabled, also enable apchannelreport, background scan */
6514 if (dut->ap_rnr == VALUE_ENABLED) {
6515 run_iwpriv(dut, ifname, "rnr 1");
6516 run_iwpriv(dut, ifname, "rnr_tbtt 1");
6517 run_iwpriv(dut, ifname, "apchanrpt 1");
6518 run_iwpriv(dut, basedev, "acs_ctrlflags 0x4");
6519 run_iwpriv(dut, basedev, "acs_scanintvl 60");
6520 run_iwpriv(dut, basedev, "acs_bkscanen 1");
6521 if (dut->ap_is_dual == 1) {
6522 run_iwpriv(dut, ifname_dual, "rnr 1");
6523 run_iwpriv(dut, ifname_dual, "rnr_tbtt 1");
6524 run_iwpriv(dut, ifname_dual, "apchanrpt 1");
6525 run_iwpriv(dut, basedev_radio, "acs_ctrlflags 0x4");
6526 run_iwpriv(dut, basedev_radio, "acs_scanintvl 60");
6527 run_iwpriv(dut, basedev_radio, "acs_bkscanen 1");
6528 }
6529 }
6530
6531 if (dut->ap_blechanutil || dut->ap_ble_admit_cap || dut->ap_blestacnt) {
6532 run_iwpriv(dut, ifname, "qbssload 0");
6533 snprintf(buf, sizeof(buf),
6534 "wlanconfig %s addie ftype 0 len 7 data 0b05%02x%02x%02x%02x%02x ",
6535 ifname, dut->ap_blestacnt & 0xFF,
6536 dut->ap_blestacnt >> 8, dut->ap_blechanutil,
6537 dut->ap_ble_admit_cap & 0xFF,
6538 dut->ap_ble_admit_cap >> 8);
6539 run_system(dut, buf);
6540 snprintf(buf, sizeof(buf),
6541 "wlanconfig %s addie ftype 2 len 7 data 0b05%02x%02x%02x%02x%02x ",
6542 ifname, dut->ap_blestacnt & 0xFF,
6543 dut->ap_blestacnt >> 8, dut->ap_blechanutil,
6544 dut->ap_ble_admit_cap & 0xFF,
6545 dut->ap_ble_admit_cap >> 8);
6546 run_system(dut, buf);
6547 }
6548
6549 if (dut->ap_esp == VALUE_ENABLED)
6550 run_iwpriv(dut, basedev, "esp_period 5");
6551 else if (dut->ap_esp == VALUE_DISABLED)
6552 run_iwpriv(dut, basedev, "esp_period 0");
6553
6554 if (dut->ap_datappdudura)
6555 run_iwpriv(dut, basedev, "esp_ppdu_dur %d",
6556 dut->ap_datappdudura);
6557
6558 if (dut->ap_airtimefract)
6559 run_iwpriv(dut, basedev, "esp_airtime %d",
6560 dut->ap_airtimefract);
6561
6562 if (dut->ap_dhcp_stop) {
6563 snprintf(buf, sizeof(buf), "/etc/init.d/dnsmasq stop");
6564 run_system(dut, buf);
6565 }
6566
6567 if (dut->ap_bawinsize)
6568 run_iwpriv(dut, basedev, "esp_ba_window %d", dut->ap_bawinsize);
6569
6570 if (dut->program == PROGRAM_DPP) {
6571 if (dut->ap_interface_2g == 1) {
6572 run_iwpriv(dut, ifname, "set_bcn_rate 5500");
6573 run_iwpriv(dut, ifname, "prb_rate 5500");
6574 run_iwpriv(dut, ifname, "mgmt_rate 5500");
6575 }
6576
6577 run_iwpriv(dut, basedev, "set_rxfilter 0xffffffff");
6578 dut->hostapd_running = 1;
6579 }
6580
6581 if (dut->program == PROGRAM_HE) {
6582 /* disable sending basic triggers */
6583 run_system_wrapper(dut,
6584 "wifitool %s setUnitTestCmd 0x47 2 42 0",
6585 ifname);
6586 /* disable MU BAR */
6587 run_system_wrapper(dut,
6588 "wifitool %s setUnitTestCmd 0x47 2 64 1",
6589 ifname);
6590 /* disable PSD Boost */
6591 run_system_wrapper(dut,
6592 "wifitool %s setUnitTestCmd 0x48 2 142 1",
6593 ifname);
6594 /* Enable mix bw */
6595 run_system_wrapper(dut,
6596 "wifitool %s setUnitTestCmd 0x47 2 141 1",
6597 ifname);
6598 /* Disable preferred AC */
6599 run_system_wrapper(dut,
6600 "wifitool %s setUnitTestCmd 0x48 2 186 0",
6601 ifname);
6602 run_iwpriv(dut, basedev, "he_muedca_mode 0");
6603 run_iwpriv(dut, ifname, "he_ul_ofdma 0");
6604 run_iwpriv(dut, ifname, "he_dl_ofdma 0");
6605 if (dut->he_set_sta_1x1 == VALUE_ENABLED) {
6606 /* sets g_force_1x1_peer to 1 */
6607 run_system_wrapper(dut,
6608 "wifitool %s setUnitTestCmd 0x48 2 118 1",
6609 ifname);
6610 }
6611 if (dut->ap_txBF) {
6612 /* Enable SU_AX sounding */
6613 run_iwpriv(dut, ifname, "he_sounding_mode 1");
6614 /* Ignore TBTT for NDP */
6615 run_system_wrapper(dut,
6616 "wifitool %s setUnitTestCmd 0x48 2 2 1",
6617 ifname);
6618 /* g_cv_query_enable=1, i.e., cv query enable */
6619 run_system_wrapper(dut,
6620 "wifitool %s setUnitTestCmd 0x47 2 7 1",
6621 ifname);
6622 /* Override TPC calculations and set TxBF flag to True
6623 */
6624 run_system_wrapper(dut,
6625 "wifitool %s setUnitTestCmd 0x47 2 47 1",
6626 ifname);
6627 }
6628 if (dut->device_type == AP_testbed) {
6629 run_iwpriv(dut, ifname, "tx_stbc 0");
6630 run_iwpriv(dut, ifname, "he_txmcsmap 0x0");
6631 run_iwpriv(dut, ifname, "he_rxmcsmap 0x0");
6632 run_iwpriv(dut, ifname, "he_amsdu_in_ampdu_supp 0");
6633 run_iwpriv(dut, ifname, "he_bfee_sts_supp 0 0");
6634 run_iwpriv(dut, ifname, "he_4xltf_800nsgi_rx 0");
6635 run_iwpriv(dut, ifname, "he_1xltf_800nsgi_rx 0");
6636 run_iwpriv(dut, ifname, "he_max_nc 0");
6637 run_iwpriv(dut, ifname, "he_bsr_supp 0");
6638 run_iwpriv(dut, ifname, "rx_stbc 0");
6639 if (dut->ap_he_dlofdma == VALUE_DISABLED)
6640 run_iwpriv(dut, ifname, "he_dlofdma 0");
6641 if (dut->ap_channel <= 11) {
6642 dut->ap_bcc = VALUE_ENABLED;
6643 run_iwpriv(dut, ifname, "vht_11ng 0");
6644 }
6645 if (!dut->ap_txBF) {
6646 run_iwpriv(dut, ifname, "he_subfer 0");
6647 run_iwpriv(dut, ifname, "he_subfee 0");
6648 }
6649 if (!dut->ap_mu_txBF) {
6650 run_iwpriv(dut, ifname, "he_mubfer 0");
6651 run_iwpriv(dut, ifname, "he_mubfee 0");
6652 }
6653 if (dut->ap_cipher == AP_WEP ||
6654 dut->ap_cipher == AP_TKIP)
6655 run_iwpriv(dut, ifname, "htweptkip 1");
6656 if (dut->ap_rx_streams || dut->ap_tx_streams)
6657 run_iwpriv(dut, ifname, "nss %d",
6658 dut->ap_rx_streams);
6659 }
6660 }
6661
6662 if (dut->ap_he_ulofdma == VALUE_ENABLED) {
6663 run_iwpriv(dut, ifname, "he_ul_ofdma 1");
6664 run_iwpriv(dut, ifname, "he_mu_edca 1");
6665
6666 /* Disable sounding for UL OFDMA */
6667 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0",
6668 ifname);
6669
6670 if ((dut->ap_rx_streams || dut->ap_tx_streams) &&
6671 dut->device_type == AP_testbed) {
6672 unsigned int txchainmask = 0x00;
6673
6674 switch (dut->ap_rx_streams) {
6675 case 1:
6676 txchainmask = 0x01;
6677 break;
6678 case 2:
6679 txchainmask = 0x03;
6680 break;
6681 case 3:
6682 txchainmask = 0x07;
6683 break;
6684 case 4:
6685 txchainmask = 0x0f;
6686 break;
6687 case 5:
6688 txchainmask = 0x1f;
6689 break;
6690 case 6:
6691 txchainmask = 0x3f;
6692 break;
6693 case 7:
6694 txchainmask = 0x7f;
6695 break;
6696 case 8:
6697 txchainmask = 0xff;
6698 break;
6699 }
6700
6701 run_iwpriv(dut, ifname, "he_ul_nss %d",
6702 dut->ap_rx_streams);
6703 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
6704 run_iwpriv(dut, basedev, "rxchainmask %d", txchainmask);
6705 }
6706
6707 if (dut->ap_channel == 100 && dut->device_type == AP_testbed)
6708 run_system_wrapper(dut, "iwpriv %s inact 1000", ifname);
6709
6710 if (dut->he_ul_mcs)
6711 run_iwpriv(dut, ifname, "he_ul_mcs %d", dut->he_ul_mcs);
6712
6713 run_iwpriv(dut, ifname, "he_ul_ltf 3");
6714 run_iwpriv(dut, ifname, "he_ul_shortgi 3");
6715 run_iwpriv(dut, basedev, "he_ul_trig_int 2");
6716
6717 /* Disable efficiency check for UL OFDMA. We do not send TBPPDU
6718 * for one user. With this command, we would send UL OFDMA even
6719 * for one user to allow testing to be done without requiring
6720 * more than one station. */
6721 run_system_wrapper(dut,
6722 "wifitool %s setUnitTestCmd 0x47 2 131 0",
6723 ifname);
6724 /* Set random RU allocation */
6725 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 9 1",
6726 ifname);
6727 /* To set TBTT PPDU duration (us) */
6728 run_system_wrapper(dut,
6729 "wifitool %s setUnitTestCmd 0x48 2 63 1908",
6730 ifname);
6731 }
6732
6733 if (dut->ap_he_dlofdma == VALUE_ENABLED) {
6734 run_iwpriv(dut, ifname, "he_dl_ofdma 1", ifname);
6735
6736 /* For fixed MCS */
6737 novap_reset(dut, ifname, 0);
6738 run_iwpriv(dut, ifname,
6739 "cfg80211tool %s setratemask 3 0x80f80f80 0x0f80f80f 0xf80f80f8");
6740 }
6741
6742 if (dut->ap_he_ppdu == PPDU_MU && dut->ap_he_dlofdma == VALUE_ENABLED) {
6743 /* Increase the min TX time limit for MU MIMO to disable MU MIMO
6744 * scheduling */
6745 run_system_wrapper(dut,
6746 "wifitool %s setUnitTestCmd 0x47 2 11 1000000",
6747 ifname);
6748 /* Increase the max TX time limit for DL OFDMA to enable OFDMA
6749 * scheduling */
6750 run_system_wrapper(dut,
6751 "wifitool %s setUnitTestCmd 0x47 2 17 1000000",
6752 ifname);
6753 /* Disable 'force SU schedule' to enable MU sch */
6754 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 8 0",
6755 ifname);
6756 /* Enable MU 11ax support in sch algo */
6757 run_system_wrapper(dut,
6758 "wifitool %s setUnitTestCmd 0x47 2 29 0",
6759 ifname);
6760 /* Enable to sort RU allocation */
6761 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x4b 2 2 1",
6762 ifname);
6763 }
6764
6765 if (dut->ap_numsounddim) {
6766 unsigned int txchainmask = 0;
6767
6768 switch (dut->ap_numsounddim) {
6769 case 1:
6770 txchainmask = 0x01;
6771 break;
6772 case 2:
6773 txchainmask = 0x03;
6774 break;
6775 case 3:
6776 txchainmask = 0x07;
6777 break;
6778 case 4:
6779 txchainmask = 0x0f;
6780 break;
6781 case 5:
6782 txchainmask = 0x1f;
6783 break;
6784 case 6:
6785 txchainmask = 0x3f;
6786 break;
6787 case 7:
6788 txchainmask = 0x7f;
6789 break;
6790 case 8:
6791 txchainmask = 0xff;
6792 break;
6793 }
6794 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
6795 }
6796
6797 if (dut->ap_numsounddim && dut->device_type == AP_testbed) {
6798 /* Sets g_force_1x1_peer to 1 which should be reset to zero
6799 * for non-MU test cases */
6800 run_system_wrapper(dut,
6801 "wifitool %s setUnitTestCmd 0x48 2 118 1",
6802 ifname);
6803 if (dut->ap_mu_txBF) {
6804 /* Disable DL OFDMA */
6805 run_system_wrapper(dut,
6806 "wifitool %s setUnitTestCmd 0x47 2 11 0",
6807 ifname);
6808 }
6809 }
6810
6811 if (dut->ap_bcc == VALUE_ENABLED) {
6812 run_iwpriv(dut, ifname, "mode 11AHE20");
6813 run_iwpriv(dut, ifname, "nss 2");
6814 run_iwpriv(dut, ifname, "he_txmcsmap 0x0");
6815 run_iwpriv(dut, ifname, "he_rxmcsmap 0x0");
6816 }
6817
6818 if (dut->ap_he_frag == VALUE_ENABLED)
6819 run_iwpriv(dut, ifname, "he_frag 1");
6820 else if (dut->ap_he_frag == VALUE_DISABLED)
6821 run_iwpriv(dut, ifname, "he_frag 0");
6822
6823 if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) {
6824 if (dut->ap_ba_bufsize == BA_BUFSIZE_64)
6825 run_iwpriv(dut, ifname, "ba_bufsize 0");
6826 else
6827 run_iwpriv(dut, ifname, "ba_bufsize 1");
6828 }
6829
6830 if (dut->ap_mu_edca == VALUE_ENABLED)
6831 run_iwpriv(dut, ifname, "he_mu_edca 1");
6832
6833 if (dut->ap_he_mimo == MIMO_DL) {
6834 mubrp_commands(dut, ifname);
6835 if (dut->device_type != AP_testbed)
6836 run_system_wrapper(
6837 dut, "wifitool %s setUnitTestCmd 0x48 2 100 2",
6838 ifname);
6839 }
6840
6841 if (dut->ap_he_mimo == MIMO_UL)
6842 run_iwpriv(dut, ifname, "he_mubfee 1");
6843
6844 if (dut->ap_he_rtsthrshld == VALUE_ENABLED)
6845 run_iwpriv(dut, ifname, "he_rtsthrshld 512");
6846 else if (dut->ap_he_rtsthrshld == VALUE_DISABLED)
6847 run_iwpriv(dut, ifname, "he_rtsthrshld 1024");
6848
6849 if (dut->ap_mbssid == VALUE_ENABLED &&
6850 (dut->ap_rx_streams || dut->ap_tx_streams) &&
6851 dut->device_type == AP_testbed) {
6852 const char *ifname_1;
6853
6854 ifname_1= dut->ap_channel >= 36 ? "ath01" : "ath11";
6855
6856 /* NSS is not set in Secondary VAP for MBSSID case,
6857 * hence it is explicitly set here. For primary VAP
6858 * NSS is set during AP configuration */
6859 run_iwpriv(dut, ifname_1, "nss %d", dut->ap_rx_streams);
6860 }
6861
6862 if (dut->ap_twtresp == VALUE_ENABLED)
6863 run_iwpriv(dut, ifname, "twt_responder 1");
6864 else if (dut->ap_twtresp == VALUE_DISABLED)
6865 run_iwpriv(dut, ifname, "twt_responder 0");
6866
6867 if (dut->program == PROGRAM_HE && dut->ap_fixed_rate) {
6868 int nss = 0, mcs = 0;
6869 uint16_t mcsnssmap = 0;
6870
6871 /* MCS 7 is used - set only nss and he_mcs.
6872 * Do not set mcsnssmap unless MCS is 9 or 11. */
6873 if (dut->ap_mcs >= 9) {
6874 if (dut->ap_mcs == 9) {
6875 if (dut->ap_tx_streams == 1) {
6876 nss = 1;
6877 mcs = dut->ap_mcs;
6878 } else if (dut->ap_tx_streams == 2) {
6879 nss = 2;
6880 mcs = dut->ap_mcs;
6881 }
6882 } else if (dut->ap_mcs == 11) {
6883 if (dut->ap_tx_streams == 1) {
6884 nss = 1;
6885 mcs = dut->ap_mcs;
6886 } else if (dut->ap_tx_streams == 2) {
6887 nss = 2;
6888 mcs = dut->ap_mcs;
6889 }
6890 }
6891
6892 get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs);
6893 he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap;
6894 }
6895
6896 run_iwpriv(dut, ifname, "nss %d", dut->ap_tx_streams);
6897 run_iwpriv(dut, ifname, "he_mcs %d", dut->ap_mcs);
6898 }
6899
6900 if (he_mcsnssmap) {
6901 run_iwpriv(dut, ifname, "he_rxmcsmap %lu", he_mcsnssmap);
6902 run_iwpriv(dut, ifname, "he_txmcsmap %lu", he_mcsnssmap);
6903 }
6904
6905 if (dut->he_sounding == VALUE_ENABLED)
6906 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0",
6907 ifname);
6908
6909 if (dut->he_mmss)
6910 run_iwpriv(dut, ifname, "ampduden_ovrd %d", dut->he_mmss);
6911
6912 if (dut->he_srctrl_allow == 0) {
6913 /* This is a special testbed AP case to enable SR for protocol
6914 * testing when SRCtrl_SRValue15Allowed is specified.
6915 */
6916 run_iwpriv(dut, ifname, "he_sr_enable 1");
6917 }
6918 }
6919
6920
cmd_ath_ap_config_commit(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)6921 static int cmd_ath_ap_config_commit(struct sigma_dut *dut,
6922 struct sigma_conn *conn,
6923 struct sigma_cmd *cmd)
6924 {
6925 /* const char *name = get_param(cmd, "NAME"); */
6926 char buf[100];
6927 struct stat s;
6928 const char *ifname = dut->ap_is_dual ? "ath1" : "ath0";
6929 int res;
6930
6931 if (stat("/proc/athversion", &s) == 0) {
6932 sigma_dut_print(dut, DUT_MSG_INFO, "Run apdown");
6933 run_system(dut, "apdown");
6934 }
6935
6936 cmd_ath_ap_radio_config(dut);
6937
6938 snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID=%s'", dut->ap_ssid);
6939 run_system(dut, buf);
6940
6941 switch (dut->ap_key_mgmt) {
6942 case AP_OPEN:
6943 if (dut->ap_cipher == AP_WEP) {
6944 run_system(dut, "cfg -a AP_SECMODE=WEP");
6945 run_system(dut, "cfg -a AP_SECFILE=NONE");
6946 /* shared auth mode not supported */
6947 run_system(dut, "cfg -a AP_WEP_MODE_0=1");
6948 run_system(dut, "cfg -a AP_WEP_MODE_1=1");
6949 snprintf(buf, sizeof(buf),
6950 "cfg -a WEP_RADIO_NUM0_KEY_1=%s",
6951 dut->ap_wepkey);
6952 run_system(dut, buf);
6953 snprintf(buf, sizeof(buf),
6954 "cfg -a WEP_RADIO_NUM1_KEY_1=%s",
6955 dut->ap_wepkey);
6956 run_system(dut, buf);
6957 } else {
6958 run_system(dut, "cfg -a AP_SECMODE=None");
6959 }
6960 break;
6961 case AP_WPA2_PSK:
6962 case AP_WPA2_PSK_MIXED:
6963 case AP_WPA_PSK:
6964 case AP_WPA2_SAE:
6965 case AP_WPA2_PSK_SAE:
6966 if (dut->ap_key_mgmt == AP_WPA2_PSK ||
6967 dut->ap_key_mgmt == AP_WPA2_SAE ||
6968 dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
6969 run_system(dut, "cfg -a AP_WPA=2");
6970 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
6971 run_system(dut, "cfg -a AP_WPA=3");
6972 else
6973 run_system(dut, "cfg -a AP_WPA=1");
6974 /* TODO: SAE configuration */
6975 run_system(dut, "cfg -a AP_SECMODE=WPA");
6976 run_system(dut, "cfg -a AP_SECFILE=PSK");
6977 res = snprintf(buf, sizeof(buf), "cfg -a 'PSK_KEY=%s'",
6978 dut->ap_passphrase);
6979 if (res < 0 || res >= sizeof(buf))
6980 return ERROR_SEND_STATUS;
6981 run_system(dut, buf);
6982 if (dut->ap_cipher == AP_CCMP_TKIP)
6983 run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\"");
6984 else if (dut->ap_cipher == AP_TKIP)
6985 run_system(dut, "cfg -a AP_CYPHER=TKIP");
6986 else
6987 run_system(dut, "cfg -a AP_CYPHER=CCMP");
6988 break;
6989 case AP_WPA2_EAP:
6990 case AP_WPA2_EAP_MIXED:
6991 case AP_WPA_EAP:
6992 if (dut->ap_key_mgmt == AP_WPA2_EAP)
6993 run_system(dut, "cfg -a AP_WPA=2");
6994 else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
6995 run_system(dut, "cfg -a AP_WPA=3");
6996 else
6997 run_system(dut, "cfg -a AP_WPA=1");
6998 run_system(dut, "cfg -a AP_SECMODE=WPA");
6999 run_system(dut, "cfg -a AP_SECFILE=EAP");
7000 if (dut->ap_cipher == AP_CCMP_TKIP)
7001 run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\"");
7002 else if (dut->ap_cipher == AP_TKIP)
7003 run_system(dut, "cfg -a AP_CYPHER=TKIP");
7004 else
7005 run_system(dut, "cfg -a AP_CYPHER=CCMP");
7006 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER=%s",
7007 dut->ap_radius_ipaddr);
7008 run_system(dut, buf);
7009 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT=%d",
7010 dut->ap_radius_port);
7011 run_system(dut, buf);
7012 res = snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SECRET=%s",
7013 dut->ap_radius_password);
7014 if (res < 0 || res >= sizeof(buf))
7015 return ERROR_SEND_STATUS;
7016 run_system(dut, buf);
7017 break;
7018 case AP_WPA2_EAP_OSEN:
7019 /* TODO */
7020 sigma_dut_print(dut, DUT_MSG_ERROR, "EAP+OSEN not supported");
7021 break;
7022 case AP_SUITEB:
7023 /* TODO */
7024 sigma_dut_print(dut, DUT_MSG_ERROR, "SuiteB not supported");
7025 break;
7026 case AP_WPA2_OWE:
7027 /* TODO */
7028 sigma_dut_print(dut, DUT_MSG_ERROR, "OWE not supported");
7029 break;
7030 case AP_WPA2_FT_EAP:
7031 case AP_WPA2_FT_PSK:
7032 case AP_WPA2_EAP_SHA256:
7033 case AP_WPA2_PSK_SHA256:
7034 case AP_WPA2_ENT_FT_EAP:
7035 case AP_OSEN:
7036 /* TODO */
7037 send_resp(dut, conn, SIGMA_ERROR,
7038 "errorCode,Unsupported KeyMgnt value");
7039 return 0;
7040 }
7041
7042 if (dut->ap_is_dual) {
7043 /* ath1 settings in case of dual */
7044 snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID_2=%s'",
7045 dut->ap_ssid);
7046 run_system(dut, buf);
7047
7048 switch (dut->ap_key_mgmt) {
7049 case AP_OPEN:
7050 if (dut->ap_cipher == AP_WEP) {
7051 run_system(dut, "cfg -a AP_SECMODE_2=WEP");
7052 run_system(dut, "cfg -a AP_SECFILE_2=NONE");
7053 /* shared auth mode not supported */
7054 run_system(dut, "cfg -a AP_WEP_MODE_0=1");
7055 run_system(dut, "cfg -a AP_WEP_MODE_1=1");
7056 snprintf(buf, sizeof(buf),
7057 "cfg -a WEP_RADIO_NUM0_KEY_1=%s",
7058 dut->ap_wepkey);
7059 run_system(dut, buf);
7060 snprintf(buf, sizeof(buf),
7061 "cfg -a WEP_RADIO_NUM1_KEY_1=%s",
7062 dut->ap_wepkey);
7063 run_system(dut, buf);
7064 } else {
7065 run_system(dut, "cfg -a AP_SECMODE_2=None");
7066 }
7067 break;
7068 case AP_WPA2_PSK:
7069 case AP_WPA2_PSK_MIXED:
7070 case AP_WPA_PSK:
7071 case AP_WPA2_SAE:
7072 case AP_WPA2_PSK_SAE:
7073 if (dut->ap_key_mgmt == AP_WPA2_PSK ||
7074 dut->ap_key_mgmt == AP_WPA2_SAE ||
7075 dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
7076 run_system(dut, "cfg -a AP_WPA_2=2");
7077 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
7078 run_system(dut, "cfg -a AP_WPA_2=3");
7079 else
7080 run_system(dut, "cfg -a AP_WPA_2=1");
7081 // run_system(dut, "cfg -a AP_WPA_2=2");
7082 /* TODO: SAE configuration */
7083 run_system(dut, "cfg -a AP_SECMODE_2=WPA");
7084 run_system(dut, "cfg -a AP_SECFILE_2=PSK");
7085 res = snprintf(buf, sizeof(buf),
7086 "cfg -a 'PSK_KEY_2=%s'",
7087 dut->ap_passphrase);
7088 if (res < 0 || res >= sizeof(buf))
7089 return ERROR_SEND_STATUS;
7090 run_system(dut, buf);
7091 if (dut->ap_cipher == AP_CCMP_TKIP)
7092 run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\"");
7093 else if (dut->ap_cipher == AP_TKIP)
7094 run_system(dut, "cfg -a AP_CYPHER_2=TKIP");
7095 else
7096 run_system(dut, "cfg -a AP_CYPHER_2=CCMP");
7097 break;
7098 case AP_WPA2_EAP:
7099 case AP_WPA2_EAP_MIXED:
7100 case AP_WPA_EAP:
7101 if (dut->ap_key_mgmt == AP_WPA2_EAP)
7102 run_system(dut, "cfg -a AP_WPA_2=2");
7103 else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
7104 run_system(dut, "cfg -a AP_WPA_2=3");
7105 else
7106 run_system(dut, "cfg -a AP_WPA_2=1");
7107 run_system(dut, "cfg -a AP_SECMODE_2=WPA");
7108 run_system(dut, "cfg -a AP_SECFILE_2=EAP");
7109 if (dut->ap_cipher == AP_CCMP_TKIP)
7110 run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\"");
7111 else if (dut->ap_cipher == AP_TKIP)
7112 run_system(dut, "cfg -a AP_CYPHER_2=TKIP");
7113 else
7114 run_system(dut, "cfg -a AP_CYPHER_2=CCMP");
7115
7116 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER_2=%s",
7117 dut->ap_radius_ipaddr);
7118 run_system(dut, buf);
7119 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT_2=%d",
7120 dut->ap_radius_port);
7121 run_system(dut, buf);
7122 res = snprintf(buf, sizeof(buf),
7123 "cfg -a AP_AUTH_SECRET_2=%s",
7124 dut->ap_radius_password);
7125 if (res < 0 || res >= sizeof(buf))
7126 return ERROR_SEND_STATUS;
7127 run_system(dut, buf);
7128 break;
7129 case AP_WPA2_EAP_OSEN:
7130 /* TODO */
7131 sigma_dut_print(dut, DUT_MSG_ERROR,
7132 "EAP+OSEN not supported");
7133 break;
7134 case AP_SUITEB:
7135 /* TODO */
7136 sigma_dut_print(dut, DUT_MSG_ERROR,
7137 "SuiteB not supported");
7138 break;
7139 case AP_WPA2_OWE:
7140 /* TODO */
7141 sigma_dut_print(dut, DUT_MSG_ERROR,
7142 "OWE not supported");
7143 break;
7144 case AP_WPA2_FT_EAP:
7145 case AP_WPA2_FT_PSK:
7146 case AP_WPA2_EAP_SHA256:
7147 case AP_WPA2_PSK_SHA256:
7148 case AP_WPA2_ENT_FT_EAP:
7149 case AP_OSEN:
7150 /* TODO */
7151 send_resp(dut, conn, SIGMA_ERROR,
7152 "errorCode,Unsupported KeyMgnt value");
7153 return 0;
7154 }
7155
7156 /* wifi0 settings in case of dual */
7157 run_system(dut, "cfg -a AP_RADIO_ID=0");
7158 run_system(dut, "cfg -a AP_PRIMARY_CH=6");
7159 run_system(dut, "cfg -a AP_STARTMODE=dual");
7160 run_system(dut, "cfg -a AP_CHMODE=11NGHT40PLUS");
7161 run_system(dut, "cfg -a TX_CHAINMASK=7");
7162 run_system(dut, "cfg -a RX_CHAINMASK=7");
7163 }
7164
7165 switch (dut->ap_pmf) {
7166 case AP_PMF_DISABLED:
7167 snprintf(buf, sizeof(buf), "cfg -a AP_PMF=0");
7168 run_system(dut, buf);
7169 break;
7170 case AP_PMF_OPTIONAL:
7171 snprintf(buf, sizeof(buf), "cfg -a AP_PMF=1");
7172 run_system(dut, buf);
7173 break;
7174 case AP_PMF_REQUIRED:
7175 snprintf(buf, sizeof(buf), "cfg -a AP_PMF=2");
7176 run_system(dut, buf);
7177 break;
7178 }
7179 if (dut->ap_add_sha256) {
7180 snprintf(buf, sizeof(buf), "cfg -a AP_WPA_SHA256=1");
7181 run_system(dut, buf);
7182 } else {
7183 snprintf(buf, sizeof(buf), "cfg -r AP_WPA_SHA256");
7184 run_system(dut, buf);
7185 }
7186
7187 if (dut->ap_hs2)
7188 run_system(dut, "cfg -a AP_HOTSPOT=1");
7189 else
7190 run_system(dut, "cfg -r AP_HOTSPOT");
7191
7192 if (dut->ap_interworking) {
7193 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_ANT=%d",
7194 dut->ap_access_net_type);
7195 run_system(dut, buf);
7196 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_INTERNET=%d",
7197 dut->ap_internet);
7198 run_system(dut, buf);
7199 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUEGROUP=%d",
7200 dut->ap_venue_group);
7201 run_system(dut, buf);
7202 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUETYPE=%d",
7203 dut->ap_venue_type);
7204 run_system(dut, buf);
7205 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=%s",
7206 dut->ap_hessid);
7207 run_system(dut, buf);
7208
7209 if (dut->ap_roaming_cons[0]) {
7210 char *second, *rc;
7211 rc = strdup(dut->ap_roaming_cons);
7212 if (rc == NULL)
7213 return 0;
7214
7215 second = strchr(rc, ';');
7216 if (second)
7217 *second++ = '\0';
7218
7219 snprintf(buf, sizeof(buf),
7220 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=%s", rc);
7221 run_system(dut, buf);
7222
7223 if (second) {
7224 snprintf(buf, sizeof(buf),
7225 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2"
7226 "=%s", second);
7227 run_system(dut, buf);
7228 }
7229 free(rc);
7230 } else {
7231 run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM");
7232 run_system(dut,
7233 "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2");
7234 }
7235 } else {
7236 run_system(dut, "cfg -r AP_HOTSPOT_ANT");
7237 run_system(dut, "cfg -r AP_HOTSPOT_INTERNET");
7238 run_system(dut, "cfg -r AP_HOTSPOT_VENUEGROUP");
7239 run_system(dut, "cfg -r AP_HOTSPOT_VENUETYPE");
7240 run_system(dut, "cfg -r AP_HOTSPOT_HESSID");
7241 run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM");
7242 run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2");
7243 }
7244
7245 if (dut->ap_proxy_arp)
7246 run_system(dut, "cfg -a IEEE80211V_PROXYARP=1");
7247 else
7248 run_system(dut, "cfg -a IEEE80211V_PROXYARP=0");
7249 if (dut->ap_dgaf_disable)
7250 run_system(dut, "cfg -a AP_HOTSPOT_DISABLE_DGAF=1");
7251 else
7252 run_system(dut, "cfg -r AP_HOTSPOT_DISABLE_DGAF");
7253
7254 if (strlen(dut->ap_tag_ssid[0])) {
7255 snprintf(buf, sizeof(buf),
7256 "cfg -a AP_SSID_2=%s", dut->ap_tag_ssid[0]);
7257 run_system(dut, buf);
7258
7259 if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) {
7260 run_system(dut, "cfg -a AP_SECMODE_2=WPA");
7261 run_system(dut, "cfg -a AP_SECFILE_2=OSEN");
7262
7263 res = snprintf(buf, sizeof(buf),
7264 "cfg -a AP_AUTH_SERVER_2=%s",
7265 dut->ap2_radius_ipaddr);
7266 if (res < 0 || res >= sizeof(buf))
7267 return ERROR_SEND_STATUS;
7268 run_system(dut, buf);
7269
7270 res = snprintf(buf, sizeof(buf),
7271 "cfg -a AP_AUTH_PORT_2=%d",
7272 dut->ap2_radius_port);
7273 if (res < 0 || res >= sizeof(buf))
7274 return ERROR_SEND_STATUS;
7275 run_system(dut, buf);
7276
7277 res = snprintf(buf, sizeof(buf),
7278 "cfg -a AP_AUTH_SECRET_2=%s",
7279 dut->ap2_radius_password);
7280 if (res < 0 || res >= sizeof(buf))
7281 return ERROR_SEND_STATUS;
7282 run_system(dut, buf);
7283 } else {
7284 run_system(dut, "cfg -a AP_SECMODE_2=None");
7285 run_system(dut, "cfg -r AP_AUTH_SERVER_2");
7286 run_system(dut, "cfg -r AP_AUTH_PORT_2");
7287 run_system(dut, "cfg -r AP_AUTH_SECRET_2");
7288 }
7289
7290 run_system(dut, "cfg -a AP_STARTMODE=multi");
7291 }
7292
7293 run_system(dut, "cfg -c");
7294
7295 sigma_dut_print(dut, DUT_MSG_INFO, "Starting AP");
7296 if (system("apup") != 0) {
7297 /* to be debugged why apup returns error
7298 send_resp(dut, conn, SIGMA_ERROR,
7299 "errorCode,apup failed");
7300 return 0;
7301 */
7302 }
7303 sigma_dut_print(dut, DUT_MSG_INFO, "AP started");
7304
7305 if (dut->ap_key_mgmt != AP_OPEN) {
7306 int res;
7307 /* allow some time for hostapd to start before returning
7308 * success */
7309 usleep(500000);
7310 if (run_hostapd_cli(dut, "ping") != 0) {
7311 send_resp(dut, conn, SIGMA_ERROR,
7312 "errorCode,Failed to talk to hostapd");
7313 return 0;
7314 }
7315
7316 if (dut->ap_hs2 && !dut->ap_anqpserver) {
7317 /* the cfg app doesn't like ";" in the variables */
7318 res = ath_ap_append_hostapd_conf(dut);
7319 if (res < 0)
7320 return res;
7321
7322 /* wait for hostapd to be ready */
7323 usleep(500000);
7324 if (run_hostapd_cli(dut, "ping") != 0) {
7325 send_resp(dut, conn, SIGMA_ERROR,
7326 "errorCode,Failed to talk to "
7327 "hostapd");
7328 return 0;
7329 }
7330 }
7331 }
7332
7333 ath_ap_set_params(dut);
7334
7335 if (dut->ap_anqpserver)
7336 return cmd_ath_ap_anqpserver_start(dut);
7337
7338 if (dut->ap2_proxy_arp)
7339 run_iwpriv(dut, ifname, "proxy_arp 1");
7340
7341 if (dut->ap_allow_vht_wep || dut->ap_allow_vht_tkip)
7342 run_iwpriv(dut, ifname, "htweptkip 1");
7343
7344 return 1;
7345 }
7346
7347
set_ebtables_proxy_arp(struct sigma_dut * dut,const char * chain,const char * ifname)7348 static int set_ebtables_proxy_arp(struct sigma_dut *dut, const char *chain,
7349 const char *ifname)
7350 {
7351 char buf[200];
7352
7353 if (!chain || !ifname)
7354 return -2;
7355
7356 snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain);
7357 if (system(buf) != 0) {
7358 sigma_dut_print(dut, DUT_MSG_ERROR,
7359 "Failed to set ebtables rules, RULE-1, %s",
7360 chain);
7361 return -2;
7362 }
7363
7364 snprintf(buf, sizeof(buf),
7365 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP",
7366 chain, ifname);
7367 if (system(buf) != 0) {
7368 sigma_dut_print(dut, DUT_MSG_ERROR,
7369 "Failed to set ebtables rules, RULE-2, %s",
7370 chain);
7371 return -2;
7372 }
7373
7374 snprintf(buf, sizeof(buf),
7375 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-solicitation -o %s -j DROP",
7376 chain, ifname);
7377 if (system(buf) != 0) {
7378 sigma_dut_print(dut, DUT_MSG_ERROR,
7379 "Failed to set ebtables rules, RULE-3, %s",
7380 chain);
7381 return -2;
7382 }
7383
7384 snprintf(buf, sizeof(buf),
7385 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-advertisement -o %s -j DROP",
7386 chain, ifname);
7387 if (system(buf) != 0) {
7388 sigma_dut_print(dut, DUT_MSG_ERROR,
7389 "Failed to set ebtables rules, RULE-4, %s",
7390 chain);
7391 return -2;
7392 }
7393
7394 return 0;
7395 }
7396
7397
set_ebtables_disable_dgaf(struct sigma_dut * dut,const char * chain,const char * ifname)7398 static int set_ebtables_disable_dgaf(struct sigma_dut *dut,
7399 const char *chain,
7400 const char *ifname)
7401 {
7402 char buf[200];
7403
7404 if (!chain || !ifname)
7405 return -2;
7406
7407 snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain);
7408 if (system(buf) != 0) {
7409 sigma_dut_print(dut, DUT_MSG_ERROR,
7410 "Failed to set ebtables rules, RULE-5, %s",
7411 chain);
7412 return -2;
7413 }
7414
7415 snprintf(buf, sizeof(buf),
7416 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP",
7417 chain, ifname);
7418 if (system(buf) != 0) {
7419 sigma_dut_print(dut, DUT_MSG_ERROR,
7420 "Failed to set ebtables rules, RULE-6, %s",
7421 chain);
7422 return -2;
7423 }
7424
7425 snprintf(buf, sizeof(buf),
7426 "ebtables -A %s -p IPv4 -d Multicast -o %s -j DROP",
7427 chain, ifname);
7428 if (system(buf) != 0) {
7429 sigma_dut_print(dut, DUT_MSG_ERROR,
7430 "Failed to set ebtables rules, RULE-7, %s",
7431 chain);
7432 return -2;
7433 }
7434
7435 snprintf(buf, sizeof(buf),
7436 "ebtables -A %s -p IPv6 -d Multicast -o %s -j DROP",
7437 chain, ifname);
7438 if (system(buf) != 0) {
7439 sigma_dut_print(dut, DUT_MSG_ERROR,
7440 "Failed to set ebtables rules, RULE-8, %s",
7441 chain);
7442 return -2;
7443 }
7444
7445 return 0;
7446 }
7447
7448
set_ebtables_forward_drop(struct sigma_dut * dut,const char * ifname,const char * ifname2)7449 static void set_ebtables_forward_drop(struct sigma_dut *dut,
7450 const char *ifname, const char *ifname2)
7451 {
7452 char buf[128];
7453
7454 snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP",
7455 ifname, ifname2);
7456 if (system(buf) != 0)
7457 sigma_dut_print(dut, DUT_MSG_ERROR,
7458 "Failed to set ebtables rule");
7459
7460 snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP",
7461 ifname2, ifname);
7462 if (system(buf) != 0)
7463 sigma_dut_print(dut, DUT_MSG_ERROR,
7464 "Failed to set ebtables rule");
7465 }
7466
7467
check_channel(int channel)7468 static int check_channel(int channel)
7469 {
7470 int channel_list[] = { 36, 40, 44, 48, 52, 60, 64, 100, 104, 108, 112,
7471 116, 120, 124, 128, 132, 140, 144, 149, 153, 157,
7472 161, 165 };
7473 int num_chan = sizeof(channel_list) / sizeof(int);
7474 int i;
7475
7476 for (i = 0; i < num_chan; i++) {
7477 if (channel == channel_list[i])
7478 return i;
7479 }
7480
7481 return -1;
7482 }
7483
7484
get_oper_centr_freq_seq_idx(int chwidth,int channel)7485 static int get_oper_centr_freq_seq_idx(int chwidth, int channel)
7486 {
7487 int ch_base;
7488 int period;
7489
7490 if (check_channel(channel) < 0)
7491 return -1;
7492
7493 if (channel >= 36 && channel <= 64)
7494 ch_base = 36;
7495 else if (channel >= 100 && channel <= 144)
7496 ch_base = 100;
7497 else
7498 ch_base = 149;
7499
7500 period = channel % ch_base * 5 / chwidth;
7501 return ch_base + period * chwidth / 5 + (chwidth - 20) / 10;
7502 }
7503
7504
is_ht40plus_chan(int chan)7505 static int is_ht40plus_chan(int chan)
7506 {
7507 return chan == 36 || chan == 44 || chan == 52 || chan == 60 ||
7508 chan == 100 || chan == 108 || chan == 116 || chan == 124 ||
7509 chan == 132 || chan == 149 || chan == 157;
7510 }
7511
7512
is_ht40minus_chan(int chan)7513 static int is_ht40minus_chan(int chan)
7514 {
7515 return chan == 40 || chan == 48 || chan == 56 || chan == 64 ||
7516 chan == 104 || chan == 112 || chan == 120 || chan == 128 ||
7517 chan == 136 || chan == 144 || chan == 153 || chan == 161;
7518 }
7519
7520
get_5g_channel_freq(int chan)7521 static int get_5g_channel_freq(int chan)
7522 {
7523 return 5000 + chan * 5;
7524 }
7525
7526
hostapd_cipher_name(enum ap_cipher cipher)7527 static const char * hostapd_cipher_name(enum ap_cipher cipher)
7528 {
7529 switch (cipher) {
7530 case AP_CCMP:
7531 return "CCMP";
7532 case AP_TKIP:
7533 return "TKIP";
7534 case AP_CCMP_TKIP:
7535 return "CCMP TKIP";
7536 case AP_GCMP_256:
7537 return "GCMP-256";
7538 case AP_GCMP_128:
7539 return "GCMP";
7540 case AP_CCMP_256:
7541 return "CCMP-256";
7542 case AP_CCMP_128_GCMP_256:
7543 return "CCMP GCMP-256";
7544 default:
7545 return "UNKNOWN";
7546 }
7547 }
7548
7549
7550 static const char *
hostapd_group_mgmt_cipher_name(enum ap_group_mgmt_cipher cipher)7551 hostapd_group_mgmt_cipher_name(enum ap_group_mgmt_cipher cipher)
7552 {
7553 switch (cipher) {
7554 case AP_BIP_GMAC_256:
7555 return "BIP-GMAC-256";
7556 case AP_BIP_CMAC_256:
7557 return "BIP-CMAC-256";
7558 case AP_BIP_GMAC_128:
7559 return "BIP-GMAC-128";
7560 case AP_BIP_CMAC_128:
7561 return "AES-128-CMAC";
7562 default:
7563 return "UNKNOWN";
7564 }
7565 }
7566
7567
ap_set_60g_ese(struct sigma_dut * dut,int count,struct sigma_ese_alloc * allocs)7568 static int ap_set_60g_ese(struct sigma_dut *dut, int count,
7569 struct sigma_ese_alloc *allocs)
7570 {
7571 switch (get_driver_type(dut)) {
7572 #ifdef __linux__
7573 case DRIVER_WIL6210:
7574 return wil6210_set_ese(dut, count, allocs);
7575 #endif /* __linux__ */
7576 default:
7577 sigma_dut_print(dut, DUT_MSG_ERROR,
7578 "Unsupported ap_set_60g_ese with the current driver");
7579 return -1;
7580 }
7581 }
7582
7583
ap_set_force_mcs(struct sigma_dut * dut,int force,int mcs)7584 static int ap_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7585 {
7586 switch (get_driver_type(dut)) {
7587 #ifdef __linux__
7588 case DRIVER_WIL6210:
7589 return wil6210_set_force_mcs(dut, force, mcs);
7590 #endif /* __linux__ */
7591 default:
7592 sigma_dut_print(dut, DUT_MSG_ERROR,
7593 "Unsupported ap_set_force_mcs with the current driver");
7594 return -1;
7595 }
7596 }
7597
7598
write_hostapd_conf_password(struct sigma_dut * dut,FILE * f,int sae)7599 static int write_hostapd_conf_password(struct sigma_dut *dut, FILE *f, int sae)
7600 {
7601 if (sae && dut->ap_sae_pk) {
7602 if (!dut->ap_sae_pk_modifier) {
7603 sigma_dut_print(dut, DUT_MSG_ERROR,
7604 "SAE-PK modifier not configured");
7605 return -1;
7606 }
7607 if (!dut->ap_sae_pk_keypair) {
7608 sigma_dut_print(dut, DUT_MSG_ERROR,
7609 "SAE-PK keypair not configured");
7610 return -1;
7611 }
7612 if (dut->ap_sae_pk_keypair_sig)
7613 fprintf(f, "sae_password=%s|pk=%s:%s:%s\n",
7614 dut->ap_passphrase,
7615 dut->ap_sae_pk_modifier,
7616 dut->ap_sae_pk_keypair,
7617 dut->ap_sae_pk_keypair_sig);
7618 else
7619 fprintf(f, "sae_password=%s|pk=%s:%s\n",
7620 dut->ap_passphrase,
7621 dut->ap_sae_pk_modifier,
7622 dut->ap_sae_pk_keypair);
7623 } else if (sae) {
7624 fprintf(f, "sae_password=%s\n", dut->ap_passphrase);
7625 } else if (!dut->ap_passphrase[0] && dut->ap_psk[0]) {
7626 fprintf(f, "wpa_psk=%s", dut->ap_psk);
7627 } else if (dut->ap_passphrase[0]) {
7628 fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase);
7629 }
7630
7631 return 0;
7632 }
7633
7634
fwtest_set_he_params(struct sigma_dut * dut,const char * ifname)7635 static void fwtest_set_he_params(struct sigma_dut *dut, const char *ifname)
7636 {
7637 /* disable sending basic triggers */
7638 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 42 0", ifname);
7639 /* disable MU BAR */
7640 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 64 1", ifname);
7641 /* disable PSD Boost */
7642 fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 142 1", ifname);
7643 /* Enable mix bw */
7644 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 141 1", ifname);
7645 /* Disable preferred AC */
7646 fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 186 0", ifname);
7647 /* enable full_band_probing */
7648 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 194 0", ifname);
7649 /* enable the equal RU allocation */
7650 fwtest_cmd_wrapper(dut, "-m 0x4b -v 0 0 1", ifname);
7651
7652 if (dut->ap_he_ulofdma == VALUE_ENABLED) {
7653 /* Disable sounding for UL OFDMA */
7654 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 7 0", ifname);
7655 /* Set random RU allocation */
7656 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 9 1", ifname);
7657 /* To set TBTT PPDU duration (us) */
7658 fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 63 1908", ifname);
7659 /* disable enable_ul_ofdma_efficiency_check */
7660 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 131 0", ifname);
7661 }
7662
7663 if (dut->ap_he_ppdu == PPDU_MU &&
7664 dut->ap_he_dlofdma == VALUE_ENABLED) {
7665 /* Increase the min TX time limit for MU MIMO to
7666 * disable MU MIMO scheduling.
7667 */
7668 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 11 1000000", ifname);
7669 /* Increase the max TX time limit for DL OFDMA
7670 * to enable OFDMA scheduling.
7671 */
7672 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 17 1000000", ifname);
7673 /* Disable 'force SU schedule' to enable MU sch */
7674 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 8 0", ifname);
7675 /* Enable MU 11ax support in sch algo */
7676 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 29 0", ifname);
7677 /* Enable to sort RU allocation */
7678 fwtest_cmd_wrapper(dut, "-m 0x4b -v 0 2 1", ifname);
7679 }
7680
7681 if (dut->ap_txBF) {
7682 /* Ignore TBTT for NDP */
7683 fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 2 1", ifname);
7684 /* cv query enable */
7685 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 7 1", ifname);
7686 /* override TPC calculations & set TxBF flag to true */
7687 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 47 1", ifname);
7688 }
7689
7690 if (dut->he_sounding == VALUE_ENABLED)
7691 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 7 0", ifname);
7692 }
7693
7694
7695 #define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x0
7696 #define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x1
7697 #define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 0x2
7698 #define IEEE80211_VHT_CAP_MAX_MPDU_MASK 0x3
7699 #define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT 23
7700 #define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
7701 (7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT)
7702
find_ap_ampdu_exp_and_max_mpdu_len(struct sigma_dut * dut)7703 static void find_ap_ampdu_exp_and_max_mpdu_len(struct sigma_dut *dut)
7704 {
7705
7706 #ifdef NL80211_SUPPORT
7707 int ampdu_exp = 0;
7708 int max_mpdu_len = 0;
7709 u32 vht_caps = dut->hw_modes.vht_capab;
7710
7711 ampdu_exp = (vht_caps &
7712 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
7713 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
7714
7715 if (ampdu_exp >= 0 && ampdu_exp <= 7)
7716 dut->ap_ampdu_exp = ampdu_exp;
7717
7718 max_mpdu_len = vht_caps & IEEE80211_VHT_CAP_MAX_MPDU_MASK;
7719
7720 if (max_mpdu_len == IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454)
7721 dut->ap_max_mpdu_len = 11454;
7722 else if (max_mpdu_len == IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991)
7723 dut->ap_max_mpdu_len = 7991;
7724 else if (max_mpdu_len == IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895)
7725 dut->ap_max_mpdu_len = 3895;
7726 #else /* NL80211_SUPPORT */
7727 sigma_dut_print(dut, DUT_MSG_DEBUG,
7728 "nl80211 is not supported to get A-MPDU parameters");
7729 #endif /* NL80211_SUPPORT */
7730 }
7731
7732
cmd_ap_config_commit(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)7733 enum sigma_cmd_result cmd_ap_config_commit(struct sigma_dut *dut,
7734 struct sigma_conn *conn,
7735 struct sigma_cmd *cmd)
7736 {
7737 /* const char *name = get_param(cmd, "NAME"); */
7738 FILE *f;
7739 const char *ifname;
7740 char buf[500];
7741 char path[100];
7742 char ap_conf_path[100];
7743 enum driver_type drv;
7744 const char *key_mgmt;
7745 #ifdef ANDROID
7746 struct group *gr;
7747 #endif /* ANDROID */
7748
7749 drv = get_driver_type(dut);
7750
7751 if (dut->mode == SIGMA_MODE_STATION) {
7752 stop_sta_mode(dut);
7753 sleep(1);
7754 }
7755
7756 if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) {
7757 snprintf(buf, sizeof(buf), "ifconfig %s down",
7758 dut->sniffer_ifname);
7759 if (system(buf) != 0) {
7760 sigma_dut_print(dut, DUT_MSG_INFO,
7761 "Failed to run '%s'", buf);
7762 }
7763 snprintf(buf, sizeof(buf), "iw dev %s set type station",
7764 dut->sniffer_ifname);
7765 if (system(buf) != 0) {
7766 sigma_dut_print(dut, DUT_MSG_INFO,
7767 "Failed to run '%s'", buf);
7768 }
7769 }
7770
7771 dut->mode = SIGMA_MODE_AP;
7772
7773 if (drv == DRIVER_ATHEROS)
7774 return cmd_ath_ap_config_commit(dut, conn, cmd);
7775 if (drv == DRIVER_WCN)
7776 return cmd_wcn_ap_config_commit(dut, conn, cmd);
7777 if (drv == DRIVER_OPENWRT)
7778 return cmd_owrt_ap_config_commit(dut, conn, cmd);
7779
7780 concat_sigma_tmpdir(dut, "/sigma_dut-ap.conf", ap_conf_path,
7781 sizeof(ap_conf_path));
7782 f = fopen(ap_conf_path, "w");
7783 if (f == NULL) {
7784 sigma_dut_print(dut, DUT_MSG_ERROR,
7785 "%s: Failed to open sigma_dut-ap.conf",
7786 __func__);
7787 return -2;
7788 }
7789
7790 ifname = get_hostapd_ifname(dut);
7791
7792 switch (dut->ap_mode) {
7793 case AP_11g:
7794 case AP_11b:
7795 case AP_11ng:
7796 fprintf(f, "hw_mode=g\n");
7797 break;
7798 case AP_11a:
7799 case AP_11na:
7800 case AP_11ac:
7801 fprintf(f, "hw_mode=a\n");
7802 break;
7803 case AP_11ad:
7804 fprintf(f, "hw_mode=ad\n");
7805 break;
7806 case AP_11ax:
7807 if (dut->use_5g)
7808 fprintf(f, "hw_mode=a\n");
7809 else
7810 fprintf(f, "hw_mode=g\n");
7811 break;
7812 default:
7813 fclose(f);
7814 return -1;
7815 }
7816
7817 if (drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN)
7818 fprintf(f, "driver=nl80211\n");
7819
7820 if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7821 drv == DRIVER_LINUX_WCN) &&
7822 (dut->ap_mode == AP_11ng || dut->ap_mode == AP_11na ||
7823 (dut->ap_mode == AP_11ax && !dut->use_5g))) {
7824 int ht40plus = 0, ht40minus = 0, tx_stbc = 0;
7825
7826 fprintf(f, "ieee80211n=1\n");
7827 if (dut->ap_mode == AP_11ax)
7828 fprintf(f, "ieee80211ax=1\n");
7829 if (dut->ap_mode == AP_11ng &&
7830 (dut->ap_chwidth == AP_40 ||
7831 (dut->ap_chwidth == AP_AUTO &&
7832 dut->default_11ng_ap_chwidth == AP_40))) {
7833 if (dut->ap_channel >= 1 && dut->ap_channel <= 7)
7834 ht40plus = 1;
7835 else if (dut->ap_channel >= 8 && dut->ap_channel <= 11)
7836 ht40minus = 1;
7837 fprintf(f, "obss_interval=300\n");
7838 }
7839
7840 /* configure ht_capab based on channel width */
7841 if (dut->ap_mode == AP_11na &&
7842 (dut->ap_chwidth == AP_40 ||
7843 (dut->ap_chwidth == AP_AUTO &&
7844 dut->default_11na_ap_chwidth == AP_40))) {
7845 if (is_ht40plus_chan(dut->ap_channel))
7846 ht40plus = 1;
7847 else if (is_ht40minus_chan(dut->ap_channel))
7848 ht40minus = 1;
7849 }
7850
7851 if (dut->ap_tx_stbc)
7852 tx_stbc = 1;
7853
7854 /* Overwrite the ht_capab with offset value if configured */
7855 if (dut->ap_chwidth == AP_40 &&
7856 dut->ap_chwidth_offset == SEC_CH_40ABOVE) {
7857 ht40plus = 1;
7858 ht40minus = 0;
7859 } else if (dut->ap_chwidth == AP_40 &&
7860 dut->ap_chwidth_offset == SEC_CH_40BELOW) {
7861 ht40minus = 1;
7862 ht40plus = 0;
7863 }
7864
7865 fprintf(f, "ht_capab=%s%s%s\n",
7866 ht40plus ? "[HT40+]" : "",
7867 ht40minus ? "[HT40-]" : "",
7868 tx_stbc ? "[TX-STBC]" : "");
7869 }
7870
7871 if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7872 drv == DRIVER_LINUX_WCN) &&
7873 (dut->ap_mode == AP_11ac ||
7874 (dut->ap_mode == AP_11ax && dut->use_5g))) {
7875 int ht40plus = 0, ht40minus = 0;
7876
7877 fprintf(f, "ieee80211ac=1\n"
7878 "ieee80211n=1\n");
7879 if (dut->ap_mode == AP_11ax)
7880 fprintf(f, "ieee80211ax=1\n");
7881
7882 /* configure ht_capab based on channel width */
7883 if (dut->ap_chwidth != AP_20) {
7884 if (is_ht40plus_chan(dut->ap_channel))
7885 ht40plus = 1;
7886 else if (is_ht40minus_chan(dut->ap_channel))
7887 ht40minus = 1;
7888
7889 fprintf(f, "ht_capab=%s%s\n",
7890 ht40plus ? "[HT40+]" : "",
7891 ht40minus ? "[HT40-]" : "");
7892 }
7893 }
7894
7895 if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO ||
7896 drv == DRIVER_LINUX_WCN) &&
7897 (dut->ap_mode == AP_11ac || dut->ap_mode == AP_11na)) {
7898 if (dut->ap_countrycode[0]) {
7899 fprintf(f, "country_code=%s\n", dut->ap_countrycode);
7900 fprintf(f, "ieee80211d=1\n");
7901 fprintf(f, "ieee80211h=1\n");
7902 }
7903 }
7904
7905 if (drv == DRIVER_LINUX_WCN && dut->ap_mode == AP_11ax) {
7906 if (dut->ap_txBF) {
7907 fprintf(f, "he_su_beamformer=1\n");
7908 fprintf(f, "he_su_beamformee=1\n");
7909 if (dut->ap_mu_txBF)
7910 fprintf(f, "he_mu_beamformer=1\n");
7911 } else {
7912 fprintf(f, "he_su_beamformer=0\n");
7913 fprintf(f, "he_su_beamformee=0\n");
7914 fprintf(f, "he_mu_beamformer=0\n");
7915 }
7916 }
7917
7918 fprintf(f, "interface=%s\n", ifname);
7919 if (dut->bridge)
7920 fprintf(f, "bridge=%s\n", dut->bridge);
7921 fprintf(f, "channel=%d\n", dut->ap_channel);
7922
7923 if (sigma_hapd_ctrl)
7924 fprintf(f, "ctrl_interface=%s\n", sigma_hapd_ctrl);
7925 else
7926 fprintf(f, "ctrl_interface=/var/run/hostapd\n");
7927
7928 if (dut->ap_ssid[0])
7929 fprintf(f, "ssid=%s\n", dut->ap_ssid);
7930 else
7931 fprintf(f, "ssid=QCA AP OOB\n");
7932 if (dut->ap_bcnint)
7933 fprintf(f, "beacon_int=%d\n", dut->ap_bcnint);
7934 if (dut->ap_start_disabled)
7935 fprintf(f, "start_disabled=1\n");
7936
7937 if (dut->ap_akm_values) {
7938 struct {
7939 int akm;
7940 const char *str;
7941 } akms[] = {
7942 { AKM_WPA_EAP, "WPA-EAP" },
7943 { AKM_WPA_PSK, "WPA-PSK" },
7944 { AKM_FT_EAP, "FT-EAP" },
7945 { AKM_FT_PSK, "FT-PSK" },
7946 { AKM_EAP_SHA256, "WPA-EAP-SHA256" },
7947 { AKM_PSK_SHA256, "WPA-PSK-SHA256" },
7948 { AKM_SAE, "SAE" },
7949 { AKM_FT_SAE, "FT-SAE" },
7950 { AKM_SUITE_B, "WPA-EAP-SUITE-B-192" },
7951 { AKM_FT_SUITE_B, "FT-EAP-SHA384" },
7952 { AKM_FILS_SHA256, "FILS-SHA256" },
7953 { AKM_FILS_SHA384, "FILS-SHA384" },
7954 { AKM_FT_FILS_SHA256, "FT-FILS-SHA256" },
7955 { AKM_FT_FILS_SHA384, "FT-FILS-SHA384" },
7956 };
7957 int first = 1;
7958 unsigned int i;
7959
7960 fprintf(f, "wpa_key_mgmt=");
7961 for (i = 0; i < ARRAY_SIZE(akms); i++) {
7962 if (dut->ap_akm_values & (1 << akms[i].akm)) {
7963 fprintf(f, "%s%s", first ? "" : " ",
7964 akms[i].str);
7965 first = 0;
7966 }
7967 }
7968 fprintf(f, "\n");
7969 /* TODO: mixed mode and WPAv1 only */
7970 fprintf(f, "wpa=2\n");
7971 fprintf(f, "wpa_pairwise=%s\n",
7972 hostapd_cipher_name(dut->ap_cipher));
7973 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
7974 fprintf(f, "group_cipher=%s\n",
7975 hostapd_cipher_name(dut->ap_group_cipher));
7976 if (write_hostapd_conf_password(
7977 dut, f,
7978 (dut->ap_akm_values &
7979 ((1 << AKM_SAE) | (1 << AKM_FT_SAE))) &&
7980 !(dut->ap_akm_values &
7981 ((1 << AKM_WPA_PSK) | (1 << AKM_FT_PSK))) &&
7982 dut->ap_passphrase[0]) < 0) {
7983 fclose(f);
7984 return ERROR_SEND_STATUS;
7985 }
7986 if (dut->ap_akm_values & ((1 << AKM_WPA_EAP) |
7987 (1 << AKM_FT_EAP) |
7988 (1 << AKM_EAP_SHA256) |
7989 (1 << AKM_SUITE_B) |
7990 (1 << AKM_FT_SUITE_B) |
7991 (1 << AKM_FILS_SHA256) |
7992 (1 << AKM_FILS_SHA384) |
7993 (1 << AKM_FT_FILS_SHA256) |
7994 (1 << AKM_FT_FILS_SHA384))) {
7995 fprintf(f, "ieee8021x=1\n");
7996 fprintf(f, "auth_server_addr=%s\n",
7997 dut->ap_radius_ipaddr);
7998 if (dut->ap_radius_port)
7999 fprintf(f, "auth_server_port=%d\n",
8000 dut->ap_radius_port);
8001 fprintf(f, "auth_server_shared_secret=%s\n",
8002 dut->ap_radius_password);
8003 }
8004 goto skip_key_mgmt;
8005 }
8006
8007 switch (dut->ap_key_mgmt) {
8008 case AP_OPEN:
8009 if (dut->ap_cipher == AP_WEP)
8010 fprintf(f, "wep_key0=%s\n", dut->ap_wepkey);
8011 break;
8012 case AP_WPA2_PSK:
8013 case AP_WPA2_PSK_MIXED:
8014 case AP_WPA_PSK:
8015 case AP_WPA2_SAE:
8016 case AP_WPA2_PSK_SAE:
8017 case AP_WPA2_PSK_SHA256:
8018 case AP_WPA2_FT_PSK:
8019 if (dut->ap_key_mgmt == AP_WPA2_PSK ||
8020 dut->ap_key_mgmt == AP_WPA2_SAE ||
8021 dut->ap_key_mgmt == AP_WPA2_PSK_SAE ||
8022 dut->ap_key_mgmt == AP_WPA2_PSK_SHA256 ||
8023 dut->ap_key_mgmt == AP_WPA2_FT_PSK)
8024 fprintf(f, "wpa=2\n");
8025 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED)
8026 fprintf(f, "wpa=3\n");
8027 else
8028 fprintf(f, "wpa=1\n");
8029 if (dut->ap_key_mgmt == AP_WPA2_SAE)
8030 key_mgmt = "SAE";
8031 else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
8032 key_mgmt = "WPA-PSK SAE";
8033 else
8034 key_mgmt = "WPA-PSK";
8035 switch (dut->ap_pmf) {
8036 case AP_PMF_DISABLED:
8037 fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt,
8038 dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
8039 break;
8040 case AP_PMF_OPTIONAL:
8041 fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt,
8042 dut->ap_add_sha256 ? " WPA-PSK-SHA256" : "");
8043 break;
8044 case AP_PMF_REQUIRED:
8045 if (dut->ap_key_mgmt == AP_WPA2_SAE)
8046 key_mgmt = "SAE";
8047 else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE)
8048 key_mgmt = "WPA-PSK-SHA256 SAE";
8049 else
8050 key_mgmt = "WPA-PSK-SHA256";
8051 fprintf(f, "wpa_key_mgmt=%s\n", key_mgmt);
8052 break;
8053 }
8054 if (dut->ap_key_mgmt == AP_WPA2_PSK_SHA256)
8055 fprintf(f, "wpa_key_mgmt=WPA-PSK-SHA256\n");
8056 else if (dut->ap_key_mgmt == AP_WPA2_FT_PSK)
8057 fprintf(f, "wpa_key_mgmt=FT-PSK\n");
8058 fprintf(f, "wpa_pairwise=%s\n",
8059 hostapd_cipher_name(dut->ap_cipher));
8060 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
8061 fprintf(f, "group_cipher=%s\n",
8062 hostapd_cipher_name(dut->ap_group_cipher));
8063 if (write_hostapd_conf_password(
8064 dut, f, dut->ap_key_mgmt == AP_WPA2_SAE) < 0) {
8065 fclose(f);
8066 return ERROR_SEND_STATUS;
8067 }
8068 break;
8069 case AP_WPA2_EAP:
8070 case AP_WPA2_EAP_MIXED:
8071 case AP_WPA_EAP:
8072 case AP_WPA2_EAP_OSEN:
8073 case AP_WPA2_EAP_SHA256:
8074 case AP_WPA2_FT_EAP:
8075 case AP_WPA2_ENT_FT_EAP:
8076 fprintf(f, "ieee8021x=1\n");
8077 if (dut->ap_key_mgmt == AP_WPA2_EAP ||
8078 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ||
8079 dut->ap_key_mgmt == AP_WPA2_EAP_SHA256 ||
8080 dut->ap_key_mgmt == AP_WPA2_FT_EAP ||
8081 dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP)
8082 fprintf(f, "wpa=2\n");
8083 else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED)
8084 fprintf(f, "wpa=3\n");
8085 else
8086 fprintf(f, "wpa=1\n");
8087 switch (dut->ap_pmf) {
8088 case AP_PMF_DISABLED:
8089 fprintf(f, "wpa_key_mgmt=WPA-EAP%s\n",
8090 dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "");
8091 break;
8092 case AP_PMF_OPTIONAL:
8093 fprintf(f, "wpa_key_mgmt=WPA-EAP%s%s\n",
8094 dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "",
8095 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" :
8096 "");
8097 break;
8098 case AP_PMF_REQUIRED:
8099 fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256%s\n",
8100 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" :
8101 "");
8102 break;
8103 }
8104 if (dut->ap_key_mgmt == AP_WPA2_EAP_SHA256)
8105 fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256\n");
8106 else if (dut->ap_key_mgmt == AP_WPA2_FT_EAP)
8107 fprintf(f, "wpa_key_mgmt=FT-EAP\n");
8108 else if (dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP)
8109 fprintf(f, "wpa_key_mgmt=FT-EAP WPA-EAP\n");
8110 fprintf(f, "wpa_pairwise=%s\n",
8111 hostapd_cipher_name(dut->ap_cipher));
8112 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
8113 fprintf(f, "group_cipher=%s\n",
8114 hostapd_cipher_name(dut->ap_group_cipher));
8115 fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
8116 if (dut->ap_radius_port)
8117 fprintf(f, "auth_server_port=%d\n",
8118 dut->ap_radius_port);
8119 fprintf(f, "auth_server_shared_secret=%s\n",
8120 dut->ap_radius_password);
8121 if (dut->program == PROGRAM_HS2_R3) {
8122 fprintf(f, "radius_das_port=3799\n");
8123 fprintf(f, "radius_das_client=0.0.0.0 %s\n",
8124 dut->ap_radius_password);
8125 fprintf(f, "radius_das_require_event_timestamp=1\n");
8126 }
8127 break;
8128 case AP_SUITEB:
8129 fprintf(f, "ieee8021x=1\n");
8130 fprintf(f, "wpa=2\n");
8131 fprintf(f, "wpa_key_mgmt=WPA-EAP-SUITE-B-192\n");
8132 fprintf(f, "wpa_pairwise=%s\n",
8133 hostapd_cipher_name(dut->ap_cipher));
8134 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
8135 fprintf(f, "group_cipher=%s\n",
8136 hostapd_cipher_name(dut->ap_group_cipher));
8137 if (dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET)
8138 fprintf(f, "group_mgmt_cipher=%s\n",
8139 hostapd_group_mgmt_cipher_name(
8140 dut->ap_group_mgmt_cipher));
8141 fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
8142 if (dut->ap_radius_port)
8143 fprintf(f, "auth_server_port=%d\n",
8144 dut->ap_radius_port);
8145 fprintf(f, "auth_server_shared_secret=%s\n",
8146 dut->ap_radius_password);
8147 break;
8148 case AP_WPA2_OWE:
8149 fprintf(f, "wpa=2\n");
8150 fprintf(f, "wpa_key_mgmt=OWE\n");
8151 fprintf(f, "rsn_pairwise=%s\n",
8152 hostapd_cipher_name(dut->ap_cipher));
8153 if (dut->ap_sae_groups)
8154 fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups);
8155 if (dut->owe_ptk_workaround)
8156 fprintf(f, "owe_ptk_workaround=1\n");
8157 break;
8158 case AP_OSEN:
8159 fprintf(f, "osen=1\n");
8160 fprintf(f, "disable_dgaf=1\n");
8161 fprintf(f, "wpa_pairwise=%s\n",
8162 hostapd_cipher_name(dut->ap_cipher));
8163 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET)
8164 fprintf(f, "group_cipher=%s\n",
8165 hostapd_cipher_name(dut->ap_group_cipher));
8166 fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr);
8167 if (dut->ap_radius_port)
8168 fprintf(f, "auth_server_port=%d\n",
8169 dut->ap_radius_port);
8170 fprintf(f, "auth_server_shared_secret=%s\n",
8171 dut->ap_radius_password);
8172 break;
8173 }
8174 skip_key_mgmt:
8175
8176 if (dut->ap_sae_passwords) {
8177 char *tmp, *pos, *end, *id;
8178
8179 tmp = strdup(dut->ap_sae_passwords);
8180 if (!tmp) {
8181 fclose(f);
8182 return ERROR_SEND_STATUS;
8183 }
8184
8185 pos = tmp;
8186 while (*pos) {
8187 end = strchr(pos, ';');
8188 if (end)
8189 *end = '\0';
8190 id = strchr(pos, ':');
8191 if (id)
8192 *id++ = '\0';
8193
8194 fprintf(f, "sae_password=%s%s%s\n",
8195 pos, id ? "|id=" : "", id ? id : "");
8196 if (!end)
8197 break;
8198 pos = end + 1;
8199 }
8200
8201 free(tmp);
8202 }
8203
8204 if (dut->ap_rsn_preauth)
8205 fprintf(f, "rsn_preauth=1\n");
8206
8207 if (dut->ap_pmksa && dut->ap_pmksa_caching)
8208 fprintf(f, "disable_pmksa_caching=1\n");
8209
8210 if (dut->ap_beacon_prot)
8211 fprintf(f, "beacon_prot=1\n");
8212
8213 if (dut->ap_transition_disable)
8214 fprintf(f, "transition_disable=0x%02x\n",
8215 dut->ap_transition_disable);
8216
8217 if (dut->ap_ocvc == 1 || dut->ap_ocvc == 0)
8218 fprintf(f, "ocv=%d\n", dut->ap_ocvc);
8219
8220 switch (dut->ap_pmf) {
8221 case AP_PMF_DISABLED:
8222 break;
8223 case AP_PMF_OPTIONAL:
8224 fprintf(f, "ieee80211w=1\n");
8225 if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE ||
8226 (dut->ap_akm_values & (AKM_SAE | AKM_WPA_PSK)) ==
8227 (AKM_SAE | AKM_WPA_PSK))
8228 fprintf(f, "sae_require_mfp=1\n");
8229 break;
8230 case AP_PMF_REQUIRED:
8231 fprintf(f, "ieee80211w=2\n");
8232 break;
8233 }
8234
8235 if (dut->ap_pmf != AP_PMF_DISABLED &&
8236 dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET)
8237 fprintf(f, "group_mgmt_cipher=%s\n",
8238 hostapd_group_mgmt_cipher_name(
8239 dut->ap_group_mgmt_cipher));
8240
8241 if (ap_ft_enabled(dut)) {
8242 unsigned char own_addr[ETH_ALEN];
8243
8244 fprintf(f, "mobility_domain=%s\n", dut->ap_mobility_domain);
8245 fprintf(f, "ft_over_ds=%d\n", dut->ap_ft_ds == VALUE_ENABLED);
8246 if (get_hwaddr(ifname, own_addr) < 0) {
8247 memset(own_addr, 0, ETH_ALEN);
8248 own_addr[0] = 0x02;
8249 }
8250 fprintf(f,
8251 "nas_identifier=%02x%02x%02x%02x%02x%02x.nas.example.com\n",
8252 own_addr[0], own_addr[1], own_addr[2],
8253 own_addr[3], own_addr[4], own_addr[5]);
8254 fprintf(f, "r1_key_holder=%02x%02x%02x%02x%02x%02x\n",
8255 own_addr[0], own_addr[1], own_addr[2],
8256 own_addr[3], own_addr[4], own_addr[5]);
8257 fprintf(f, "ft_psk_generate_local=1\n");
8258 fprintf(f, "pmk_r1_push=0\n");
8259 fprintf(f,
8260 "r0kh=ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n");
8261 fprintf(f,
8262 "r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n");
8263 }
8264
8265 if (dut->rsne_override)
8266 fprintf(f, "own_ie_override=%s\n", dut->rsne_override);
8267 if (dut->rsnxe_override_eapol)
8268 fprintf(f, "rsnxe_override_eapol=%s\n",
8269 dut->rsnxe_override_eapol);
8270
8271 if (dut->sae_commit_override)
8272 fprintf(f, "sae_commit_override=%s\n",
8273 dut->sae_commit_override);
8274
8275 if (dut->ap_sae_groups)
8276 fprintf(f, "sae_groups=%s\n", dut->ap_sae_groups);
8277
8278 if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) {
8279 const char *sae_pwe = NULL;
8280
8281 if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut))
8282 sae_pwe = "3";
8283 else if (dut->sae_pwe == SAE_PWE_LOOP)
8284 sae_pwe = "0";
8285 else if (dut->sae_pwe == SAE_PWE_H2E)
8286 sae_pwe = "1";
8287 else if (dut->sae_h2e_default)
8288 sae_pwe = "2";
8289 if (sae_pwe)
8290 fprintf(f, "sae_pwe=%s\n", sae_pwe);
8291 }
8292
8293 if (dut->sae_anti_clogging_threshold >= 0)
8294 fprintf(f, "sae_anti_clogging_threshold=%d\n",
8295 dut->sae_anti_clogging_threshold);
8296 if (dut->sae_reflection)
8297 fprintf(f, "sae_reflection_attack=1\n");
8298 if (dut->ap_sae_commit_status >= 0)
8299 fprintf(f, "sae_commit_status=%d\n", dut->ap_sae_commit_status);
8300 if (dut->ap_sae_pk_omit)
8301 fprintf(f, "sae_pk_omit=1\n");
8302 if (dut->sae_confirm_immediate)
8303 fprintf(f, "sae_confirm_immediate=2\n");
8304
8305 if (dut->ap_p2p_mgmt)
8306 fprintf(f, "manage_p2p=1\n");
8307
8308 if (dut->ap_tdls_prohibit || dut->ap_l2tif)
8309 fprintf(f, "tdls_prohibit=1\n");
8310 if (dut->ap_tdls_prohibit_chswitch || dut->ap_l2tif)
8311 fprintf(f, "tdls_prohibit_chan_switch=1\n");
8312 if (dut->ap_p2p_cross_connect >= 0) {
8313 fprintf(f, "manage_p2p=1\n"
8314 "allow_cross_connection=%d\n",
8315 dut->ap_p2p_cross_connect);
8316 }
8317
8318 if (dut->ap_l2tif || dut->ap_proxy_arp ||
8319 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN) {
8320 if (!dut->bridge) {
8321 sigma_dut_print(dut, DUT_MSG_ERROR,
8322 "Bridge must be configured. Run with -b <brname>.");
8323 fclose(f);
8324 return -2;
8325 }
8326 fprintf(f, "ap_isolate=1\n");
8327 }
8328
8329 if (dut->ap_proxy_arp)
8330 fprintf(f, "proxy_arp=1\n");
8331
8332 if (dut->ap_wme)
8333 fprintf(f, "wmm_enabled=1\n");
8334
8335 if (dut->ap_wmmps == AP_WMMPS_ON)
8336 fprintf(f, "uapsd_advertisement_enabled=1\n");
8337
8338 if (dut->ap_hs2) {
8339 if (dut->ap_bss_load) {
8340 char *bss_load;
8341
8342 switch (dut->ap_bss_load) {
8343 case -1:
8344 bss_load = "bss_load_update_period=10";
8345 break;
8346 case 1:
8347 /* STA count: 1, CU: 50, AAC: 65535 */
8348 bss_load = "bss_load_test=1:50:65535";
8349 break;
8350 case 2:
8351 /* STA count: 1, CU: 200, AAC: 65535 */
8352 bss_load = "bss_load_test=1:200:65535";
8353 break;
8354 case 3:
8355 /* STA count: 1, CU: 75, AAC: 65535 */
8356 bss_load = "bss_load_test=1:75:65535";
8357 break;
8358 default:
8359 bss_load = NULL;
8360 break;
8361 }
8362
8363 if (!bss_load) {
8364 fclose(f);
8365 return -2;
8366 }
8367 fprintf(f, "%s\n", bss_load);
8368 }
8369
8370 if (append_hostapd_conf_hs2(dut, f)) {
8371 fclose(f);
8372 return -2;
8373 }
8374 }
8375
8376 if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) {
8377 fclose(f);
8378 return -2;
8379 }
8380
8381 if (dut->ap_hs2 && strlen(dut->ap_tag_ssid[0])) {
8382 unsigned char bssid[6];
8383 char ifname2[50];
8384
8385 if (get_hwaddr(ifname, bssid)) {
8386 fclose(f);
8387 return -2;
8388 }
8389 if (bssid[0] & 0x02)
8390 bssid[5] ^= 0x01;
8391 else
8392 bssid[0] |= 0x02;
8393
8394 snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8395 fprintf(f, "bss=%s\n", ifname2);
8396 fprintf(f, "ssid=%s\n", dut->ap_tag_ssid[0]);
8397 if (dut->bridge)
8398 fprintf(f, "bridge=%s\n", dut->bridge);
8399
8400 if (drv == DRIVER_LINUX_WCN)
8401 fprintf(f, "use_driver_iface_addr=1\n");
8402 else
8403 fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8404 bssid[0], bssid[1], bssid[2], bssid[3],
8405 bssid[4], bssid[5]);
8406
8407 if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) {
8408 fprintf(f, "osen=1\n");
8409 /* Disable DGAF for OSEN BSS */
8410 fprintf(f, "disable_dgaf=1\n");
8411 fprintf(f, "ap_isolate=1\n");
8412 if (strlen(dut->ap2_radius_ipaddr))
8413 fprintf(f, "auth_server_addr=%s\n",
8414 dut->ap2_radius_ipaddr);
8415 if (dut->ap2_radius_port)
8416 fprintf(f, "auth_server_port=%d\n",
8417 dut->ap2_radius_port);
8418 if (strlen(dut->ap2_radius_password))
8419 fprintf(f, "auth_server_shared_secret=%s\n",
8420 dut->ap2_radius_password);
8421
8422 set_ebtables_forward_drop(dut, ifname, ifname2);
8423 } else if (dut->ap2_osu) {
8424 fprintf(f, "ap_isolate=1\n");
8425 set_ebtables_forward_drop(dut, ifname, ifname2);
8426 }
8427
8428 if (dut->ap2_proxy_arp) {
8429 if (!dut->bridge) {
8430 sigma_dut_print(dut, DUT_MSG_ERROR,
8431 "Bridge must be configured. Run with -b <brname>.");
8432 fclose(f);
8433 return -2;
8434 }
8435 fprintf(f, "ap_isolate=1\n");
8436 fprintf(f, "proxy_arp=1\n");
8437
8438 if (set_ebtables_proxy_arp(dut, "FORWARD", ifname2) ||
8439 set_ebtables_proxy_arp(dut, "OUTPUT", ifname2)) {
8440 fclose(f);
8441 return -2;
8442 }
8443
8444 }
8445 }
8446
8447 if (dut->program == PROGRAM_WPS) {
8448 /* 60G WPS tests requires wps_state of 2 (configured) */
8449 int wps_state = is_60g_sigma_dut(dut) ? 2 : 1;
8450
8451 fprintf(f, "eap_server=1\n"
8452 "wps_state=%d\n"
8453 "device_name=QCA AP\n"
8454 "manufacturer=QCA\n"
8455 "device_type=6-0050F204-1\n"
8456 "config_methods=label virtual_display %s"
8457 "virtual_push_button keypad%s\n"
8458 "ap_pin=12345670\n"
8459 "friendly_name=QCA Access Point\n"
8460 "upnp_iface=%s\n",
8461 wps_state,
8462 is_60g_sigma_dut(dut) ? "physical_display " : "",
8463 dut->ap_wpsnfc ? " nfc_interface ext_nfc_token" : "",
8464 dut->bridge ? dut->bridge : ifname);
8465 if (dut->wsc_fragment) {
8466 fprintf(f, "device_name=%s\n"
8467 "manufacturer=%s\n"
8468 "model_name=%s\n"
8469 "model_number=%s\n"
8470 "serial_number=%s\n",
8471 WPS_LONG_DEVICE_NAME,
8472 WPS_LONG_MANUFACTURER,
8473 WPS_LONG_MODEL_NAME,
8474 WPS_LONG_MODEL_NUMBER,
8475 WPS_LONG_SERIAL_NUMBER);
8476 } else {
8477 fprintf(f, "device_name=QCA AP\n"
8478 "manufacturer=QCA\n");
8479 }
8480 if (dut->eap_fragment)
8481 fprintf(f, "fragment_size=128\n");
8482 }
8483
8484 if (dut->ap_dpp_conf_addr && dut->ap_dpp_conf_pkhash)
8485 fprintf(f, "dpp_controller=ipaddr=%s pkhash=%s\n",
8486 dut->ap_dpp_conf_addr, dut->ap_dpp_conf_pkhash);
8487
8488 if (dut->ap_he_rtsthrshld == VALUE_ENABLED)
8489 fprintf(f, "he_rts_threshold=512\n");
8490 else if (dut->ap_he_rtsthrshld == VALUE_DISABLED)
8491 fprintf(f, "he_rts_threshold=1024\n");
8492
8493 if ((dut->program == PROGRAM_VHT) ||
8494 (dut->program == PROGRAM_HE && dut->use_5g)) {
8495 int vht_oper_centr_freq_idx;
8496
8497 if (check_channel(dut->ap_channel) < 0) {
8498 send_resp(dut, conn, SIGMA_INVALID,
8499 "errorCode,Invalid channel");
8500 fclose(f);
8501 return 0;
8502 }
8503
8504 switch (dut->ap_chwidth) {
8505 case AP_20:
8506 dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH;
8507 vht_oper_centr_freq_idx =
8508 get_oper_centr_freq_seq_idx(20,
8509 dut->ap_channel);
8510 break;
8511 case AP_40:
8512 dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH;
8513 vht_oper_centr_freq_idx =
8514 get_oper_centr_freq_seq_idx(40,
8515 dut->ap_channel);
8516 break;
8517 case AP_80:
8518 dut->ap_vht_chwidth = AP_80_VHT_OPER_CHWIDTH;
8519 vht_oper_centr_freq_idx =
8520 get_oper_centr_freq_seq_idx(80,
8521 dut->ap_channel);
8522 break;
8523 case AP_160:
8524 dut->ap_vht_chwidth = AP_160_VHT_OPER_CHWIDTH;
8525 vht_oper_centr_freq_idx =
8526 get_oper_centr_freq_seq_idx(160,
8527 dut->ap_channel);
8528 break;
8529 default:
8530 dut->ap_vht_chwidth = VHT_DEFAULT_OPER_CHWIDTH;
8531 vht_oper_centr_freq_idx =
8532 get_oper_centr_freq_seq_idx(80,
8533 dut->ap_channel);
8534 break;
8535 }
8536 fprintf(f, "vht_oper_centr_freq_seg0_idx=%d\n",
8537 vht_oper_centr_freq_idx);
8538 fprintf(f, "vht_oper_chwidth=%d\n", dut->ap_vht_chwidth);
8539 if (dut->ap_mode == AP_11ax) {
8540 fprintf(f, "he_oper_chwidth=%d\n", dut->ap_vht_chwidth);
8541 fprintf(f, "he_oper_centr_freq_seg0_idx=%d\n",
8542 vht_oper_centr_freq_idx);
8543 }
8544
8545 find_ap_ampdu_exp_and_max_mpdu_len(dut);
8546
8547 if (dut->ap_sgi80 || dut->ap_txBF ||
8548 dut->ap_ldpc != VALUE_NOT_SET ||
8549 dut->ap_tx_stbc || dut->ap_mu_txBF ||
8550 dut->ap_ampdu_exp || dut->ap_max_mpdu_len ||
8551 dut->ap_chwidth == AP_160 || dut->ap_chwidth == AP_80_80) {
8552 fprintf(f, "vht_capab=%s%s%s%s%s%s",
8553 dut->ap_sgi80 ? "[SHORT-GI-80]" : "",
8554 dut->ap_txBF ?
8555 "[SU-BEAMFORMER][SU-BEAMFORMEE][BF-ANTENNA-2][SOUNDING-DIMENSION-2]" : "",
8556 (dut->ap_ldpc == VALUE_ENABLED) ?
8557 "[RXLDPC]" : "",
8558 dut->ap_tx_stbc ? "[TX-STBC-2BY1]" : "",
8559 dut->ap_mu_txBF ? "[MU-BEAMFORMER]" : "",
8560 dut->ap_chwidth == AP_160 ? "[VHT160]" :
8561 (dut->ap_chwidth == AP_80_80 ?
8562 "[VHT160-80PLUS80]" : ""));
8563
8564 if (dut->ap_ampdu_exp)
8565 fprintf(f, "[MAX-A-MPDU-LEN-EXP%d]",
8566 dut->ap_ampdu_exp);
8567
8568 if (dut->ap_max_mpdu_len)
8569 fprintf(f, "[MAX-MPDU-%d]",
8570 dut->ap_max_mpdu_len);
8571
8572 fprintf(f, "\n");
8573 }
8574 }
8575
8576 if (dut->ap_key_mgmt == AP_WPA2_OWE && dut->ap_tag_ssid[0][0] &&
8577 dut->ap_tag_key_mgmt[0] == AP2_OPEN) {
8578 /* OWE transition mode */
8579 unsigned char bssid[6];
8580 char ifname2[50];
8581 unsigned long val;
8582 FILE *f2;
8583
8584 snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8585
8586 fprintf(f, "owe_transition_ifname=%s\n", ifname2);
8587 val = 0x12345678; /* default to something */
8588 f2 = fopen("/dev/urandom", "r");
8589 if (f2) {
8590 if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) {
8591 sigma_dut_print(dut, DUT_MSG_ERROR,
8592 "Could not read /dev/urandom");
8593 }
8594 fclose(f2);
8595 }
8596 fprintf(f, "ssid=owe-%lx\n", val);
8597 fprintf(f, "ignore_broadcast_ssid=1\n");
8598
8599 if (get_hwaddr(ifname, bssid)) {
8600 fclose(f);
8601 return -2;
8602 }
8603 if (bssid[0] & 0x02)
8604 bssid[5] ^= 0x01;
8605 else
8606 bssid[0] |= 0x02;
8607
8608 fprintf(f, "bss=%s\n", ifname2);
8609 fprintf(f, "ssid=%s\n", dut->ap_ssid);
8610 if (dut->bridge)
8611 fprintf(f, "bridge=%s\n", dut->bridge);
8612 if (drv == DRIVER_LINUX_WCN)
8613 fprintf(f, "use_driver_iface_addr=1\n");
8614 else
8615 fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8616 bssid[0], bssid[1], bssid[2], bssid[3],
8617 bssid[4], bssid[5]);
8618 fprintf(f, "owe_transition_ifname=%s\n", ifname);
8619 }
8620
8621 if (dut->ap_key_mgmt == AP_OPEN &&
8622 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) {
8623 /* OWE transition mode */
8624 unsigned char bssid[6];
8625 char ifname2[50];
8626 unsigned long val;
8627 FILE *f2;
8628
8629 snprintf(ifname2, sizeof(ifname2), "%s_1", ifname);
8630
8631 fprintf(f, "owe_transition_ifname=%s\n", ifname2);
8632 fprintf(f, "ssid=%s\n", dut->ap_ssid);
8633
8634 if (get_hwaddr(ifname, bssid)) {
8635 fclose(f);
8636 return -2;
8637 }
8638 if (bssid[0] & 0x02)
8639 bssid[5] ^= 0x01;
8640 else
8641 bssid[0] |= 0x02;
8642
8643 fprintf(f, "bss=%s\n", ifname2);
8644 val = 0x12345678; /* default to something */
8645 f2 = fopen("/dev/urandom", "r");
8646 if (f2) {
8647 if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) {
8648 sigma_dut_print(dut, DUT_MSG_ERROR,
8649 "Could not read /dev/urandom");
8650 }
8651 fclose(f2);
8652 }
8653 fprintf(f, "ssid=owe-%lx\n", val);
8654 if (dut->bridge)
8655 fprintf(f, "bridge=%s\n", dut->bridge);
8656 if (drv == DRIVER_LINUX_WCN)
8657 fprintf(f, "use_driver_iface_addr=1\n");
8658 else
8659 fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
8660 bssid[0], bssid[1], bssid[2], bssid[3],
8661 bssid[4], bssid[5]);
8662 fprintf(f, "owe_transition_ifname=%s\n", ifname);
8663 fprintf(f, "wpa=2\n");
8664 fprintf(f, "wpa_key_mgmt=OWE\n");
8665 fprintf(f, "rsn_pairwise=CCMP\n");
8666 fprintf(f, "ieee80211w=2\n");
8667 fprintf(f, "ignore_broadcast_ssid=1\n");
8668 if (dut->ap_sae_groups)
8669 fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups);
8670 if (dut->owe_ptk_workaround)
8671 fprintf(f, "owe_ptk_workaround=1\n");
8672 }
8673
8674 if (dut->program == PROGRAM_OCE) {
8675 fprintf(f, "oce=%d\n",
8676 dut->dev_role == DEVROLE_STA_CFON ? 2 : 1);
8677 }
8678 fclose(f);
8679 if (dut->use_hostapd_pid_file)
8680 kill_hostapd_process_pid(dut);
8681 #ifdef __QNXNTO__
8682 if (system("slay hostapd") == 0)
8683 #else /* __QNXNTO__ */
8684 if (!dut->use_hostapd_pid_file &&
8685 (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
8686 system("killall hostapd") == 0))
8687 #endif /* __QNXNTO__ */
8688 {
8689 int i;
8690 /* Wait some time to allow hostapd to complete cleanup before
8691 * starting a new process */
8692 for (i = 0; i < 10; i++) {
8693 usleep(500000);
8694 #ifdef __QNXNTO__
8695 if (system("pidin | grep hostapd") != 0)
8696 break;
8697 #else /* __QNXNTO__ */
8698 if (system("pidof hostapd") != 0)
8699 break;
8700 #endif /* __QNXNTO__ */
8701 }
8702 }
8703 dut->hostapd_running = 0;
8704
8705 #ifdef ANDROID
8706 /* Set proper conf file permissions so that hostapd process
8707 * can access it.
8708 */
8709 if (chmod(ap_conf_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0)
8710 sigma_dut_print(dut, DUT_MSG_ERROR,
8711 "Error changing permissions");
8712
8713 gr = getgrnam("wifi");
8714 if (!gr || chown(ap_conf_path, -1, gr->gr_gid) < 0)
8715 sigma_dut_print(dut, DUT_MSG_ERROR, "Error changing groupid");
8716 #endif /* ANDROID */
8717
8718 f = fopen(ap_conf_path, "r");
8719 if (f) {
8720 size_t len;
8721
8722 len = fread(buf, 1, sizeof(buf), f);
8723 fclose(f);
8724 if (len >= sizeof(buf))
8725 len = sizeof(buf) - 1;
8726 buf[len] = '\0';
8727 sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd debug log:\n%s",
8728 buf);
8729 }
8730
8731 if (drv == DRIVER_QNXNTO) {
8732 snprintf(buf, sizeof(buf),
8733 "hostapd -B %s%s%s %s%s %s/sigma_dut-ap.conf",
8734 dut->hostapd_debug_log ? "-dddKt " : "",
8735 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ?
8736 "-f " : "",
8737 dut->hostapd_debug_log ? dut->hostapd_debug_log : "",
8738 dut->hostapd_entropy_log ? " -e" : "",
8739 dut->hostapd_entropy_log ? dut->hostapd_entropy_log :
8740 "",
8741 dut->sigma_tmpdir);
8742 } else {
8743 /*
8744 * It looks like a monitor interface can cause some issues for
8745 * beaconing, so remove it (if injection was used) before
8746 * starting hostapd.
8747 */
8748 if (if_nametoindex("sigmadut") > 0 &&
8749 system("iw dev sigmadut del") != 0)
8750 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove "
8751 "monitor interface");
8752
8753 snprintf(path, sizeof(path), "%shostapd",
8754 file_exists("hostapd") ? "./" : "");
8755 snprintf(buf, sizeof(buf),
8756 "%s -B%s%s%s%s%s%s %s/sigma_dut-ap.conf",
8757 dut->hostapd_bin ? dut->hostapd_bin : path,
8758 dut->hostapd_debug_log ? " -dddKt" : "",
8759 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ?
8760 " -f " : "",
8761 dut->hostapd_debug_log ? dut->hostapd_debug_log : "",
8762 dut->hostapd_entropy_log ? " -e" : "",
8763 dut->hostapd_entropy_log ? dut->hostapd_entropy_log :
8764 "",
8765 dut->use_hostapd_pid_file ?
8766 " -P " SIGMA_DUT_HOSTAPD_PID_FILE : "",
8767 dut->sigma_tmpdir);
8768 }
8769
8770 sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd command: %s", buf);
8771 if (system(buf) != 0) {
8772 send_resp(dut, conn, SIGMA_ERROR,
8773 "errorCode,Failed to start hostapd");
8774 return 0;
8775 }
8776
8777 /* allow some time for hostapd to start before returning success */
8778 usleep(500000);
8779 if (run_hostapd_cli(dut, "ping") != 0) {
8780 send_resp(dut, conn, SIGMA_ERROR,
8781 "errorCode,Failed to talk to hostapd");
8782 return 0;
8783 }
8784
8785 if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) {
8786 int buf_size;
8787
8788 if (dut->ap_ba_bufsize == BA_BUFSIZE_256)
8789 buf_size = 256;
8790 else
8791 buf_size = 64;
8792
8793 if ((drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) &&
8794 sta_set_addba_buf_size(dut, ifname, buf_size)) {
8795 send_resp(dut, conn, SIGMA_ERROR,
8796 "ErrorCode,set_addba_buf_size failed");
8797 return STATUS_SENT_ERROR;
8798 }
8799
8800 sigma_dut_print(dut, DUT_MSG_INFO,
8801 "setting addba buf_size=%d", buf_size);
8802 }
8803
8804 if (drv == DRIVER_LINUX_WCN) {
8805 const char *ifname_ptr = ifname;
8806
8807 if ((dut->ap_key_mgmt == AP_OPEN &&
8808 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) ||
8809 (dut->ap_key_mgmt == AP_WPA2_OWE &&
8810 dut->ap_tag_ssid[0][0] &&
8811 dut->ap_tag_key_mgmt[0] == AP2_OPEN)) {
8812 /* OWE transition mode */
8813 if (dut->bridge)
8814 ifname_ptr = dut->bridge;
8815 }
8816
8817 sigma_dut_print(dut, DUT_MSG_INFO,
8818 "setting ip addr %s mask %s ifname %s",
8819 ap_inet_addr, ap_inet_mask, ifname_ptr);
8820 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up",
8821 ifname_ptr, ap_inet_addr, ap_inet_mask);
8822 if (system(buf) != 0) {
8823 sigma_dut_print(dut, DUT_MSG_ERROR,
8824 "Failed to initialize the interface");
8825 return -1;
8826 }
8827 }
8828
8829 /* Configure the driver with LDPC setting for AP mode as a new vdev is
8830 * created when hostapd is started.
8831 */
8832 if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN)
8833 wcn_config_ap_ldpc(dut, ifname);
8834
8835 if ((drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) &&
8836 dut->program == PROGRAM_OCE && dut->dev_role == DEVROLE_STA_CFON &&
8837 wcn_config_ap_fils_dscv(dut, ifname))
8838 return ERROR_SEND_STATUS;
8839
8840 if (dut->ap_l2tif) {
8841 snprintf(path, sizeof(path),
8842 "/sys/class/net/%s/brport/hairpin_mode",
8843 ifname);
8844 if (!file_exists(path)) {
8845 sigma_dut_print(dut, DUT_MSG_ERROR,
8846 "%s must be binded to the bridge for L2TIF",
8847 ifname);
8848 return -2;
8849 }
8850
8851 snprintf(buf, sizeof(buf), "echo 1 > %s", path);
8852 if (system(buf) != 0) {
8853 sigma_dut_print(dut, DUT_MSG_ERROR,
8854 "Failed to enable hairpin_mode for L2TIF");
8855 return -2;
8856 }
8857
8858 snprintf(buf, sizeof(buf), "ebtables -P FORWARD ACCEPT");
8859 if (system(buf) != 0) {
8860 sigma_dut_print(dut, DUT_MSG_ERROR,
8861 "Failed to set ebtables rules, RULE-9");
8862 return -2;
8863 }
8864
8865 snprintf(buf, sizeof(buf),
8866 "ebtables -A FORWARD -p IPv4 --ip-proto icmp -i %s -j DROP",
8867 ifname);
8868 if (system(buf) != 0) {
8869 sigma_dut_print(dut, DUT_MSG_ERROR,
8870 "Failed to set ebtables rules, RULE-11");
8871 return -2;
8872 }
8873 }
8874
8875 if (dut->ap_proxy_arp) {
8876 if (dut->ap_dgaf_disable) {
8877 if (set_ebtables_disable_dgaf(dut, "FORWARD", ifname) ||
8878 set_ebtables_disable_dgaf(dut, "OUTPUT", ifname))
8879 return -2;
8880 } else {
8881 if (set_ebtables_proxy_arp(dut, "FORWARD", ifname) ||
8882 set_ebtables_proxy_arp(dut, "OUTPUT", ifname))
8883 return -2;
8884 }
8885
8886 /* For 4.5-(c) */
8887 snprintf(buf, sizeof(buf),
8888 "ebtables -A FORWARD -p ARP --arp-opcode 2 -i %s -j DROP",
8889 ifname);
8890 if (system(buf) != 0) {
8891 sigma_dut_print(dut, DUT_MSG_ERROR,
8892 "Failed to set ebtables rules, RULE-10");
8893 return -2;
8894 }
8895 }
8896
8897 if (dut->ap_tdls_prohibit || dut->ap_l2tif) {
8898 /* Drop TDLS frames */
8899 snprintf(buf, sizeof(buf),
8900 "ebtables -A FORWARD -p 0x890d -i %s -j DROP", ifname);
8901 if (system(buf) != 0) {
8902 sigma_dut_print(dut, DUT_MSG_ERROR,
8903 "Failed to set ebtables rules, RULE-13");
8904 return -2;
8905 }
8906 }
8907
8908 if (dut->ap_fake_pkhash &&
8909 run_hostapd_cli(dut, "set wps_corrupt_pkhash 1") != 0) {
8910 send_resp(dut, conn, SIGMA_ERROR,
8911 "errorCode,Could not enable FakePubKey");
8912 return 0;
8913 }
8914
8915 if (dut->program == PROGRAM_60GHZ) {
8916 if (dut->ap_num_ese_allocs > 0) {
8917 /* wait extra time for AP to start */
8918 sleep(2);
8919 if (ap_set_60g_ese(dut, dut->ap_num_ese_allocs,
8920 dut->ap_ese_allocs)) {
8921 send_resp(dut, conn, SIGMA_ERROR,
8922 "errorCode,Could not set ExtSch");
8923 return 0;
8924 }
8925 }
8926 if (dut->ap_fixed_rate) {
8927 sigma_dut_print(dut, DUT_MSG_DEBUG,
8928 "forcing TX MCS index %d",
8929 dut->ap_mcs);
8930 if (ap_set_force_mcs(dut, 1, dut->ap_mcs)) {
8931 send_resp(dut, conn, SIGMA_ERROR,
8932 "errorCode,Could not force MCS");
8933 return -2;
8934 }
8935 }
8936 }
8937
8938 if (dut->wps_forced_version) {
8939 snprintf(buf, sizeof(buf), "SET wps_version_number %d",
8940 dut->wps_forced_version);
8941 if (hapd_command(ifname, buf) < 0) {
8942 send_resp(dut, conn, SIGMA_ERROR,
8943 "errorCode,Fail to set wps_version_number");
8944 return STATUS_SENT;
8945 }
8946 }
8947
8948 if (drv == DRIVER_MAC80211 && dut->program == PROGRAM_HE)
8949 fwtest_set_he_params(dut, ifname);
8950
8951 dut->hostapd_running = 1;
8952 return 1;
8953 }
8954
8955
parse_qos_params(struct sigma_dut * dut,struct sigma_conn * conn,struct qos_params * qos,const char * cwmin,const char * cwmax,const char * aifs,const char * txop,const char * acm)8956 static int parse_qos_params(struct sigma_dut *dut, struct sigma_conn *conn,
8957 struct qos_params *qos, const char *cwmin,
8958 const char *cwmax, const char *aifs,
8959 const char *txop, const char *acm)
8960 {
8961 int val;
8962
8963 if (cwmin) {
8964 qos->ac = 1;
8965 val = atoi(cwmin);
8966 if (val < 0 || val > 15) {
8967 send_resp(dut, conn, SIGMA_INVALID,
8968 "errorCode,Invalid cwMin");
8969 return 0;
8970 }
8971 qos->cwmin = val;
8972 }
8973
8974 if (cwmax) {
8975 qos->ac = 1;
8976 val = atoi(cwmax);
8977 if (val < 0 || val > 15) {
8978 send_resp(dut, conn, SIGMA_INVALID,
8979 "errorCode,Invalid cwMax");
8980 return 0;
8981 }
8982 qos->cwmax = val;
8983 }
8984
8985 if (aifs) {
8986 qos->ac = 1;
8987 val = atoi(aifs);
8988 if (val < 1 || val > 255) {
8989 send_resp(dut, conn, SIGMA_INVALID,
8990 "errorCode,Invalid AIFS");
8991 return 0;
8992 }
8993 qos->aifs = val;
8994 }
8995
8996 if (txop) {
8997 qos->ac = 1;
8998 val = atoi(txop);
8999 if (val < 0 || val > 0xffff) {
9000 send_resp(dut, conn, SIGMA_INVALID,
9001 "errorCode,Invalid txop");
9002 return 0;
9003 }
9004 qos->txop = val * 32;
9005 }
9006
9007 if (acm) {
9008 qos->ac = 1;
9009 qos->acm = strcasecmp(acm, "on") == 0;
9010 }
9011
9012 return 1;
9013 }
9014
9015
cmd_ap_set_apqos(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9016 static enum sigma_cmd_result cmd_ap_set_apqos(struct sigma_dut *dut,
9017 struct sigma_conn *conn,
9018 struct sigma_cmd *cmd)
9019 {
9020 /* TXOP: The values provided here for VHT5G only */
9021 if (!parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VO],
9022 get_param(cmd, "cwmin_VO"),
9023 get_param(cmd, "cwmax_VO"),
9024 get_param(cmd, "AIFS_VO"),
9025 get_param(cmd, "TXOP_VO"),
9026 get_param(cmd, "ACM_VO")) ||
9027 !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VI],
9028 get_param(cmd, "cwmin_VI"),
9029 get_param(cmd, "cwmax_VI"),
9030 get_param(cmd, "AIFS_VI"),
9031 get_param(cmd, "TXOP_VI"),
9032 get_param(cmd, "ACM_VI")) ||
9033 !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BE],
9034 get_param(cmd, "cwmin_BE"),
9035 get_param(cmd, "cwmax_BE"),
9036 get_param(cmd, "AIFS_BE"),
9037 get_param(cmd, "TXOP_BE"),
9038 get_param(cmd, "ACM_BE")) ||
9039 !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BK],
9040 get_param(cmd, "cwmin_BK"),
9041 get_param(cmd, "cwmax_BK"),
9042 get_param(cmd, "AIFS_BK"),
9043 get_param(cmd, "TXOP_BK"),
9044 get_param(cmd, "ACM_BK")))
9045 return 0;
9046
9047 return 1;
9048 }
9049
9050
cmd_ap_set_staqos(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9051 static enum sigma_cmd_result cmd_ap_set_staqos(struct sigma_dut *dut,
9052 struct sigma_conn *conn,
9053 struct sigma_cmd *cmd)
9054 {
9055 if (!parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VO],
9056 get_param(cmd, "cwmin_VO"),
9057 get_param(cmd, "cwmax_VO"),
9058 get_param(cmd, "AIFS_VO"),
9059 get_param(cmd, "TXOP_VO"),
9060 get_param(cmd, "ACM_VO")) ||
9061 !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VI],
9062 get_param(cmd, "cwmin_VI"),
9063 get_param(cmd, "cwmax_VI"),
9064 get_param(cmd, "AIFS_VI"),
9065 get_param(cmd, "TXOP_VI"),
9066 get_param(cmd, "ACM_VI")) ||
9067 !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BE],
9068 get_param(cmd, "cwmin_BE"),
9069 get_param(cmd, "cwmax_BE"),
9070 get_param(cmd, "AIFS_BE"),
9071 get_param(cmd, "TXOP_BE"),
9072 get_param(cmd, "ACM_BE")) ||
9073 !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BK],
9074 get_param(cmd, "cwmin_BK"),
9075 get_param(cmd, "cwmax_BK"),
9076 get_param(cmd, "AIFS_BK"),
9077 get_param(cmd, "TXOP_BK"),
9078 get_param(cmd, "ACM_BK")))
9079 return 0;
9080
9081 return 1;
9082 }
9083
9084
cmd_ath_ap_hs2_reset(struct sigma_dut * dut)9085 static void cmd_ath_ap_hs2_reset(struct sigma_dut *dut)
9086 {
9087 unsigned char bssid[6];
9088 char buf[100];
9089 run_system(dut, "cfg -a AP_SSID=\"Hotspot 2.0\"");
9090 run_system(dut, "cfg -a AP_PRIMARY_CH=1");
9091 run_system(dut, "cfg -a AP_SECMODE=WPA");
9092 run_system(dut, "cfg -a AP_SECFILE=EAP");
9093 run_system(dut, "cfg -a AP_WPA=2");
9094 run_system(dut, "cfg -a AP_CYPHER=CCMP");
9095 run_system(dut, "cfg -a AP_HOTSPOT=1");
9096 run_system(dut, "cfg -a AP_HOTSPOT_ANT=2");
9097 run_system(dut, "cfg -a AP_HOTSPOT_INTERNET=0");
9098 run_system(dut, "cfg -a AP_HOTSPOT_VENUEGROUP=2");
9099 run_system(dut, "cfg -a AP_HOTSPOT_VENUETYPE=8");
9100 run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=506f9a");
9101 run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2=001bc504bd");
9102 if (!get_hwaddr("ath0", bssid)) {
9103 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID="
9104 "%02x:%02x:%02x:%02x:%02x:%02x",
9105 bssid[0], bssid[1], bssid[2], bssid[3],
9106 bssid[4], bssid[5]);
9107 run_system(dut, buf);
9108 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
9109 "%02x:%02x:%02x:%02x:%02x:%02x",
9110 bssid[0], bssid[1], bssid[2], bssid[3],
9111 bssid[4], bssid[5]);
9112 } else {
9113 if (!get_hwaddr("wifi0", bssid)) {
9114 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID="
9115 "%02x:%02x:%02x:%02x:%02x:%02x",
9116 bssid[0], bssid[1], bssid[2], bssid[3],
9117 bssid[4], bssid[5]);
9118 run_system(dut, buf);
9119 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid),
9120 "%02x:%02x:%02x:%02x:%02x:%02x",
9121 bssid[0], bssid[1], bssid[2], bssid[3],
9122 bssid[4], bssid[5]);
9123 } else {
9124 /* load the driver and try again */
9125 run_system(dut, "/etc/rc.d/rc.wlan up");
9126
9127 if (!get_hwaddr("wifi0", bssid)) {
9128 snprintf(buf, sizeof(buf),
9129 "cfg -a AP_HOTSPOT_HESSID="
9130 "%02x:%02x:%02x:%02x:%02x:%02x",
9131 bssid[0], bssid[1], bssid[2],
9132 bssid[3], bssid[4], bssid[5]);
9133 run_system(dut, buf);
9134 snprintf(dut->ap_hessid,
9135 sizeof(dut->ap_hessid),
9136 "%02x:%02x:%02x:%02x:%02x:%02x",
9137 bssid[0], bssid[1], bssid[2],
9138 bssid[3], bssid[4], bssid[5]);
9139 }
9140 }
9141 }
9142
9143 run_system(dut, "cfg -r AP_SSID_2");
9144 run_system(dut, "cfg -c");
9145 /* run_system(dut, "cfg -s"); */
9146 }
9147
9148
ath_reset_vht_defaults(struct sigma_dut * dut)9149 static void ath_reset_vht_defaults(struct sigma_dut *dut)
9150 {
9151 run_system(dut, "cfg -x");
9152 run_system(dut, "cfg -a AP_RADIO_ID=1");
9153 run_system(dut, "cfg -a AP_PRIMARY_CH_2=36");
9154 run_system(dut, "cfg -a AP_STARTMODE=standard");
9155 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80");
9156 run_system(dut, "cfg -a TX_CHAINMASK_2=7");
9157 run_system(dut, "cfg -a RX_CHAINMASK_2=7");
9158 run_system(dut, "cfg -a ATH_countrycode=0x348");
9159 /* NOTE: For Beeliner we have to turn off MU-MIMO */
9160 if (system("rm /tmp/secath*") != 0) {
9161 sigma_dut_print(dut, DUT_MSG_ERROR,
9162 "Failed to remove secath file");
9163 }
9164 }
9165
9166
9167 #ifdef NL80211_SUPPORT
9168
9169 #define IEEE80211_HT_AMPDU_PARAM_FACTOR 0x3
9170 #define IEEE80211_HT_AMPDU_PARAM_DENSITY_SHIFT 2
9171
phy_info_ht_capa(struct dut_hw_modes * mode,struct nlattr * capa,struct nlattr * ampdu_factor,struct nlattr * ampdu_density,struct nlattr * mcs_set)9172 static void phy_info_ht_capa(struct dut_hw_modes *mode, struct nlattr *capa,
9173 struct nlattr *ampdu_factor,
9174 struct nlattr *ampdu_density,
9175 struct nlattr *mcs_set)
9176 {
9177 if (capa)
9178 mode->ht_capab = nla_get_u16(capa);
9179
9180 if (ampdu_factor)
9181 mode->ampdu_params |= nla_get_u8(ampdu_factor) &
9182 IEEE80211_HT_AMPDU_PARAM_FACTOR;
9183
9184 if (ampdu_density)
9185 mode->ampdu_params |= nla_get_u8(ampdu_density) <<
9186 IEEE80211_HT_AMPDU_PARAM_DENSITY_SHIFT;
9187
9188 if (mcs_set && nla_len(mcs_set) >= sizeof(mode->mcs_set))
9189 memcpy(mode->mcs_set, nla_data(mcs_set), sizeof(mode->mcs_set));
9190 }
9191
9192
phy_info_vht_capa(struct dut_hw_modes * mode,struct nlattr * capa,struct nlattr * mcs_set)9193 static void phy_info_vht_capa(struct dut_hw_modes *mode,
9194 struct nlattr *capa,
9195 struct nlattr *mcs_set)
9196 {
9197 if (capa)
9198 mode->vht_capab = nla_get_u32(capa);
9199
9200 if (mcs_set && nla_len(mcs_set) >= sizeof(mode->vht_mcs_set))
9201 memcpy(mode->vht_mcs_set, nla_data(mcs_set),
9202 sizeof(mode->vht_mcs_set));
9203 }
9204
9205
phy_info_band(struct dut_hw_modes * mode,struct nlattr * nl_band)9206 static int phy_info_band(struct dut_hw_modes *mode, struct nlattr *nl_band)
9207 {
9208 struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
9209
9210 nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
9211 nla_len(nl_band), NULL);
9212
9213 phy_info_ht_capa(mode, tb_band[NL80211_BAND_ATTR_HT_CAPA],
9214 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR],
9215 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY],
9216 tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
9217
9218 phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
9219 tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
9220
9221 /* Other nl80211 band attributes can be parsed here, if required */
9222
9223 return NL_OK;
9224 }
9225
9226
antenna_mask_to_nss(unsigned int mask)9227 static int antenna_mask_to_nss(unsigned int mask)
9228 {
9229 unsigned int i;
9230 int msb = 0;
9231
9232 for (i = 0; i < sizeof(mask) * 8; i++)
9233 if ((mask >> i) & 1)
9234 msb = i;
9235
9236 return msb + 1;
9237 }
9238
9239
wiphy_info_handler(struct nl_msg * msg,void * arg)9240 static int wiphy_info_handler(struct nl_msg *msg, void *arg)
9241 {
9242 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9243 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9244 struct sigma_dut *dut = arg;
9245 unsigned int tx_antenna_mask;
9246 struct nlattr *nl_band;
9247 int rem_band;
9248
9249 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9250 genlmsg_attrlen(gnlh, 0), NULL);
9251
9252 if (tb[NL80211_ATTR_WIPHY_ANTENNA_TX]) {
9253 tx_antenna_mask =
9254 nla_get_u32(tb[NL80211_ATTR_WIPHY_ANTENNA_TX]);
9255 dut->ap_tx_streams = antenna_mask_to_nss(tx_antenna_mask);
9256 }
9257
9258 if (!tb[NL80211_ATTR_WIPHY_BANDS])
9259 return 1;
9260
9261 nla_for_each_nested(nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) {
9262 int res = phy_info_band(&dut->hw_modes, nl_band);
9263
9264 if (res != NL_OK)
9265 return res;
9266 }
9267
9268 return 0;
9269 }
9270
9271
mac80211_get_wiphy(struct sigma_dut * dut)9272 static int mac80211_get_wiphy(struct sigma_dut *dut)
9273 {
9274 struct nl_msg *msg;
9275 int ret = 0;
9276 int ifindex;
9277
9278 ifindex = if_nametoindex(dut->main_ifname);
9279 if (ifindex == 0) {
9280 sigma_dut_print(dut, DUT_MSG_DEBUG,
9281 "%s: Index for interface %s failed",
9282 __func__, dut->main_ifname);
9283 return -1;
9284 }
9285
9286 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9287 NL80211_CMD_GET_WIPHY)) ||
9288 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex)) {
9289 sigma_dut_print(dut, DUT_MSG_DEBUG,
9290 "%s: could not build get wiphy cmd", __func__);
9291 nlmsg_free(msg);
9292 return -1;
9293 }
9294
9295 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, wiphy_info_handler,
9296 dut);
9297 if (ret)
9298 sigma_dut_print(dut, DUT_MSG_DEBUG,
9299 "%s: err in send_and_recv_msgs, ret=%d",
9300 __func__, ret);
9301
9302 return ret;
9303 }
9304
9305 #endif /* NL80211_SUPPORT */
9306
9307
cmd_ap_reset_default(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9308 static enum sigma_cmd_result cmd_ap_reset_default(struct sigma_dut *dut,
9309 struct sigma_conn *conn,
9310 struct sigma_cmd *cmd)
9311 {
9312 const char *type, *program;
9313 enum driver_type drv;
9314 char buf[128];
9315 int i;
9316
9317 for (i = 0; i < MAX_WLAN_TAGS - 1; i++) {
9318 /*
9319 * Reset all tagged SSIDs to NULL-string and all key management
9320 * to open.
9321 */
9322 dut->ap_tag_ssid[i][0] = '\0';
9323 dut->ap_tag_key_mgmt[i] = AP2_OPEN;
9324 }
9325
9326 drv = get_driver_type(dut);
9327
9328 program = get_param(cmd, "program");
9329 if (!program)
9330 program = get_param(cmd, "prog");
9331 dut->program = sigma_program_to_enum(program);
9332 dut->device_type = AP_unknown;
9333 type = get_param(cmd, "type");
9334 if (type && strcasecmp(type, "Testbed") == 0)
9335 dut->device_type = AP_testbed;
9336 if (type && strcasecmp(type, "DUT") == 0)
9337 dut->device_type = AP_dut;
9338
9339 dut->ap_rts = 0;
9340 dut->ap_frgmnt = 0;
9341 dut->ap_bcnint = 0;
9342 dut->ap_key_mgmt = AP_OPEN;
9343 dut->ap_ssid[0] = '\0';
9344 dut->ap_fake_pkhash = 0;
9345 memset(dut->ap_qos, 0, sizeof(dut->ap_qos));
9346 memset(dut->ap_sta_qos, 0, sizeof(dut->ap_sta_qos));
9347 dut->ap_addba_reject = VALUE_NOT_SET;
9348 dut->ap_noack = VALUE_NOT_SET;
9349 dut->ap_is_dual = 0;
9350 dut->ap_mode = AP_inval;
9351 dut->ap_mode_1 = AP_inval;
9352
9353 dut->ap_allow_vht_wep = 0;
9354 dut->ap_allow_vht_tkip = 0;
9355 dut->ap_disable_protection = 0;
9356 memset(dut->ap_countrycode, 0, sizeof(dut->ap_countrycode));
9357 dut->ap_dyn_bw_sig = VALUE_NOT_SET;
9358 dut->ap_ldpc = VALUE_NOT_SET;
9359 dut->ap_sig_rts = VALUE_NOT_SET;
9360 dut->ap_rx_amsdu = VALUE_NOT_SET;
9361 dut->ap_txBF = 0;
9362 dut->ap_mu_txBF = 0;
9363 dut->ap_chwidth = AP_AUTO;
9364 dut->ap_ampdu_exp = 0;
9365 dut->ap_max_mpdu_len = 0;
9366
9367 dut->ap_rsn_preauth = 0;
9368 dut->ap_wpsnfc = 0;
9369 dut->ap_bss_load = -1;
9370 dut->ap_p2p_cross_connect = -1;
9371
9372 dut->ap_regulatory_mode = AP_80211D_MODE_DISABLED;
9373 dut->ap_dfs_mode = AP_DFS_MODE_DISABLED;
9374 dut->ap_chwidth_offset = SEC_CH_NO;
9375
9376 dut->mbo_pref_ap_cnt = 0;
9377 dut->ft_bss_mac_cnt = 0;
9378 dut->ap_interface_5g = 0;
9379 dut->ap_interface_2g = 0;
9380 dut->ap_pmf = AP_PMF_DISABLED;
9381
9382 dut->wsc_fragment = 0;
9383 dut->eap_fragment = 0;
9384 dut->wps_forced_version = 0;
9385
9386 if (dut->program == PROGRAM_HT || dut->program == PROGRAM_VHT) {
9387 dut->ap_wme = AP_WME_ON;
9388 dut->ap_wmmps = AP_WMMPS_ON;
9389 } else {
9390 dut->ap_wme = AP_WME_OFF;
9391 dut->ap_wmmps = AP_WMMPS_OFF;
9392 }
9393
9394 dut->ap_venue_url = 0;
9395 dut->ap_advice_of_charge = 0;
9396 dut->ap_oper_icon_metadata = 0;
9397 dut->ap_tnc_file_name = 0;
9398 dut->ap_tnc_time_stamp = 0;
9399
9400 dut->ap_akm_values = 0;
9401 free(dut->ap_sae_passwords);
9402 dut->ap_sae_passwords = NULL;
9403 dut->ap_sae_pk = 0;
9404 free(dut->ap_sae_pk_modifier);
9405 dut->ap_sae_pk_modifier = NULL;
9406 free(dut->ap_sae_pk_keypair);
9407 dut->ap_sae_pk_keypair = NULL;
9408 free(dut->ap_sae_pk_keypair_sig);
9409 dut->ap_sae_pk_keypair_sig = NULL;
9410
9411 dut->ap_ocvc = -1;
9412
9413 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
9414 dut->program == PROGRAM_HS2_R3 ||
9415 dut->program == PROGRAM_IOTLP) {
9416 int i;
9417
9418 if (drv == DRIVER_ATHEROS)
9419 cmd_ath_ap_hs2_reset(dut);
9420 else if (drv == DRIVER_OPENWRT)
9421 cmd_owrt_ap_hs2_reset(dut);
9422
9423 dut->ap_interworking = 1;
9424 dut->ap_access_net_type = 2;
9425 dut->ap_internet = 0;
9426 dut->ap_venue_group = 2;
9427 dut->ap_venue_type = 8;
9428 dut->ap_domain_name_list[0] = '\0';
9429 dut->ap_hs2 = 1;
9430 snprintf(dut->ap_roaming_cons, sizeof(dut->ap_roaming_cons),
9431 "506f9a;001bc504bd");
9432 dut->ap_l2tif = 0;
9433 dut->ap_proxy_arp = 0;
9434 if (dut->bridge) {
9435 char buf[50];
9436
9437 snprintf(buf, sizeof(buf), "ip neigh flush dev %s",
9438 dut->bridge);
9439 if (system(buf) != 0) {
9440 sigma_dut_print(dut, DUT_MSG_DEBUG,
9441 "%s ip neigh table flushing failed",
9442 dut->bridge);
9443 }
9444
9445 snprintf(buf, sizeof(buf), "ebtables -F");
9446 if (system(buf) != 0) {
9447 sigma_dut_print(dut, DUT_MSG_DEBUG,
9448 "%s ebtables flushing failed",
9449 dut->bridge);
9450 }
9451 }
9452 dut->ap_dgaf_disable = 0;
9453 dut->ap_p2p_cross_connect = 0;
9454 dut->ap_gas_cb_delay = 0;
9455 dut->ap_nai_realm_list = 0;
9456 dut->ap_oper_name = 0;
9457 dut->ap_venue_name = 0;
9458 for (i = 0; i < 10; i++) {
9459 dut->ap_plmn_mcc[i][0] = '\0';
9460 dut->ap_plmn_mnc[i][0] = '\0';
9461 }
9462 dut->ap_wan_metrics = 0;
9463 dut->ap_conn_capab = 0;
9464 dut->ap_ip_addr_type_avail = 0;
9465 dut->ap_net_auth_type = 0;
9466 dut->ap_oper_class = 0;
9467 dut->ap_pmf = 0;
9468 dut->ap_add_sha256 = 0;
9469 }
9470
9471 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
9472 dut->program == PROGRAM_IOTLP) {
9473 int i;
9474 const char hessid[] = "50:6f:9a:00:11:22";
9475
9476 memcpy(dut->ap_hessid, hessid, strlen(hessid) + 1);
9477 dut->ap_osu_ssid[0] = '\0';
9478 dut->ap_pmf = 1;
9479 dut->ap_osu_provider_list = 0;
9480 dut->ap_osu_provider_nai_list = 0;
9481 for (i = 0; i < 10; i++) {
9482 dut->ap_osu_server_uri[i][0] = '\0';
9483 dut->ap_osu_method[i] = 0xFF;
9484 }
9485 dut->ap_qos_map_set = 0;
9486 dut->ap_tag_key_mgmt[0] = AP2_OPEN;
9487 dut->ap2_proxy_arp = 0;
9488 dut->ap2_osu = 0;
9489 dut->ap_osu_icon_tag = 0;
9490 }
9491
9492 if (dut->program == PROGRAM_VHT) {
9493 /* Set up the defaults */
9494 dut->use_5g = 1;
9495 dut->ap_mode = AP_11ac;
9496 dut->ap_channel = 36;
9497 dut->ap_ampdu = VALUE_NOT_SET;
9498 dut->ap_ndpa_frame = 1;
9499 if (dut->device_type == AP_testbed) {
9500 dut->ap_amsdu = VALUE_DISABLED;
9501 dut->ap_ldpc = VALUE_DISABLED;
9502 dut->ap_rx_amsdu = VALUE_DISABLED;
9503 dut->ap_sgi80 = 0;
9504 } else {
9505 dut->ap_amsdu = VALUE_ENABLED;
9506 /*
9507 * As LDPC is optional, don't enable this by default
9508 * for LINUX-WCN driver. The ap_set_wireless command
9509 * can be used to enable LDPC, when needed.
9510 */
9511 if (drv != DRIVER_LINUX_WCN)
9512 dut->ap_ldpc = VALUE_ENABLED;
9513 dut->ap_rx_amsdu = VALUE_ENABLED;
9514 dut->ap_sgi80 = 1;
9515 }
9516 dut->ap_fixed_rate = 0;
9517 dut->ap_rx_streams = 3;
9518 dut->ap_tx_streams = 3;
9519 dut->ap_vhtmcs_map = 0;
9520 dut->ap_chwidth = AP_80;
9521 dut->ap_tx_stbc = 1;
9522 dut->ap_dyn_bw_sig = VALUE_ENABLED;
9523 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9524 dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
9525 if (get_driver_type(dut) == DRIVER_ATHEROS)
9526 ath_reset_vht_defaults(dut);
9527 }
9528
9529 if (dut->program == PROGRAM_IOTLP) {
9530 dut->wnm_bss_max_feature = VALUE_DISABLED;
9531 dut->wnm_bss_max_idle_time = 0;
9532 dut->wnm_bss_max_protection = VALUE_NOT_SET;
9533 dut->ap_proxy_arp = 1;
9534 } else {
9535 /*
9536 * Do not touch the BSS-MAX Idle time feature
9537 * if the program is not IOTLP.
9538 */
9539 dut->wnm_bss_max_feature = VALUE_NOT_SET;
9540 dut->wnm_bss_max_idle_time = 0;
9541 dut->wnm_bss_max_protection = VALUE_NOT_SET;
9542 }
9543
9544 if (dut->program == PROGRAM_LOC) {
9545 dut->ap_rrm = 1;
9546 dut->ap_rtt = 1;
9547 dut->ap_lci = 0;
9548 dut->ap_val_lci[0] = '\0';
9549 dut->ap_infoz[0] = '\0';
9550 dut->ap_lcr = 0;
9551 dut->ap_val_lcr[0] = '\0';
9552 dut->ap_neighap = 0;
9553 dut->ap_opchannel = 0;
9554 dut->ap_scan = 0;
9555 dut->ap_fqdn_held = 0;
9556 dut->ap_fqdn_supl = 0;
9557 dut->ap_interworking = 0;
9558 dut->ap_gas_cb_delay = 0;
9559 dut->ap_msnt_type = 0;
9560 }
9561 dut->ap_ft_oa = 0;
9562 dut->ap_ft_ds = VALUE_NOT_SET;
9563 dut->ap_reg_domain = REG_DOMAIN_NOT_SET;
9564 dut->ap_mobility_domain[0] = '\0';
9565
9566 if (dut->program == PROGRAM_MBO) {
9567 dut->ap_mbo = 1;
9568 dut->ap_interworking = 1;
9569 dut->ap_ne_class = 0;
9570 dut->ap_ne_op_ch = 0;
9571 dut->ap_set_bssidpref = 1;
9572 dut->ap_btmreq_disassoc_imnt = 0;
9573 dut->ap_btmreq_term_bit = 0;
9574 dut->ap_disassoc_timer = 0;
9575 dut->ap_btmreq_bss_term_dur = 0;
9576 dut->ap_channel = 36;
9577 dut->ap_chwidth = AP_20;
9578 dut->ap_cell_cap_pref = 0;
9579 dut->ap_gas_cb_delay = 0;
9580 dut->mbo_self_ap_tuple.ap_ne_class = -1;
9581 dut->mbo_self_ap_tuple.ap_ne_pref = -1; /* Not set */
9582 dut->mbo_self_ap_tuple.ap_ne_op_ch = -1;
9583 dut->ap_btmreq_bss_term_tsf = 0;
9584 dut->ap_assoc_delay = 0;
9585 }
9586
9587 if (dut->program == PROGRAM_OCE) {
9588 if (dut->ap_dhcp_stop)
9589 run_system(dut, "/etc/init.d/dnsmasq start");
9590
9591 dut->ap_dhcp_stop = 0;
9592 dut->ap_oce = VALUE_ENABLED;
9593 dut->ap_broadcast_ssid = VALUE_ENABLED;
9594 dut->ap_fils_dscv_int = 20;
9595 dut->ap_filsdscv = dut->dev_role == DEVROLE_STA_CFON ?
9596 VALUE_NOT_SET : VALUE_ENABLED;
9597 dut->ap_filshlp = VALUE_DISABLED;
9598 dut->ap_rnr = VALUE_DISABLED;
9599 dut->ap_nairealm[0] = '\0';
9600 dut->ap_nairealm_int = 0;
9601 dut->ap_blechanutil = 0;
9602 dut->ap_ble_admit_cap = 0;
9603 dut->ap_esp = VALUE_ENABLED;
9604 dut->ap_datappdudura = 0;
9605 dut->ap_airtimefract = 0;
9606 dut->ap_blestacnt = 0;
9607 dut->ap_ul_availcap = 0;
9608 dut->ap_dl_availcap = 0;
9609 dut->ap_akm = 0;
9610 dut->ap_add_sha256 = 0;
9611 dut->ap_add_sha384 = 0;
9612 dut->ap_80plus80 = 0;
9613 }
9614
9615 dut->ap_he_ppdu = PPDU_NOT_SET;
9616 dut->ap_he_ulofdma = VALUE_NOT_SET;
9617 dut->ap_numsounddim = 0;
9618 dut->ap_bcc = VALUE_DISABLED;
9619 dut->ap_mu_edca = VALUE_DISABLED;
9620 dut->ap_he_mimo = MIMO_NOT_SET;
9621 dut->ap_he_rtsthrshld = VALUE_NOT_SET;
9622 dut->ap_mbssid = VALUE_DISABLED;
9623 dut->ap_ampdu = VALUE_NOT_SET;
9624 dut->he_mcsnssmap = 0;
9625 dut->ap_fixed_rate = 0;
9626 dut->he_mmss = 0;
9627 dut->he_set_sta_1x1 = VALUE_DISABLED;
9628 dut->he_srctrl_allow = -1;
9629 if (dut->device_type == AP_testbed) {
9630 dut->ap_he_dlofdma = VALUE_DISABLED;
9631 dut->ap_he_frag = VALUE_DISABLED;
9632 dut->ap_twtresp = VALUE_DISABLED;
9633 dut->he_ul_mcs = 7;
9634 } else {
9635 dut->ap_he_dlofdma = VALUE_NOT_SET;
9636 dut->ap_he_frag = VALUE_NOT_SET;
9637 dut->ap_ba_bufsize = BA_BUFSIZE_NOT_SET;
9638 dut->ap_twtresp = VALUE_NOT_SET;
9639 dut->he_ul_mcs = 0;
9640 }
9641
9642 if (dut->program == PROGRAM_HE) {
9643 if (dut->device_type == AP_testbed) {
9644 dut->ap_ldpc = VALUE_DISABLED;
9645 dut->ap_ba_bufsize = BA_BUFSIZE_64;
9646 dut->ap_amsdu = VALUE_DISABLED;
9647 dut->ap_txBF = 0;
9648 dut->ap_mu_txBF = 0;
9649 dut->he_sounding = VALUE_DISABLED;
9650 } else {
9651 if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) {
9652 dut->ap_txBF = 0;
9653 dut->ap_mu_txBF = 0;
9654 } else {
9655 dut->ap_txBF = 1;
9656 dut->ap_mu_txBF = 1;
9657 }
9658 dut->he_sounding = VALUE_ENABLED;
9659 if (drv == DRIVER_LINUX_WCN) {
9660 dut->ap_ldpc = VALUE_ENABLED;
9661 wcn_config_ap_ldpc(dut, get_main_ifname(dut));
9662 #ifdef NL80211_SUPPORT
9663 if (wcn_set_he_ltf(dut, get_main_ifname(dut),
9664 QCA_WLAN_HE_LTF_AUTO)) {
9665 sigma_dut_print(dut, DUT_MSG_ERROR,
9666 "Failed to set LTF in ap_reset_default");
9667 }
9668 #endif /* NL80211_SUPPORT */
9669 }
9670 }
9671 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9672 dut->ap_dfs_mode = AP_DFS_MODE_ENABLED;
9673 }
9674
9675 memset(&dut->hw_modes, 0, sizeof(struct dut_hw_modes));
9676 #ifdef NL80211_SUPPORT
9677 if (get_driver_type(dut) == DRIVER_MAC80211 && mac80211_get_wiphy(dut))
9678 sigma_dut_print(dut, DUT_MSG_DEBUG,
9679 "Failed to get wiphy data from the driver");
9680 #endif /* NL80211_SUPPORT */
9681
9682 dut->ap_oper_chn = 0;
9683
9684 dut->ap_pmksa = 0;
9685 dut->ap_pmksa_caching = 0;
9686
9687 free(dut->rsne_override);
9688 dut->rsne_override = NULL;
9689 free(dut->rsnxe_override_eapol);
9690 dut->rsnxe_override_eapol = NULL;
9691
9692 free(dut->sae_commit_override);
9693 dut->sae_commit_override = NULL;
9694
9695 free(dut->ap_sae_groups);
9696 dut->ap_sae_groups = NULL;
9697
9698 dut->sae_anti_clogging_threshold = -1;
9699 dut->sae_reflection = 0;
9700 dut->ap_sae_commit_status = -1;
9701 dut->ap_sae_pk_omit = 0;
9702 dut->sae_confirm_immediate = 0;
9703 dut->sae_pwe = SAE_PWE_DEFAULT;
9704
9705 dut->ap_cipher = AP_CCMP;
9706 dut->ap_group_cipher = AP_NO_GROUP_CIPHER_SET;
9707 dut->ap_group_mgmt_cipher = AP_NO_GROUP_MGMT_CIPHER_SET;
9708 dut->ap_passphrase[0] = '\0';
9709 dut->ap_psk[0] = '\0';
9710 dut->ap_beacon_prot = 0;
9711 dut->ap_transition_disable = 0;
9712
9713 dut->dpp_conf_id = -1;
9714 free(dut->ap_dpp_conf_addr);
9715 dut->ap_dpp_conf_addr = NULL;
9716 free(dut->ap_dpp_conf_pkhash);
9717 dut->ap_dpp_conf_pkhash = NULL;
9718 dut->ap_start_disabled = 0;
9719
9720 if (is_60g_sigma_dut(dut)) {
9721 dut->ap_mode = AP_11ad;
9722 dut->ap_channel = 2;
9723 dut->wps_disable = 0; /* WPS is enabled */
9724 dut->ap_pmf = 0;
9725 dut->ap_num_ese_allocs = 0;
9726 dut->ap_fixed_rate = 0;
9727
9728 dut->dev_role = DEVROLE_AP;
9729
9730 sigma_dut_print(dut, DUT_MSG_DEBUG,
9731 "Setting msdu_size to MAX: 7912");
9732 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
9733 get_main_ifname(dut));
9734
9735 if (system(buf) != 0) {
9736 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9737 buf);
9738 return ERROR_SEND_STATUS;
9739 }
9740
9741 if (ap_set_force_mcs(dut, 0, 1)) {
9742 sigma_dut_print(dut, DUT_MSG_ERROR,
9743 "Failed to reset force MCS");
9744 return ERROR_SEND_STATUS;
9745 }
9746
9747 if (set_ps(get_main_ifname(dut), dut, 1)) {
9748 sigma_dut_print(dut, DUT_MSG_ERROR,
9749 "Failed to enable power save");
9750 return ERROR_SEND_STATUS;
9751 }
9752 }
9753
9754 if (dut->program == PROGRAM_WPS &&
9755 get_driver_type(dut) == DRIVER_WIL6210) {
9756 /*
9757 * In 60 GHz WPS tests, we configure the AP OOB to
9758 * secure connection with a random passphrase.
9759 */
9760 char r[16], passphrase[65];
9761
9762 if (random_get_bytes(r, sizeof(r))) {
9763 sigma_dut_print(dut, DUT_MSG_ERROR,
9764 "Failed to get random bytes");
9765 return ERROR_SEND_STATUS;
9766 }
9767 if (base64_encode(r, sizeof(r),
9768 passphrase, sizeof(passphrase))) {
9769 sigma_dut_print(dut, DUT_MSG_ERROR,
9770 "Failed to generate random passphrase");
9771 return ERROR_SEND_STATUS;
9772 }
9773
9774 dut->ap_key_mgmt = AP_WPA2_PSK;
9775 dut->ap_cipher = AP_GCMP_128;
9776 strlcpy(dut->ap_passphrase, passphrase,
9777 sizeof(dut->ap_passphrase));
9778 sigma_dut_print(dut, DUT_MSG_DEBUG,
9779 "60G WPS: configure secure AP with random passphrase");
9780 }
9781
9782 dut->hostapd_running = 0;
9783
9784 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
9785 return 1;
9786
9787 if (dut->use_hostapd_pid_file) {
9788 kill_hostapd_process_pid(dut);
9789 } else if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 ||
9790 system("killall hostapd") == 0) {
9791 int i;
9792 /* Wait some time to allow hostapd to complete cleanup before
9793 * starting a new process */
9794 for (i = 0; i < 10; i++) {
9795 usleep(500000);
9796 if (system("pidof hostapd") != 0)
9797 break;
9798 }
9799 }
9800
9801 if (if_nametoindex("sigmadut") > 0 &&
9802 system("iw dev sigmadut del") != 0)
9803 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove "
9804 "monitor interface");
9805
9806 return 1;
9807 }
9808
9809
sta_cfon_reset_default(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9810 int sta_cfon_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
9811 struct sigma_cmd *cmd)
9812 {
9813 return cmd_ap_reset_default(dut, conn, cmd);
9814 }
9815
9816
cmd_ap_get_info(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9817 static enum sigma_cmd_result cmd_ap_get_info(struct sigma_dut *dut,
9818 struct sigma_conn *conn,
9819 struct sigma_cmd *cmd)
9820 {
9821 /* const char *name = get_param(cmd, "NAME"); */
9822 struct stat s;
9823 char resp[200];
9824 FILE *f;
9825 enum driver_type drv = get_driver_type(dut);
9826 int res;
9827
9828 switch (drv) {
9829 case DRIVER_ATHEROS: {
9830 /* Atheros AP */
9831 struct utsname uts;
9832 char *version, athver[100];
9833
9834 if (stat("/proc/athversion", &s) != 0) {
9835 if (system("/etc/rc.d/rc.wlan up") != 0) {
9836 }
9837 }
9838
9839 athver[0] = '\0';
9840 f = fopen("/proc/athversion", "r");
9841 if (f) {
9842 if (fgets(athver, sizeof(athver), f)) {
9843 char *pos = strchr(athver, '\n');
9844 if (pos)
9845 *pos = '\0';
9846 }
9847 fclose(f);
9848 }
9849
9850 if (uname(&uts) == 0)
9851 version = uts.release;
9852 else
9853 version = "Unknown";
9854
9855 if (if_nametoindex("ath1") > 0)
9856 res = snprintf(resp, sizeof(resp),
9857 "interface,ath0_24G ath1_5G,agent,1.0,version,%s/drv:%s",
9858 version, athver);
9859 else
9860 res = snprintf(resp, sizeof(resp),
9861 "interface,ath0_24G,agent,1.0,version,%s/drv:%s",
9862 version, athver);
9863 if (res < 0 || res >= sizeof(resp))
9864 send_resp(dut, conn, SIGMA_ERROR, NULL);
9865 else
9866 send_resp(dut, conn, SIGMA_COMPLETE, resp);
9867 return 0;
9868 }
9869 case DRIVER_LINUX_WCN:
9870 case DRIVER_MAC80211: {
9871 struct utsname uts;
9872 char *version;
9873
9874 if (uname(&uts) == 0)
9875 version = uts.release;
9876 else
9877 version = "Unknown";
9878
9879 if (if_nametoindex("wlan1") > 0)
9880 snprintf(resp, sizeof(resp), "interface,wlan0_24G "
9881 "wlan1_5G,agent,1.0,version,%s", version);
9882 else
9883 snprintf(resp, sizeof(resp), "interface,wlan0_any,"
9884 "agent,1.0,version,%s", version);
9885
9886 send_resp(dut, conn, SIGMA_COMPLETE, resp);
9887 return 0;
9888 }
9889 case DRIVER_QNXNTO: {
9890 struct utsname uts;
9891 char *version;
9892
9893 if (uname(&uts) == 0)
9894 version = uts.release;
9895 else
9896 version = "Unknown";
9897 snprintf(resp, sizeof(resp),
9898 "interface,%s_any,agent,1.0,version,%s",
9899 dut->main_ifname ? get_main_ifname(dut) : "NA",
9900 version);
9901 send_resp(dut, conn, SIGMA_COMPLETE, resp);
9902 return 0;
9903 }
9904 case DRIVER_OPENWRT: {
9905 switch (get_openwrt_driver_type()) {
9906 case OPENWRT_DRIVER_ATHEROS: {
9907 struct utsname uts;
9908 char *version;
9909
9910 if (uname(&uts) == 0)
9911 version = uts.release;
9912 else
9913 version = "Unknown";
9914
9915 if (if_nametoindex("ath1") > 0)
9916 snprintf(resp, sizeof(resp),
9917 "interface,ath0_5G ath1_24G,agent,1.0,version,%s",
9918 version);
9919 else
9920 snprintf(resp, sizeof(resp),
9921 "interface,ath0_any,agent,1.0,version,%s",
9922 version);
9923
9924 send_resp(dut, conn, SIGMA_COMPLETE, resp);
9925 return 0;
9926 }
9927 default:
9928 send_resp(dut, conn, SIGMA_ERROR,
9929 "errorCode,Unsupported openwrt driver");
9930 return 0;
9931 }
9932 }
9933 default:
9934 send_resp(dut, conn, SIGMA_ERROR,
9935 "errorCode,Unsupported driver");
9936 return 0;
9937 }
9938 }
9939
9940
cmd_ap_deauth_sta(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)9941 static enum sigma_cmd_result cmd_ap_deauth_sta(struct sigma_dut *dut,
9942 struct sigma_conn *conn,
9943 struct sigma_cmd *cmd)
9944 {
9945 /* const char *name = get_param(cmd, "NAME"); */
9946 /* const char *ifname = get_param(cmd, "INTERFACE"); */
9947 const char *val, *disconnect;
9948 char buf[100];
9949
9950 val = get_param(cmd, "MinorCode");
9951 if (val) {
9952 /* TODO: add support for P2P minor code */
9953 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MinorCode not "
9954 "yet supported");
9955 return 0;
9956 }
9957
9958 val = get_param(cmd, "STA_MAC_ADDRESS");
9959 if (val == NULL)
9960 return -1;
9961 disconnect = get_param(cmd, "disconnect");
9962 if (disconnect && strcasecmp(disconnect, "silent") == 0)
9963 snprintf(buf, sizeof(buf), "deauth %s tx=0", val);
9964 else
9965 snprintf(buf, sizeof(buf), "deauth %s", val);
9966 if (run_hostapd_cli(dut, buf) != 0)
9967 return -2;
9968
9969 return 1;
9970 }
9971
9972
9973 #ifdef __linux__
9974 int inject_frame(int s, const void *data, size_t len, int encrypt);
9975 int open_monitor(const char *ifname);
9976 #endif /* __linux__ */
9977
9978 enum send_frame_type {
9979 DISASSOC, DEAUTH, SAQUERY
9980 };
9981 enum send_frame_protection {
9982 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9983 };
9984
9985
ap_inject_frame(struct sigma_dut * dut,struct sigma_conn * conn,enum send_frame_type frame,enum send_frame_protection protected,const char * sta_addr)9986 static int ap_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9987 enum send_frame_type frame,
9988 enum send_frame_protection protected,
9989 const char *sta_addr)
9990 {
9991 #ifdef __linux__
9992 unsigned char buf[1000], *pos;
9993 int s, res;
9994 unsigned char addr_sta[6], addr_own[6];
9995 char *ifname;
9996 char cbuf[100];
9997 struct ifreq ifr;
9998
9999 if ((dut->ap_mode == AP_11a || dut->ap_mode == AP_11na ||
10000 dut->ap_mode == AP_11ac) &&
10001 if_nametoindex("wlan1") > 0)
10002 ifname = "wlan1";
10003 else
10004 ifname = "wlan0";
10005
10006 if (hwaddr_aton(sta_addr, addr_sta) < 0)
10007 return -1;
10008
10009 s = socket(AF_INET, SOCK_DGRAM, 0);
10010 if (s < 0)
10011 return -1;
10012 memset(&ifr, 0, sizeof(ifr));
10013 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10014 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
10015 perror("ioctl");
10016 close(s);
10017 return -1;
10018 }
10019 close(s);
10020 memcpy(addr_own, ifr.ifr_hwaddr.sa_data, 6);
10021
10022 if (if_nametoindex("sigmadut") == 0) {
10023 snprintf(cbuf, sizeof(cbuf),
10024 "iw dev %s interface add sigmadut type monitor",
10025 ifname);
10026 if (system(cbuf) != 0 ||
10027 if_nametoindex("sigmadut") == 0) {
10028 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10029 "monitor interface with '%s'", cbuf);
10030 return -2;
10031 }
10032 }
10033
10034 if (system("ifconfig sigmadut up") != 0) {
10035 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10036 "monitor interface up");
10037 return -2;
10038 }
10039
10040 pos = buf;
10041
10042 /* Frame Control */
10043 switch (frame) {
10044 case DISASSOC:
10045 *pos++ = 0xa0;
10046 break;
10047 case DEAUTH:
10048 *pos++ = 0xc0;
10049 break;
10050 case SAQUERY:
10051 *pos++ = 0xd0;
10052 break;
10053 }
10054
10055 if (protected == INCORRECT_KEY)
10056 *pos++ = 0x40; /* Set Protected field to 1 */
10057 else
10058 *pos++ = 0x00;
10059
10060 /* Duration */
10061 *pos++ = 0x00;
10062 *pos++ = 0x00;
10063
10064 /* addr1 = DA (station) */
10065 memcpy(pos, addr_sta, 6);
10066 pos += 6;
10067 /* addr2 = SA (own address) */
10068 memcpy(pos, addr_own, 6);
10069 pos += 6;
10070 /* addr3 = BSSID (own address) */
10071 memcpy(pos, addr_own, 6);
10072 pos += 6;
10073
10074 /* Seq# (to be filled by driver/mac80211) */
10075 *pos++ = 0x00;
10076 *pos++ = 0x00;
10077
10078 if (protected == INCORRECT_KEY) {
10079 /* CCMP parameters */
10080 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
10081 pos += 8;
10082 }
10083
10084 if (protected == INCORRECT_KEY) {
10085 switch (frame) {
10086 case DEAUTH:
10087 /* Reason code (encrypted) */
10088 memcpy(pos, "\xa7\x39", 2);
10089 pos += 2;
10090 break;
10091 case DISASSOC:
10092 /* Reason code (encrypted) */
10093 memcpy(pos, "\xa7\x39", 2);
10094 pos += 2;
10095 break;
10096 case SAQUERY:
10097 /* Category|Action|TransID (encrypted) */
10098 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
10099 pos += 4;
10100 break;
10101 default:
10102 return -1;
10103 }
10104
10105 /* CCMP MIC */
10106 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
10107 pos += 8;
10108 } else {
10109 switch (frame) {
10110 case DEAUTH:
10111 /* reason code = 8 */
10112 *pos++ = 0x08;
10113 *pos++ = 0x00;
10114 break;
10115 case DISASSOC:
10116 /* reason code = 8 */
10117 *pos++ = 0x08;
10118 *pos++ = 0x00;
10119 break;
10120 case SAQUERY:
10121 /* Category - SA Query */
10122 *pos++ = 0x08;
10123 /* SA query Action - Request */
10124 *pos++ = 0x00;
10125 /* Transaction ID */
10126 *pos++ = 0x12;
10127 *pos++ = 0x34;
10128 break;
10129 }
10130 }
10131
10132 s = open_monitor("sigmadut");
10133 if (s < 0) {
10134 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
10135 "monitor socket");
10136 return 0;
10137 }
10138
10139 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
10140 if (res < 0) {
10141 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
10142 "inject frame");
10143 close(s);
10144 return 0;
10145 }
10146 if (res < pos - buf) {
10147 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
10148 "frame sent");
10149 close(s);
10150 return 0;
10151 }
10152
10153 close(s);
10154
10155 return 1;
10156 #else /* __linux__ */
10157 send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_send_frame not "
10158 "yet supported");
10159 return 0;
10160 #endif /* __linux__ */
10161 }
10162
10163
ap_send_frame_hs2(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10164 int ap_send_frame_hs2(struct sigma_dut *dut, struct sigma_conn *conn,
10165 struct sigma_cmd *cmd)
10166 {
10167 const char *val, *dest;
10168 char buf[100];
10169
10170 val = get_param(cmd, "FrameName");
10171 if (val == NULL)
10172 return -1;
10173
10174 if (strcasecmp(val, "QoSMapConfigure") == 0) {
10175 dest = get_param(cmd, "Dest");
10176 if (!dest)
10177 return -1;
10178
10179 val = get_param(cmd, "QoS_MAP_SET");
10180 if (val) {
10181 dut->ap_qos_map_set = atoi(val);
10182 sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
10183 dut->ap_qos_map_set);
10184 }
10185
10186 if (dut->ap_qos_map_set == 1)
10187 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1);
10188 else if (dut->ap_qos_map_set == 2)
10189 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2);
10190
10191 snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest);
10192 if (run_hostapd_cli(dut, buf) != 0)
10193 return -1;
10194 }
10195
10196 return 1;
10197 }
10198
10199
ath_ap_send_frame_vht(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10200 static int ath_ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10201 struct sigma_cmd *cmd)
10202 {
10203 const char *val;
10204 const char *ifname;
10205 int chwidth, nss;
10206
10207 val = get_param(cmd, "FrameName");
10208 if (!val || strcasecmp(val, "op_md_notif_frm") != 0) {
10209 send_resp(dut, conn, SIGMA_ERROR,
10210 "errorCode,Unsupported FrameName");
10211 return 0;
10212 }
10213
10214 /*
10215 * Sequence of commands for Opmode notification on
10216 * Peregrine based products
10217 */
10218 ifname = get_main_ifname(dut);
10219
10220 /* Disable STBC */
10221 run_iwpriv(dut, ifname, "tx_stbc 0");
10222
10223 /* Check whether optional arg channel width was passed */
10224 val = get_param(cmd, "Channel_width");
10225 if (val) {
10226 switch (atoi(val)) {
10227 case 20:
10228 chwidth = 0;
10229 break;
10230 case 40:
10231 chwidth = 1;
10232 break;
10233 case 80:
10234 chwidth = 2;
10235 break;
10236 case 160:
10237 chwidth = 3;
10238 break;
10239 default:
10240 chwidth = 2;
10241 break;
10242 }
10243 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
10244 }
10245
10246 /* Check whether optional arg NSS was passed */
10247 val = get_param(cmd, "NSS");
10248 if (val) {
10249 /* Convert nss to chainmask */
10250 switch (atoi(val)) {
10251 case 1:
10252 nss = 1;
10253 break;
10254 case 2:
10255 nss = 3;
10256 break;
10257 case 3:
10258 nss = 7;
10259 break;
10260 default:
10261 /* We do not support NSS > 3 */
10262 nss = 3;
10263 break;
10264 }
10265 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
10266 }
10267
10268 /* Send the opmode notification */
10269 run_iwpriv(dut, ifname, "opmode_notify 1");
10270
10271 return 1;
10272 }
10273
10274
ath_ap_send_frame_loc(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10275 static int ath_ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn,
10276 struct sigma_cmd *cmd)
10277 {
10278 const char *val;
10279 FILE *f;
10280 int rand_int = 0;
10281
10282 val = get_param(cmd, "MsntType");
10283 if (val) {
10284 if (dut->ap_msnt_type == 0)
10285 dut->ap_msnt_type = atoi(val);
10286
10287 if (dut->ap_msnt_type != 5 && dut->ap_msnt_type != 2) {
10288 dut->ap_msnt_type = atoi(val);
10289 if (dut->ap_msnt_type == 1) {
10290 val = get_param(cmd, "RandInterval");
10291 if (val)
10292 rand_int = atoi(val);
10293 f = fopen("/tmp/ftmrr.txt", "a");
10294 if (!f) {
10295 sigma_dut_print(dut, DUT_MSG_ERROR,
10296 "Failed to open /tmp/ftmrr.txt");
10297 return -1;
10298 }
10299
10300 fprintf(f, "sta_mac = %s\n", cmd->values[3]);
10301 fprintf(f, "meas_type = 0x10\nrand_inter = 0x%x\nmin_ap_count = 0x%s\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0xf\nmeas_req_mode = 0x00\n",
10302 rand_int, cmd->values[7]);
10303 fclose(f);
10304 dut->ap_msnt_type = 5;
10305 run_system(dut, "wpc -f /tmp/ftmrr.txt");
10306 }
10307 } else if (dut->ap_msnt_type == 5) {
10308 run_system(dut, "wpc -f /tmp/ftmrr.txt");
10309 } else if (dut->ap_msnt_type == 2) {
10310 f = fopen("/tmp/wru.txt", "w");
10311 if (!f) {
10312 sigma_dut_print(dut, DUT_MSG_ERROR,
10313 "Failed to open /tmp/wru.txt");
10314 return -1;
10315 }
10316
10317 fprintf(f, "sta_mac = %s\n", cmd->values[3]);
10318 fprintf(f, "meas_type = 0x08\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0x1\nmeas_req_mode = 0x00\nloc_subject = 0x01\n");
10319 fclose(f);
10320 run_system(dut, "wpc -w /tmp/wru.txt");
10321 }
10322 }
10323 return 1;
10324 }
10325
10326
10327 /*
10328 * The following functions parse_send_frame_params_int(),
10329 * parse_send_frame_params_str(), and parse_send_frame_params_mac()
10330 * are used by ath_ap_send_frame_bcn_rpt_req().
10331 * Beacon Report Request is a frame used as part of the MBO program.
10332 * The command for sending beacon report has a lot of
10333 * arguments and having these functions reduces code size.
10334 *
10335 */
parse_send_frame_params_int(char * param,struct sigma_cmd * cmd,struct sigma_dut * dut,char * buf,size_t buf_size)10336 static int parse_send_frame_params_int(char *param, struct sigma_cmd *cmd,
10337 struct sigma_dut *dut,
10338 char *buf, size_t buf_size)
10339 {
10340 const char *str_val;
10341 int int_val;
10342 char temp[100];
10343
10344 str_val = get_param(cmd, param);
10345 if (!str_val) {
10346 sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
10347 return -1;
10348 }
10349 int_val = atoi(str_val);
10350 snprintf(temp, sizeof(temp), " %d", int_val);
10351 strlcat(buf, temp, buf_size);
10352 return 0;
10353 }
10354
10355
parse_send_frame_params_str(char * param,struct sigma_cmd * cmd,struct sigma_dut * dut,char * buf,size_t buf_size)10356 static int parse_send_frame_params_str(char *param, struct sigma_cmd *cmd,
10357 struct sigma_dut *dut,
10358 char *buf, size_t buf_size)
10359 {
10360 const char *str_val;
10361 char temp[100];
10362
10363 str_val = get_param(cmd, param);
10364 if (!str_val) {
10365 sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
10366 return -1;
10367 }
10368 snprintf(temp, sizeof(temp), " %s", str_val);
10369 temp[sizeof(temp) - 1] = '\0';
10370 strlcat(buf, temp, buf_size);
10371 return 0;
10372 }
10373
10374
parse_send_frame_params_mac(char * param,struct sigma_cmd * cmd,struct sigma_dut * dut,char * buf,size_t buf_size)10375 static int parse_send_frame_params_mac(char *param, struct sigma_cmd *cmd,
10376 struct sigma_dut *dut,
10377 char *buf, size_t buf_size)
10378 {
10379 const char *str_val;
10380 unsigned char mac[6];
10381 char temp[100];
10382
10383 str_val = get_param(cmd, param);
10384 if (!str_val) {
10385 sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param);
10386 return -1;
10387 }
10388
10389 if (parse_mac_address(dut, str_val, mac) < 0) {
10390 sigma_dut_print(dut, DUT_MSG_ERROR,
10391 "MAC Address not in proper format");
10392 return -1;
10393 }
10394 snprintf(temp, sizeof(temp), " %02x:%02x:%02x:%02x:%02x:%02x",
10395 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
10396 strlcat(buf, temp, buf_size);
10397 return 0;
10398 }
10399
10400
fill_1_or_0_based_on_presence(struct sigma_cmd * cmd,char * param,char * buf,size_t buf_size)10401 static void fill_1_or_0_based_on_presence(struct sigma_cmd *cmd, char *param,
10402 char *buf, size_t buf_size)
10403 {
10404 const char *str_val;
10405 char *value = " 1";
10406
10407 str_val = get_param(cmd, param);
10408 if (!str_val || str_val[0] == '\0')
10409 value = " 0";
10410 strlcat(buf, value, buf_size);
10411
10412 }
10413
10414
10415 /*
10416 * wifitool athN sendbcnrpt
10417 * <STA MAC - Plugs in from Dest_MAC>
10418 * <regclass - Plugs in from RegClass - int>
10419 * <channum - Plugs in from Channel PARAM of dev_send_frame - int>
10420 * <rand_ivl - Plugs in from RandInt - string>
10421 * <duration - Plugs in from MeaDur - integer>
10422 * <mode - Plugs in from MeaMode - string>
10423 * <req_ssid - Plugs in from SSID PARAM of dev_send_frame - string>
10424 * <rep_cond - Plugs in from RptCond - integer>
10425 * <rpt_detail - Plugs in from RptDet - integer>
10426 * <req_ie - Plugs in from ReqInfo PARAM of dev_send_frame - string>
10427 * <chanrpt_mode - Plugs in from APChanRpt - integer>
10428 * <specific_bssid - Plugs in from BSSID PARAM of dev_send_frame>
10429 * [AP channel numbers]
10430 */
ath_ap_send_frame_bcn_rpt_req(struct sigma_dut * dut,struct sigma_cmd * cmd,const char * ifname)10431 static int ath_ap_send_frame_bcn_rpt_req(struct sigma_dut *dut,
10432 struct sigma_cmd *cmd,
10433 const char *ifname)
10434 {
10435 char buf[100];
10436 int rpt_det;
10437 const char *str_val;
10438 const char *mea_mode;
10439
10440 snprintf(buf, sizeof(buf), "wifitool %s sendbcnrpt", ifname);
10441
10442 if (parse_send_frame_params_mac("Dest_MAC", cmd, dut, buf, sizeof(buf)))
10443 return -1;
10444 if (parse_send_frame_params_int("RegClass", cmd, dut, buf, sizeof(buf)))
10445 return -1;
10446 if (parse_send_frame_params_int("Channel", cmd, dut, buf, sizeof(buf)))
10447 return -1;
10448 if (parse_send_frame_params_str("RandInt", cmd, dut, buf, sizeof(buf)))
10449 return -1;
10450 if (parse_send_frame_params_int("MeaDur", cmd, dut, buf, sizeof(buf)))
10451 return -1;
10452
10453 str_val = get_param(cmd, "MeaMode");
10454 if (!str_val) {
10455 sigma_dut_print(dut, DUT_MSG_ERROR,
10456 "MeaMode parameter not present in send bcn-rpt-req");
10457 return -1;
10458 }
10459 if (strcasecmp(str_val, "passive") == 0) {
10460 mea_mode = " 0";
10461 } else if (strcasecmp(str_val, "active") == 0) {
10462 mea_mode = " 1";
10463 } else if (strcasecmp(str_val, "table") == 0) {
10464 mea_mode = " 2";
10465 } else {
10466 sigma_dut_print(dut, DUT_MSG_ERROR,
10467 "MEA-MODE Value not correctly given");
10468 return -1;
10469 }
10470 strlcat(buf, mea_mode, sizeof(buf));
10471
10472 fill_1_or_0_based_on_presence(cmd, "SSID", buf, sizeof(buf));
10473
10474 if (parse_send_frame_params_int("RptCond", cmd, dut, buf, sizeof(buf)))
10475 return -1;
10476
10477 if (parse_send_frame_params_int("RptDet", cmd, dut, buf, sizeof(buf)))
10478 return -1;
10479 str_val = get_param(cmd, "RptDet");
10480 rpt_det = str_val ? atoi(str_val) : 0;
10481
10482 if (rpt_det)
10483 fill_1_or_0_based_on_presence(cmd, "ReqInfo", buf, sizeof(buf));
10484 else
10485 strlcat(buf, " 0", sizeof(buf));
10486
10487 if (rpt_det)
10488 fill_1_or_0_based_on_presence(cmd, "APChanRpt", buf,
10489 sizeof(buf));
10490 else
10491 strlcat(buf, " 0", sizeof(buf));
10492
10493 if (parse_send_frame_params_mac("BSSID", cmd, dut, buf, sizeof(buf)))
10494 return -1;
10495
10496 str_val = get_param(cmd, "APChanRpt");
10497 if (str_val) {
10498 const char *pos;
10499 int ap_chanrpt;
10500 int ap_chanrpt_2 = 0;
10501 char chanrpt[100];
10502
10503 ap_chanrpt = atoi(str_val);
10504 pos = strchr(str_val, '_');
10505 if (pos) {
10506 pos++;
10507 ap_chanrpt_2 = atoi(pos);
10508 }
10509 if (ap_chanrpt) {
10510 snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt);
10511 strlcat(buf, chanrpt, sizeof(buf));
10512 }
10513 if (ap_chanrpt_2) {
10514 snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt_2);
10515 strlcat(buf, chanrpt, sizeof(buf));
10516 }
10517 }
10518
10519 run_system(dut, buf);
10520 return 0;
10521 }
10522
10523
inform_and_sleep(struct sigma_dut * dut,int seconds)10524 static void inform_and_sleep(struct sigma_dut *dut, int seconds)
10525 {
10526 sigma_dut_print(dut, DUT_MSG_DEBUG, "sleeping for %d seconds", seconds);
10527 sleep(seconds);
10528 sigma_dut_print(dut, DUT_MSG_DEBUG, "woke up after %d seconds",
10529 seconds);
10530 }
10531
10532
ath_ap_send_frame_btm_req(struct sigma_dut * dut,struct sigma_cmd * cmd,const char * ifname)10533 static int ath_ap_send_frame_btm_req(struct sigma_dut *dut,
10534 struct sigma_cmd *cmd, const char *ifname)
10535 {
10536 unsigned char mac_addr[ETH_ALEN];
10537 int disassoc_timer;
10538 char buf[100];
10539 const char *val;
10540 int cand_list = 1;
10541
10542 val = get_param(cmd, "Dest_MAC");
10543 if (!val || parse_mac_address(dut, val, mac_addr) < 0) {
10544 sigma_dut_print(dut, DUT_MSG_ERROR,
10545 "MAC Address not in proper format");
10546 return -1;
10547 }
10548
10549 val = get_param(cmd, "Disassoc_Timer");
10550 if (val)
10551 disassoc_timer = atoi(val);
10552 else
10553 disassoc_timer = dut->ap_disassoc_timer;
10554 if (disassoc_timer < 0) {
10555 sigma_dut_print(dut, DUT_MSG_ERROR,
10556 "Invalid Disassoc_Timer value %d",
10557 disassoc_timer);
10558 return -1;
10559 }
10560
10561 val = get_param(cmd, "Cand_List");
10562 if (val && val[0])
10563 cand_list = atoi(val);
10564
10565 val = get_param(cmd, "BTMQuery_Reason_Code");
10566 if (val)
10567 run_iwpriv(dut, ifname, "mbo_trans_rs %s", val);
10568
10569 if (dut->ap_btmreq_disassoc_imnt && !dut->ap_assoc_delay)
10570 run_iwpriv(dut, ifname, "mbo_asoc_ret 1");
10571
10572 snprintf(buf, sizeof(buf),
10573 "wifitool %s sendbstmreq %02x:%02x:%02x:%02x:%02x:%02x %d %d 15 %d %d %d %d",
10574 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
10575 mac_addr[4], mac_addr[5], cand_list, disassoc_timer,
10576 dut->ap_btmreq_disassoc_imnt,
10577 dut->ap_btmreq_term_bit,
10578 dut->ap_btmreq_bss_term_tsf,
10579 dut->ap_btmreq_bss_term_dur);
10580 run_system(dut, buf);
10581
10582 if (dut->ap_btmreq_term_bit) {
10583 if (dut->ap_btmreq_bss_term_tsf >= 2)
10584 inform_and_sleep(dut, dut->ap_btmreq_bss_term_tsf - 2);
10585 run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10586 mac_addr[0], mac_addr[1], mac_addr[2],
10587 mac_addr[3], mac_addr[4], mac_addr[5]);
10588 inform_and_sleep(dut, 2);
10589 run_system_wrapper(dut, "ifconfig %s down", ifname);
10590 inform_and_sleep(dut, 5);
10591 run_system_wrapper(dut, "ifconfig %s up", ifname);
10592 } else if (dut->ap_btmreq_disassoc_imnt) {
10593 inform_and_sleep(dut, (disassoc_timer / 1000) + 1);
10594 run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10595 mac_addr[0], mac_addr[1], mac_addr[2],
10596 mac_addr[3], mac_addr[4], mac_addr[5]);
10597 }
10598 return 0;
10599 }
10600
10601
ath_ap_send_frame_disassoc(struct sigma_dut * dut,struct sigma_cmd * cmd,const char * ifname)10602 static int ath_ap_send_frame_disassoc(struct sigma_dut *dut,
10603 struct sigma_cmd *cmd, const char *ifname)
10604 {
10605 unsigned char mac_addr[ETH_ALEN];
10606 const char *val;
10607
10608 val = get_param(cmd, "Dest_MAC");
10609 if (!val || parse_mac_address(dut, val, mac_addr) < 0) {
10610 sigma_dut_print(dut, DUT_MSG_ERROR,
10611 "MAC Address not in proper format");
10612 return -1;
10613 }
10614
10615 run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x",
10616 mac_addr[0], mac_addr[1], mac_addr[2],
10617 mac_addr[3], mac_addr[4], mac_addr[5]);
10618 return 0;
10619 }
10620
10621
ath_ap_send_frame_mbo(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10622 static int ath_ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn,
10623 struct sigma_cmd *cmd)
10624 {
10625 const char *val;
10626 const char *ifname;
10627
10628 ifname = get_main_ifname(dut);
10629
10630 val = get_param(cmd, "FrameName");
10631 if (!val)
10632 return -1;
10633
10634 if (strcasecmp(val, "BTMReq") == 0)
10635 ath_ap_send_frame_btm_req(dut, cmd, ifname);
10636 else if (strcasecmp(val, "BcnRptReq") == 0)
10637 ath_ap_send_frame_bcn_rpt_req(dut, cmd, ifname);
10638 else if (strcasecmp(val, "disassoc") == 0)
10639 ath_ap_send_frame_disassoc(dut, cmd, ifname);
10640 else
10641 return -1;
10642
10643 return 1;
10644 }
10645
10646
ap_send_frame_vht(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10647 static int ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10648 struct sigma_cmd *cmd)
10649 {
10650 switch (get_driver_type(dut)) {
10651 case DRIVER_ATHEROS:
10652 return ath_ap_send_frame_vht(dut, conn, cmd);
10653 break;
10654 case DRIVER_OPENWRT:
10655 switch (get_openwrt_driver_type()) {
10656 case OPENWRT_DRIVER_ATHEROS:
10657 return ath_ap_send_frame_vht(dut, conn, cmd);
10658 default:
10659 send_resp(dut, conn, SIGMA_ERROR,
10660 "errorCode,Unsupported ap_send_frame with the current openwrt driver");
10661 return 0;
10662 }
10663 default:
10664 send_resp(dut, conn, SIGMA_ERROR,
10665 "errorCode,Unsupported ap_send_frame with the current driver");
10666 return 0;
10667 }
10668 }
10669
10670
ap_send_frame_loc(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10671 static int ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn,
10672 struct sigma_cmd *cmd)
10673 {
10674 switch (get_driver_type(dut)) {
10675 case DRIVER_ATHEROS:
10676 return ath_ap_send_frame_loc(dut, conn, cmd);
10677 case DRIVER_OPENWRT:
10678 switch (get_openwrt_driver_type()) {
10679 case OPENWRT_DRIVER_ATHEROS:
10680 return ath_ap_send_frame_loc(dut, conn, cmd);
10681 default:
10682 send_resp(dut, conn, SIGMA_ERROR,
10683 "errorCode,Unsupported ap_send_frame_loc with the current openwrt driver");
10684 return 0;
10685 }
10686 default:
10687 send_resp(dut, conn, SIGMA_ERROR,
10688 "errorCode,Unsupported ap_send_frame_loc with the current driver");
10689 return 0;
10690 }
10691 }
10692
10693
ap_send_frame_mbo(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10694 static int ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn,
10695 struct sigma_cmd *cmd)
10696 {
10697 switch (get_driver_type(dut)) {
10698 case DRIVER_ATHEROS:
10699 return ath_ap_send_frame_mbo(dut, conn, cmd);
10700 case DRIVER_OPENWRT:
10701 switch (get_openwrt_driver_type()) {
10702 case OPENWRT_DRIVER_ATHEROS:
10703 return ath_ap_send_frame_mbo(dut, conn, cmd);
10704 default:
10705 send_resp(dut, conn, SIGMA_ERROR,
10706 "errorCode,Unsupported ap_send_frame with the current openwrt driver");
10707 return 0;
10708 }
10709 default:
10710 send_resp(dut, conn, SIGMA_ERROR,
10711 "errorCode,Unsupported ap_send_frame with the current driver");
10712 return 0;
10713 }
10714 }
10715
10716
ap_send_frame_60g(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10717 static int ap_send_frame_60g(struct sigma_dut *dut,
10718 struct sigma_conn *conn,
10719 struct sigma_cmd *cmd)
10720 {
10721 switch (get_driver_type(dut)) {
10722 #ifdef __linux__
10723 case DRIVER_WIL6210:
10724 return wil6210_send_frame_60g(dut, conn, cmd);
10725 #endif /* __linux__ */
10726 default:
10727 send_resp(dut, conn, SIGMA_ERROR,
10728 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10729 return 0;
10730 }
10731 }
10732
10733
cmd_ap_send_frame(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10734 enum sigma_cmd_result cmd_ap_send_frame(struct sigma_dut *dut,
10735 struct sigma_conn *conn,
10736 struct sigma_cmd *cmd)
10737 {
10738 /* const char *name = get_param(cmd, "NAME"); */
10739 /* const char *ifname = get_param(cmd, "INTERFACE"); */
10740 const char *val;
10741 enum send_frame_type frame;
10742 enum send_frame_protection protected;
10743 char buf[100];
10744
10745 val = get_param(cmd, "Program");
10746 if (val) {
10747 if (strcasecmp(val, "HS2") == 0 ||
10748 strcasecmp(val, "HS2-R2") == 0 ||
10749 strcasecmp(val, "IOTLP") == 0)
10750 return ap_send_frame_hs2(dut, conn, cmd);
10751 if (strcasecmp(val, "VHT") == 0)
10752 return ap_send_frame_vht(dut, conn, cmd);
10753 if (strcasecmp(val, "LOC") == 0)
10754 return ap_send_frame_loc(dut, conn, cmd);
10755 if (strcasecmp(val, "MBO") == 0)
10756 return ap_send_frame_mbo(dut, conn, cmd);
10757 if (strcasecmp(val, "60GHz") == 0)
10758 return ap_send_frame_60g(dut, conn, cmd);
10759 }
10760
10761 val = get_param(cmd, "PMFFrameType");
10762 if (val == NULL)
10763 val = get_param(cmd, "FrameName");
10764 if (val == NULL)
10765 val = get_param(cmd, "Type");
10766 if (val == NULL)
10767 return -1;
10768 if (strcasecmp(val, "disassoc") == 0)
10769 frame = DISASSOC;
10770 else if (strcasecmp(val, "deauth") == 0)
10771 frame = DEAUTH;
10772 else if (strcasecmp(val, "saquery") == 0)
10773 frame = SAQUERY;
10774 else {
10775 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10776 "PMFFrameType");
10777 return 0;
10778 }
10779
10780 val = get_param(cmd, "PMFProtected");
10781 if (val == NULL)
10782 val = get_param(cmd, "Protected");
10783 if (val == NULL)
10784 return -1;
10785 if (strcasecmp(val, "Correct-key") == 0 ||
10786 strcasecmp(val, "CorrectKey") == 0)
10787 protected = CORRECT_KEY;
10788 else if (strcasecmp(val, "IncorrectKey") == 0)
10789 protected = INCORRECT_KEY;
10790 else if (strcasecmp(val, "Unprotected") == 0)
10791 protected = UNPROTECTED;
10792 else {
10793 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10794 "PMFProtected");
10795 return 0;
10796 }
10797
10798 val = get_param(cmd, "stationID");
10799 if (val == NULL)
10800 return -1;
10801
10802 if (protected == INCORRECT_KEY ||
10803 (protected == UNPROTECTED && frame == SAQUERY))
10804 return ap_inject_frame(dut, conn, frame, protected, val);
10805
10806 switch (frame) {
10807 case DISASSOC:
10808 snprintf(buf, sizeof(buf), "disassoc %s test=%d",
10809 val, protected == CORRECT_KEY);
10810 break;
10811 case DEAUTH:
10812 snprintf(buf, sizeof(buf), "deauth %s test=%d",
10813 val, protected == CORRECT_KEY);
10814 break;
10815 case SAQUERY:
10816 snprintf(buf, sizeof(buf), "sa_query %s", val);
10817 break;
10818 }
10819
10820 if (run_hostapd_cli(dut, buf) != 0)
10821 return -2;
10822
10823 return 1;
10824 }
10825
10826
cmd_ap_get_mac_address(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10827 static enum sigma_cmd_result cmd_ap_get_mac_address(struct sigma_dut *dut,
10828 struct sigma_conn *conn,
10829 struct sigma_cmd *cmd)
10830 {
10831 #if defined( __linux__)
10832 /* const char *name = get_param(cmd, "NAME"); */
10833 /* const char *ifname = get_param(cmd, "INTERFACE"); */
10834 char resp[100];
10835 unsigned char addr[6];
10836 char ifname[50];
10837 struct ifreq ifr;
10838 int s, wlan_tag = 1;
10839 const char *val;
10840
10841 val = get_param(cmd, "WLAN_TAG");
10842 if (val) {
10843 wlan_tag = atoi(val);
10844 if (wlan_tag < 1 || wlan_tag > 3) {
10845 /*
10846 * The only valid WLAN Tags as of now as per the latest
10847 * WFA scripts are 1, 2, and 3.
10848 */
10849 send_resp(dut, conn, SIGMA_ERROR,
10850 "errorCode,Unsupported WLAN_TAG");
10851 return 0;
10852 }
10853 }
10854
10855 get_if_name(dut, ifname, sizeof(ifname), wlan_tag);
10856
10857 s = socket(AF_INET, SOCK_DGRAM, 0);
10858 if (s < 0)
10859 return -1;
10860 memset(&ifr, 0, sizeof(ifr));
10861 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10862 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
10863 perror("ioctl");
10864 close(s);
10865 snprintf(resp, sizeof(resp),
10866 "errorCode,Could not find interface %s", ifname);
10867 send_resp(dut, conn, SIGMA_ERROR, resp);
10868 return 0;
10869 }
10870 close(s);
10871 memcpy(addr, ifr.ifr_hwaddr.sa_data, 6);
10872
10873 snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x",
10874 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
10875 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10876 return 0;
10877 #elif defined( __QNXNTO__)
10878 char resp[50];
10879 unsigned char addr[6];
10880
10881 if (!dut->main_ifname) {
10882 send_resp(dut, conn, SIGMA_ERROR, "ifname is null");
10883 return 0;
10884 }
10885
10886 if (get_hwaddr(get_main_ifname(dut), addr) != 0) {
10887 send_resp(dut, conn, SIGMA_ERROR,
10888 "errorCode,Failed to get address");
10889 return 0;
10890 }
10891 snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x",
10892 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
10893 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10894 return 0;
10895 #else /* __linux__ */
10896 send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_get_mac_address not "
10897 "yet supported");
10898 return 0;
10899 #endif /* __linux__ */
10900 }
10901
10902
sta_cfon_get_mac_address(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10903 int sta_cfon_get_mac_address(struct sigma_dut *dut, struct sigma_conn *conn,
10904 struct sigma_cmd *cmd)
10905 {
10906 return cmd_ap_get_mac_address(dut, conn, cmd);
10907 }
10908
10909
cmd_ap_set_pmf(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10910 static enum sigma_cmd_result cmd_ap_set_pmf(struct sigma_dut *dut,
10911 struct sigma_conn *conn,
10912 struct sigma_cmd *cmd)
10913 {
10914 /*
10915 * Ignore the command since the parameters are already handled through
10916 * ap_set_security.
10917 */
10918
10919 return 1;
10920 }
10921
10922
cmd_ap_set_hs2(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)10923 static enum sigma_cmd_result cmd_ap_set_hs2(struct sigma_dut *dut,
10924 struct sigma_conn *conn,
10925 struct sigma_cmd *cmd)
10926 {
10927 /* const char *name = get_param(cmd, "NAME"); */
10928 /* const char *ifname = get_param(cmd, "INTERFACE"); */
10929 const char *val, *dest;
10930 char *pos, buf[100];
10931 int i, wlan_tag = 1, res;
10932
10933 sigma_dut_print(dut, DUT_MSG_INFO, "ap_set_hs2: Processing the "
10934 "following parameters");
10935 for (i = 0; i < cmd->count; i++) {
10936 sigma_dut_print(dut, DUT_MSG_INFO, "%s %s", cmd->params[i],
10937 (cmd->values[i] ? cmd->values[i] : "NULL"));
10938 }
10939
10940 val = get_param(cmd, "ICMPv4_ECHO");
10941 if (val && atoi(val)) {
10942 snprintf(buf, sizeof(buf), "ebtables -F");
10943 if (system(buf) != 0) {
10944 sigma_dut_print(dut, DUT_MSG_ERROR,
10945 "Failed to set ebtables rules, RULE-12");
10946 }
10947 return 1;
10948 }
10949
10950 val = get_param(cmd, "WLAN_TAG");
10951 if (val) {
10952 wlan_tag = atoi(val);
10953 if (wlan_tag != 1 && wlan_tag != 2) {
10954 send_resp(dut, conn, SIGMA_INVALID,
10955 "errorCode,Invalid WLAN_TAG");
10956 return 0;
10957 }
10958 }
10959
10960 if (wlan_tag == 2) {
10961 val = get_param(cmd, "PROXY_ARP");
10962 if (val)
10963 dut->ap2_proxy_arp = atoi(val);
10964
10965 val = get_param(cmd, "OSU");
10966 if (val)
10967 dut->ap2_osu = atoi(val);
10968 return 1;
10969 }
10970
10971 dest = get_param(cmd, "STA_MAC");
10972 if (dest) {
10973 /* This is a special/ugly way of using this command.
10974 * If "Dest" MAC is included, assume that this command
10975 * is being issued after ap_config_commit for dynamically
10976 * setting the QoS Map Set.
10977 */
10978 val = get_param(cmd, "QoS_MAP_SET");
10979 if (val) {
10980 dut->ap_qos_map_set = atoi(val);
10981 sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
10982 dut->ap_qos_map_set);
10983 }
10984
10985 if (dut->ap_qos_map_set == 1)
10986 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1);
10987 else if (dut->ap_qos_map_set == 2)
10988 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2);
10989
10990 snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest);
10991 if (run_hostapd_cli(dut, buf) != 0)
10992 return -1;
10993 }
10994
10995 val = get_param(cmd, "DGAF_DISABLE");
10996 if (val)
10997 dut->ap_dgaf_disable = atoi(val);
10998
10999 dut->ap_interworking = 1;
11000
11001 val = get_param(cmd, "INTERWORKING");
11002 if (val == NULL)
11003 val = get_param(cmd, "INTERNETWORKING");
11004 if (val != NULL && atoi(val) == 0) {
11005 dut->ap_interworking = 0;
11006 dut->ap_hs2 = 0;
11007 return 1;
11008 }
11009
11010 val = get_param(cmd, "ACCS_NET_TYPE");
11011 if (val) {
11012 if (strcasecmp(val, "Chargeable_Public_Network") == 0 ||
11013 strcasecmp(val, "Chargable_Public_Network") == 0 ||
11014 strcasecmp(val, "Chargable Public Network") == 0)
11015 dut->ap_access_net_type = 2;
11016 else
11017 dut->ap_access_net_type = atoi(val);
11018 }
11019
11020 val = get_param(cmd, "INTERNET");
11021 if (val)
11022 dut->ap_internet = atoi(val);
11023
11024 val = get_param(cmd, "VENUE_GRP");
11025 if (val) {
11026 if (strcasecmp(val, "Business") == 0)
11027 dut->ap_venue_group = 2;
11028 else
11029 dut->ap_venue_group = atoi(val);
11030 sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d",
11031 dut->ap_venue_name);
11032 }
11033
11034 val = get_param(cmd, "VENUE_TYPE");
11035 if (val) {
11036 if (strcasecmp(val, "R&D") == 0)
11037 dut->ap_venue_type = 8;
11038 else
11039 dut->ap_venue_type = atoi(val);
11040 sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_type %d",
11041 dut->ap_venue_type);
11042 }
11043
11044 val = get_param(cmd, "HESSID");
11045 if (val) {
11046 if (strlen(val) >= sizeof(dut->ap_hessid)) {
11047 send_resp(dut, conn, SIGMA_ERROR,
11048 "errorCode,Invalid HESSID");
11049 return 0;
11050 }
11051 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), "%s", val);
11052 sigma_dut_print(dut, DUT_MSG_INFO, "ap_hessid %s",
11053 dut->ap_hessid);
11054 }
11055
11056 val = get_param(cmd, "ROAMING_CONS");
11057 if (val) {
11058 if (strlen(val) >= sizeof(dut->ap_roaming_cons)) {
11059 send_resp(dut, conn, SIGMA_ERROR,
11060 "errorCode,Invalid ROAMING_CONS");
11061 return 0;
11062 }
11063 if (strcasecmp(val, "Disabled") == 0) {
11064 dut->ap_roaming_cons[0] = '\0';
11065 } else {
11066 snprintf(dut->ap_roaming_cons,
11067 sizeof(dut->ap_roaming_cons), "%s", val);
11068 }
11069 sigma_dut_print(dut, DUT_MSG_INFO, "ap_roaming_cons %s",
11070 dut->ap_roaming_cons);
11071 }
11072
11073 val = get_param(cmd, "ANQP");
11074 if (val)
11075 dut->ap_anqpserver_on = atoi(val);
11076
11077 val = get_param(cmd, "NAI_REALM_LIST");
11078 if (val) {
11079 dut->ap_nai_realm_list = atoi(val);
11080 sigma_dut_print(dut, DUT_MSG_INFO, "ap_nai_realm_list %d",
11081 dut->ap_nai_realm_list);
11082 }
11083
11084 val = get_param(cmd, "3GPP_INFO");
11085 if (val) {
11086 /* What kind of encoding format is used?! */
11087 send_resp(dut, conn, SIGMA_ERROR, "errorCode,3GPP_INFO "
11088 "not yet supported (contents not fully defined)");
11089 return 0;
11090 }
11091
11092 val = get_param(cmd, "DOMAIN_LIST");
11093 if (val) {
11094 if (strlen(val) >= sizeof(dut->ap_domain_name_list)) {
11095 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Too long "
11096 "DOMAIN_LIST");
11097 return 0;
11098 }
11099 snprintf(dut->ap_domain_name_list,
11100 sizeof(dut->ap_domain_name_list), "%s", val);
11101 pos = dut->ap_domain_name_list;
11102 while (*pos) {
11103 if (*pos == ';')
11104 *pos = ',';
11105 pos++;
11106 }
11107 sigma_dut_print(dut, DUT_MSG_INFO, "ap_domain_name_list %s",
11108 dut->ap_domain_name_list);
11109 }
11110
11111 val = get_param(cmd, "OPER_NAME");
11112 if (val) {
11113 dut->ap_oper_name = atoi(val);
11114 sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_name %d",
11115 dut->ap_oper_name);
11116 }
11117
11118 val = get_param(cmd, "VENUE_NAME");
11119 if (val) {
11120 dut->ap_venue_name = atoi(val);
11121 sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d",
11122 dut->ap_venue_name);
11123 }
11124
11125 val = get_param(cmd, "GAS_CB_DELAY");
11126 if (val) {
11127 dut->ap_gas_cb_delay = atoi(val);
11128 sigma_dut_print(dut, DUT_MSG_INFO, "ap_gas_cb_delay %d",
11129 dut->ap_gas_cb_delay);
11130 }
11131
11132 val = get_param(cmd, "MIH");
11133 if (val && atoi(val) > 0) {
11134 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MIH not "
11135 "supported");
11136 return 0;
11137 }
11138
11139 val = get_param(cmd, "L2_TRAFFIC_INSPECT");
11140 if (val) {
11141 dut->ap_l2tif = atoi(val);
11142 sigma_dut_print(dut, DUT_MSG_INFO, "ap_l2tif %d",
11143 dut->ap_l2tif);
11144 }
11145
11146 val = get_param(cmd, "BCST_UNCST");
11147 if (val) {
11148 send_resp(dut, conn, SIGMA_ERROR,
11149 "errorCode,BCST_UNCST not yet supported");
11150 return 0;
11151 }
11152
11153 val = get_param(cmd, "PLMN_MCC");
11154 if (val) {
11155 char mcc[100], *start, *end;
11156 int i = 0;
11157 if (strlen(val) >= sizeof(mcc)) {
11158 send_resp(dut, conn, SIGMA_ERROR,
11159 "errorCode,PLMN_MCC too long");
11160 return 0;
11161 }
11162 strlcpy(mcc, val, sizeof(mcc));
11163 start = mcc;
11164 while ((end = strchr(start, ';'))) {
11165 /* process all except the last */
11166 *end = '\0';
11167 if (strlen(start) != 3) {
11168 send_resp(dut, conn, SIGMA_ERROR,
11169 "errorCode,Invalid PLMN_MCC");
11170 return 0;
11171 }
11172 res = snprintf(dut->ap_plmn_mcc[i],
11173 sizeof(dut->ap_plmn_mcc[i]), "%s",
11174 start);
11175 if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i]))
11176 return ERROR_SEND_STATUS;
11177 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s",
11178 dut->ap_plmn_mcc[i]);
11179 i++;
11180 start = end + 1;
11181 *end = ';';
11182 }
11183 if (strlen(start) != 3) {
11184 send_resp(dut, conn, SIGMA_ERROR,
11185 "errorCode,Invalid PLMN_MCC");
11186 return 0;
11187 }
11188 /* process last or only one */
11189 res = snprintf(dut->ap_plmn_mcc[i],
11190 sizeof(dut->ap_plmn_mcc[i]), "%s", start);
11191 if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i]))
11192 return ERROR_SEND_STATUS;
11193 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s",
11194 dut->ap_plmn_mcc[i]);
11195 }
11196
11197 val = get_param(cmd, "PLMN_MNC");
11198 if (val) {
11199 char mnc[100], *start, *end;
11200 int i = 0;
11201 if (strlen(val) >= sizeof(mnc)) {
11202 send_resp(dut, conn, SIGMA_ERROR,
11203 "errorCode,PLMN_MNC too long");
11204 return 0;
11205 }
11206 strlcpy(mnc, val, sizeof(mnc));
11207 start = mnc;
11208 while ((end = strchr(start, ';'))) {
11209 *end = '\0';
11210 if (strlen(start) != 2 && strlen(start) != 3) {
11211 send_resp(dut, conn, SIGMA_ERROR,
11212 "errorCode,Invalid PLMN_MNC");
11213 return 0;
11214 }
11215 res = snprintf(dut->ap_plmn_mnc[i],
11216 sizeof(dut->ap_plmn_mnc[i]), "%s",
11217 start);
11218 if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i]))
11219 return ERROR_SEND_STATUS;
11220 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s",
11221 dut->ap_plmn_mnc[i]);
11222 i++;
11223 start = end + 1;
11224 *end = ';';
11225 }
11226 if (strlen(start) != 2 && strlen(start) != 3) {
11227 send_resp(dut, conn, SIGMA_ERROR,
11228 "errorCode,Invalid PLMN_MNC");
11229 return 0;
11230 }
11231 res = snprintf(dut->ap_plmn_mnc[i],
11232 sizeof(dut->ap_plmn_mnc[i]), "%s", start);
11233 if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i]))
11234 return ERROR_SEND_STATUS;
11235 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s",
11236 dut->ap_plmn_mnc[i]);
11237 }
11238
11239 val = get_param(cmd, "PROXY_ARP");
11240 if (val) {
11241 dut->ap_proxy_arp = atoi(val);
11242 sigma_dut_print(dut, DUT_MSG_INFO, "ap_proxy_arp %d",
11243 dut->ap_proxy_arp);
11244 }
11245
11246 val = get_param(cmd, "WAN_METRICS");
11247 if (val) {
11248 dut->ap_wan_metrics = atoi(val);
11249 sigma_dut_print(dut, DUT_MSG_INFO, "ap_wan_metrics %d",
11250 dut->ap_wan_metrics);
11251 }
11252
11253 val = get_param(cmd, "CONN_CAP");
11254 if (val) {
11255 dut->ap_conn_capab = atoi(val);
11256 sigma_dut_print(dut, DUT_MSG_INFO, "ap_conn_capab %d",
11257 dut->ap_conn_capab);
11258 }
11259
11260 val = get_param(cmd, "IP_ADD_TYPE_AVAIL");
11261 if (val) {
11262 dut->ap_ip_addr_type_avail = atoi(val);
11263 sigma_dut_print(dut, DUT_MSG_INFO, "ap_ip_addr_type_avail %d",
11264 dut->ap_ip_addr_type_avail);
11265 }
11266
11267 val = get_param(cmd, "NET_AUTH_TYPE");
11268 if (val) {
11269 dut->ap_net_auth_type = atoi(val);
11270 sigma_dut_print(dut, DUT_MSG_INFO, "ap_net_auth_type %d",
11271 dut->ap_net_auth_type);
11272 }
11273
11274 val = get_param(cmd, "OP_CLASS");
11275 if (val == NULL)
11276 val = get_param(cmd, "OPER_CLASS");
11277 if (val) {
11278 dut->ap_oper_class = atoi(val);
11279 sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_class %d",
11280 dut->ap_oper_class);
11281 }
11282
11283 val = get_param(cmd, "OSU_PROVIDER_LIST");
11284 if (val) {
11285 dut->ap_osu_provider_list = atoi(val);
11286 sigma_dut_print(dut, DUT_MSG_INFO, "ap_osu_provider_list %d",
11287 dut->ap_osu_provider_list);
11288 }
11289
11290 val = get_param(cmd, "OSU_PROVIDER_NAI_LIST");
11291 if (val) {
11292 dut->ap_osu_provider_nai_list = atoi(val);
11293 sigma_dut_print(dut, DUT_MSG_INFO,
11294 "ap_osu_provider_nai_list %d",
11295 dut->ap_osu_provider_nai_list);
11296 }
11297
11298 val = get_param(cmd, "OSU_SERVER_URI");
11299 if (val) {
11300 i = 0;
11301 do {
11302 int len;
11303 const char *uri = val;
11304 val = strchr(val, ' ');
11305 len = val ? (val++ - uri) : (int) strlen(uri);
11306 if (len > 0 && len < 256) {
11307 memcpy(dut->ap_osu_server_uri[i], uri, len);
11308 dut->ap_osu_server_uri[i][len] = '\0';
11309 sigma_dut_print(dut, DUT_MSG_INFO,
11310 "ap_osu_server_uri[%d] %s", i,
11311 dut->ap_osu_server_uri[i]);
11312 }
11313 } while (val && ++i < 10);
11314 }
11315
11316 val = get_param(cmd, "OSU_METHOD");
11317 if (val) {
11318 i = 0;
11319 do {
11320 int len;
11321 const char *method = val;
11322 val = strchr(val, ' ');
11323 len = val ? (val++ - method) : (int) strlen(method);
11324 if (len > 0) {
11325 if (strncasecmp(method, "SOAP", len) == 0)
11326 dut->ap_osu_method[i] = 1;
11327 else if (strncasecmp(method, "OMADM", len) == 0)
11328 dut->ap_osu_method[i] = 0;
11329 else
11330 return -2;
11331 }
11332 } while (val && ++i < 10);
11333 }
11334
11335 val = get_param(cmd, "OSU_SSID");
11336 if (val) {
11337 if (strlen(val) > 0 && strlen(val) <= 32) {
11338 strlcpy(dut->ap_osu_ssid, val,
11339 sizeof(dut->ap_osu_ssid));
11340 sigma_dut_print(dut, DUT_MSG_INFO,
11341 "ap_osu_ssid %s",
11342 dut->ap_osu_ssid);
11343 }
11344 }
11345
11346 val = get_param(cmd, "OSU_ICON_TAG");
11347 if (val)
11348 dut->ap_osu_icon_tag = atoi(val);
11349
11350 val = get_param(cmd, "QoS_MAP_SET");
11351 if (val) {
11352 dut->ap_qos_map_set = atoi(val);
11353 sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d",
11354 dut->ap_qos_map_set);
11355 }
11356
11357 val = get_param(cmd, "BSS_LOAD");
11358 if (val) {
11359 dut->ap_bss_load = atoi(val);
11360 sigma_dut_print(dut, DUT_MSG_INFO, "ap_bss_load %d",
11361 dut->ap_bss_load);
11362 }
11363
11364 val = get_param(cmd, "Venue_URL");
11365 if (val)
11366 dut->ap_venue_url = atoi(val);
11367
11368 val = get_param(cmd, "Advice_of_Charge");
11369 if (val)
11370 dut->ap_advice_of_charge = atoi(val);
11371
11372 val = get_param(cmd, "Operator_Icon_Metadata");
11373 if (val)
11374 dut->ap_oper_icon_metadata = atoi(val);
11375
11376 val = get_param(cmd, "TnC_File_Name");
11377 if (val)
11378 dut->ap_tnc_file_name = atoi(val);
11379
11380 val = get_param(cmd, "TnC_File_Time_Stamp");
11381 if (val)
11382 dut->ap_tnc_time_stamp = strtol(val, NULL, 10);
11383
11384 return 1;
11385 }
11386
11387
nfc_status(struct sigma_dut * dut,const char * state,const char * oper)11388 void nfc_status(struct sigma_dut *dut, const char *state, const char *oper)
11389 {
11390 char buf[100];
11391
11392 if (!file_exists("nfc-status"))
11393 return;
11394
11395 snprintf(buf, sizeof(buf), "./nfc-status %s %s", state, oper);
11396 run_system(dut, buf);
11397 }
11398
11399
run_nfc_command(struct sigma_dut * dut,const char * cmd,const char * info)11400 static int run_nfc_command(struct sigma_dut *dut, const char *cmd,
11401 const char *info)
11402 {
11403 int res;
11404
11405 printf("\n\n\n=====[ NFC operation ]=========================\n\n");
11406 printf("%s\n\n", info);
11407
11408 nfc_status(dut, "START", info);
11409 res = run_system(dut, cmd);
11410 nfc_status(dut, res ? "FAIL" : "SUCCESS", info);
11411 if (res) {
11412 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s': %d",
11413 cmd, res);
11414 return res;
11415 }
11416
11417 return 0;
11418 }
11419
11420
ap_nfc_write_config_token(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11421 static int ap_nfc_write_config_token(struct sigma_dut *dut,
11422 struct sigma_conn *conn,
11423 struct sigma_cmd *cmd)
11424 {
11425 int res;
11426 char buf[300];
11427
11428 run_system(dut, "killall wps-ap-nfc.py");
11429 unlink("nfc-success");
11430 snprintf(buf, sizeof(buf),
11431 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-config",
11432 dut->summary_log ? "--summary " : "",
11433 dut->summary_log ? dut->summary_log : "");
11434 res = run_nfc_command(dut, buf,
11435 "Touch NFC Tag to write WPS configuration token");
11436 if (res || !file_exists("nfc-success")) {
11437 send_resp(dut, conn, SIGMA_ERROR,
11438 "ErrorCode,Failed to write tag");
11439 return 0;
11440 }
11441
11442 return 1;
11443 }
11444
11445
ap_nfc_wps_read_passwd(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11446 static int ap_nfc_wps_read_passwd(struct sigma_dut *dut,
11447 struct sigma_conn *conn,
11448 struct sigma_cmd *cmd)
11449 {
11450 int res;
11451 char buf[300];
11452
11453 run_system(dut, "killall wps-ap-nfc.py");
11454
11455 unlink("nfc-success");
11456 snprintf(buf, sizeof(buf),
11457 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success",
11458 dut->summary_log ? "--summary " : "",
11459 dut->summary_log ? dut->summary_log : "");
11460 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
11461 if (res || !file_exists("nfc-success")) {
11462 send_resp(dut, conn, SIGMA_ERROR,
11463 "ErrorCode,Failed to read tag");
11464 return 0;
11465 }
11466
11467 return 1;
11468 }
11469
11470
ap_nfc_write_password_token(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11471 static int ap_nfc_write_password_token(struct sigma_dut *dut,
11472 struct sigma_conn *conn,
11473 struct sigma_cmd *cmd)
11474 {
11475 int res;
11476 char buf[300];
11477
11478 run_system(dut, "killall wps-ap-nfc.py");
11479 unlink("nfc-success");
11480 snprintf(buf, sizeof(buf),
11481 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-password",
11482 dut->summary_log ? "--summary " : "",
11483 dut->summary_log ? dut->summary_log : "");
11484 res = run_nfc_command(dut, buf,
11485 "Touch NFC Tag to write WPS password token");
11486 if (res || !file_exists("nfc-success")) {
11487 send_resp(dut, conn, SIGMA_ERROR,
11488 "ErrorCode,Failed to write tag");
11489 return 0;
11490 }
11491
11492 if (run_hostapd_cli(dut, "wps_nfc_token enable") != 0) {
11493 send_resp(dut, conn, SIGMA_ERROR,
11494 "ErrorCode,Failed to enable NFC password token");
11495 return 0;
11496 }
11497
11498 return 1;
11499 }
11500
11501
ap_nfc_wps_connection_handover(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11502 static int ap_nfc_wps_connection_handover(struct sigma_dut *dut,
11503 struct sigma_conn *conn,
11504 struct sigma_cmd *cmd)
11505 {
11506 int res;
11507 char buf[300];
11508
11509 run_system(dut, "killall wps-ap-nfc.py");
11510 unlink("nfc-success");
11511 snprintf(buf, sizeof(buf),
11512 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success",
11513 dut->summary_log ? "--summary " : "",
11514 dut->summary_log ? dut->summary_log : "");
11515 res = run_nfc_command(dut, buf,
11516 "Touch NFC Device to respond to WPS connection handover");
11517 if (res) {
11518 send_resp(dut, conn, SIGMA_ERROR,
11519 "ErrorCode,Failed to enable NFC for connection "
11520 "handover");
11521 return 0;
11522 }
11523 if (!file_exists("nfc-success")) {
11524 send_resp(dut, conn, SIGMA_ERROR,
11525 "ErrorCode,Failed to complete NFC connection handover");
11526 return 0;
11527 }
11528
11529 return 1;
11530 }
11531
11532
cmd_ap_nfc_action(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11533 static enum sigma_cmd_result cmd_ap_nfc_action(struct sigma_dut *dut,
11534 struct sigma_conn *conn,
11535 struct sigma_cmd *cmd)
11536 {
11537 /* const char *name = get_param(cmd, "Name"); */
11538 /* const char *intf = get_param(cmd, "Interface"); */
11539 const char *oper = get_param(cmd, "Operation");
11540
11541 if (oper == NULL)
11542 return -1;
11543
11544 if (strcasecmp(oper, "WRITE_CONFIG") == 0)
11545 return ap_nfc_write_config_token(dut, conn, cmd);
11546 if (strcasecmp(oper, "WRITE_PASSWD") == 0)
11547 return ap_nfc_write_password_token(dut, conn, cmd);
11548 if (strcasecmp(oper, "WPS_READ_PASSWD") == 0)
11549 return ap_nfc_wps_read_passwd(dut, conn, cmd);
11550 if (strcasecmp(oper, "WPS_CONN_HNDOVR") == 0)
11551 return ap_nfc_wps_connection_handover(dut, conn, cmd);
11552
11553 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported operation");
11554 return 0;
11555 }
11556
11557
cmd_ap_wps_read_pin(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11558 static enum sigma_cmd_result cmd_ap_wps_read_pin(struct sigma_dut *dut,
11559 struct sigma_conn *conn,
11560 struct sigma_cmd *cmd)
11561 {
11562 char *pin = "12345670"; /* TODO: use random PIN */
11563 char resp[100];
11564
11565 snprintf(resp, sizeof(resp), "PIN,%s", pin);
11566 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11567
11568 return 0;
11569 }
11570
11571
cmd_ap_wps_enter_pin(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11572 static enum sigma_cmd_result cmd_ap_wps_enter_pin(struct sigma_dut *dut,
11573 struct sigma_conn *conn,
11574 struct sigma_cmd *cmd)
11575 {
11576 const char *pin = get_param(cmd, "PIN");
11577 char wps_pin[11];
11578
11579 if (!pin)
11580 return -1;
11581
11582 sigma_dut_print(dut, DUT_MSG_DEBUG,
11583 "Authorize a client to join with WPS PIN %s", pin);
11584
11585 strlcpy(wps_pin, pin, sizeof(wps_pin));
11586 /* we need to tolerate extra '-' characters entered */
11587 str_remove_chars(wps_pin, '-');
11588 strlcpy(dut->wps_pin, wps_pin, sizeof(dut->wps_pin));
11589 dut->wps_method = WFA_CS_WPS_PIN_KEYPAD;
11590
11591 return 1;
11592 }
11593
11594
cmd_ap_wps_set_pbc(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11595 static enum sigma_cmd_result cmd_ap_wps_set_pbc(struct sigma_dut *dut,
11596 struct sigma_conn *conn,
11597 struct sigma_cmd *cmd)
11598 {
11599 sigma_dut_print(dut, DUT_MSG_DEBUG,
11600 "Selecting the push button configuration method");
11601
11602 dut->wps_method = WFA_CS_WPS_PBC;
11603
11604 return 1;
11605 }
11606
11607
ap_wps_registration(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11608 int ap_wps_registration(struct sigma_dut *dut, struct sigma_conn *conn,
11609 struct sigma_cmd *cmd)
11610 {
11611 char buf[100], resp[256];
11612 const char *intf = get_param(cmd, "interface");
11613 const char *config_method = get_param(cmd, "WPSConfigMethod");
11614
11615 if (config_method && strcasecmp(config_method, "PBC") == 0)
11616 dut->wps_method = WFA_CS_WPS_PBC;
11617
11618 if (!intf)
11619 intf = get_main_ifname(dut);
11620
11621 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
11622 send_resp(dut, conn, SIGMA_ERROR,
11623 "ErrorCode,WPS parameters not yet set");
11624 return STATUS_SENT;
11625 }
11626
11627 if (dut->wps_method == WFA_CS_WPS_PBC)
11628 snprintf(buf, sizeof(buf), "WPS_PBC");
11629 else /* WFA_CS_WPS_PIN_KEYPAD */
11630 snprintf(buf, sizeof(buf), "WPS_PIN any %s", dut->wps_pin);
11631
11632 /* Run WPS command */
11633 if (hapd_command(intf, buf) < 0) {
11634 /* command fails immediately if overlapped session detected */
11635 snprintf(resp, sizeof(resp), "WpsState,OverlapSession");
11636 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11637 return STATUS_SENT;
11638 }
11639
11640 /* In AP mode return immediately and do not wait for WPS registration */
11641 return SUCCESS_SEND_STATUS;
11642 }
11643
11644
cmd_ap_get_parameter(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)11645 static enum sigma_cmd_result cmd_ap_get_parameter(struct sigma_dut *dut,
11646 struct sigma_conn *conn,
11647 struct sigma_cmd *cmd)
11648 {
11649 char value[256], resp[512];
11650 const char *param = get_param(cmd, "parameter");
11651 const char *ifname = get_param(cmd, "Interface");
11652 const char *var;
11653
11654 if (!ifname)
11655 ifname = get_main_ifname(dut);
11656
11657 if (!param) {
11658 send_resp(dut, conn, SIGMA_ERROR,
11659 "ErrorCode,Parameter not specified");
11660 return 0;
11661 }
11662
11663 if (strcasecmp(param, "SSID") == 0) {
11664 if (get_hapd_config(ifname, "ssid", value, sizeof(value))) {
11665 sigma_dut_print(dut, DUT_MSG_ERROR,
11666 "Failed to get SSID");
11667 return -2;
11668 }
11669 snprintf(resp, sizeof(resp), "SSID,%s", value);
11670 } else if (strcasecmp(param, "PSK") == 0) {
11671 if (get_hapd_config(ifname, "passphrase", value,
11672 sizeof(value))) {
11673 sigma_dut_print(dut, DUT_MSG_ERROR,
11674 "Failed to get PSK");
11675 return -2;
11676 }
11677 snprintf(resp, sizeof(resp), "PSK,%s", value);
11678 } else if (strcasecmp(param, "PMK") == 0) {
11679 var = get_param(cmd, "STA_MAC_Address");
11680 if (!var)
11681 return INVALID_SEND_STATUS;
11682 snprintf(resp, sizeof(resp), "GET_PMK %s", var);
11683 if (hapd_command_resp(ifname, resp, &resp[4],
11684 sizeof(resp) - 4) < 0) {
11685 send_resp(dut, conn, SIGMA_ERROR,
11686 "ErrorCode,GET_PMK failed");
11687 return STATUS_SENT_ERROR;
11688 }
11689 memcpy(resp, "PMK,", 4);
11690 } else {
11691 send_resp(dut, conn, SIGMA_ERROR,
11692 "ErrorCode,Unsupported parameter");
11693 return 0;
11694 }
11695
11696 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11697 return 0;
11698 }
11699
11700
ath_vht_op_mode_notif(struct sigma_dut * dut,const char * ifname,const char * val)11701 static int ath_vht_op_mode_notif(struct sigma_dut *dut, const char *ifname,
11702 const char *val)
11703 {
11704 char *token, *result;
11705 int nss = 0, chwidth = 0;
11706 char *saveptr;
11707
11708 /*
11709 * The following commands should be invoked to generate
11710 * VHT op mode notification
11711 */
11712
11713 /* Extract the NSS info */
11714 token = strdup(val);
11715 if (!token)
11716 return -1;
11717 result = strtok_r(token, ";", &saveptr);
11718 if (result) {
11719 int count = atoi(result);
11720
11721 /* We do not support NSS > 3 */
11722 if (count < 0 || count > 3) {
11723 free(token);
11724 return -1;
11725 }
11726
11727 /* Convert nss to chainmask */
11728 while (count--)
11729 nss = (nss << 1) | 1;
11730
11731 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
11732 }
11733
11734 /* Extract the Channel width info */
11735 result = strtok_r(NULL, ";", &saveptr);
11736 if (result) {
11737 switch (atoi(result)) {
11738 case 20:
11739 chwidth = 0;
11740 break;
11741 case 40:
11742 chwidth = 1;
11743 break;
11744 case 80:
11745 chwidth = 2;
11746 break;
11747 case 160:
11748 chwidth = 3;
11749 break;
11750 default:
11751 chwidth = 2;
11752 break;
11753 }
11754 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
11755 }
11756
11757 /* Send the opmode notification */
11758 run_iwpriv(dut, ifname, "opmode_notify 1");
11759 free(token);
11760
11761 return 0;
11762 }
11763
11764
ath_vht_nss_mcs(struct sigma_dut * dut,const char * ifname,const char * val)11765 static int ath_vht_nss_mcs(struct sigma_dut *dut, const char *ifname,
11766 const char *val)
11767 {
11768 /* String (nss_operating_mode; mcs_operating_mode) */
11769 int nss, mcs;
11770 char *token, *result;
11771 char *saveptr;
11772
11773 token = strdup(val);
11774 if (!token)
11775 return -1;
11776 result = strtok_r(token, ";", &saveptr);
11777 if (!result) {
11778 sigma_dut_print(dut, DUT_MSG_ERROR,
11779 "VHT NSS not specified");
11780 goto end;
11781 }
11782 if (strcasecmp(result, "def") != 0) {
11783 nss = atoi(result);
11784
11785 if (nss == 4)
11786 ath_disable_txbf(dut, ifname);
11787
11788 run_iwpriv(dut, ifname, "nss %d", nss);
11789 } else {
11790 if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1)
11791 run_iwpriv(dut, ifname, "nss 1");
11792 if (dut->device_type == AP_testbed &&
11793 dut->program == PROGRAM_HE) {
11794 nss = dut->ap_tx_streams;
11795 run_iwpriv(dut, ifname, "nss %d", nss);
11796 }
11797 }
11798
11799 result = strtok_r(NULL, ";", &saveptr);
11800 if (!result) {
11801 sigma_dut_print(dut, DUT_MSG_ERROR,
11802 "VHT MCS not specified");
11803 goto end;
11804 }
11805 if (strcasecmp(result, "def") == 0) {
11806 if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1)
11807 run_iwpriv(dut, ifname, "vhtmcs 7");
11808 else
11809 run_iwpriv(dut, ifname, "set11NRates 0");
11810 if (dut->device_type == AP_testbed &&
11811 dut->program == PROGRAM_HE)
11812 run_iwpriv(dut, ifname, "he_mcs 7");
11813 } else {
11814 mcs = atoi(result);
11815 if (dut->program == PROGRAM_HE)
11816 run_iwpriv(dut, ifname, "he_mcs %d", mcs);
11817 else
11818 run_iwpriv(dut, ifname, "vhtmcs %d", mcs);
11819 }
11820
11821 end:
11822 free(token);
11823 return 0;
11824 }
11825
11826
ath_vht_chnum_band(struct sigma_dut * dut,const char * ifname,const char * val)11827 static int ath_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
11828 const char *val)
11829 {
11830 char *token, *result;
11831 int channel = 36;
11832 int chwidth = 80;
11833 char *saveptr;
11834
11835 /* Extract the channel info */
11836 token = strdup(val);
11837 if (!token)
11838 return -1;
11839 result = strtok_r(token, ";", &saveptr);
11840 if (result)
11841 channel = atoi(result);
11842
11843 /* Extract the channel width info */
11844 result = strtok_r(NULL, ";", &saveptr);
11845 if (result)
11846 chwidth = atoi(result);
11847
11848 /* Issue the channel switch command */
11849 run_iwpriv(dut, ifname, "doth_ch_chwidth %d 10 %d", channel, chwidth);
11850
11851 free(token);
11852 return 0;
11853 }
11854
11855
ath_ndpa_stainfo_mac(struct sigma_dut * dut,const char * ifname,const char * val)11856 static int ath_ndpa_stainfo_mac(struct sigma_dut *dut, const char *ifname,
11857 const char *val)
11858 {
11859 char buf[80];
11860 unsigned char mac_addr[6];
11861
11862 if (parse_mac_address(dut, val, mac_addr) < 0)
11863 return -1;
11864
11865 snprintf(buf, sizeof(buf),
11866 "wifitool %s beeliner_fw_test 92 0x%02x%02x%02x%02x",
11867 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3]);
11868 run_system(dut, buf);
11869
11870 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 93 0x%02x%02x",
11871 ifname, mac_addr[4], mac_addr[5]);
11872 run_system(dut, buf);
11873
11874 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 94 1", ifname);
11875 run_system(dut, buf);
11876
11877 return 0;
11878 }
11879
11880
novap_reset(struct sigma_dut * dut,const char * ifname,int reset)11881 void novap_reset(struct sigma_dut *dut, const char *ifname, int reset)
11882 {
11883 run_iwpriv(dut, ifname, "novap_reset %d", reset);
11884 }
11885
11886
mbo_find_nebor_ap_entry(struct sigma_dut * dut,const uint8_t * mac_addr)11887 static struct mbo_pref_ap * mbo_find_nebor_ap_entry(struct sigma_dut *dut,
11888 const uint8_t *mac_addr)
11889 {
11890 int i;
11891
11892 for (i = 0; i < dut->mbo_pref_ap_cnt; i++) {
11893 if (memcmp(mac_addr, dut->mbo_pref_aps[i].mac_addr,
11894 ETH_ALEN) == 0)
11895 return &dut->mbo_pref_aps[i];
11896 }
11897 return NULL;
11898 }
11899
11900
mbo_add_nebor_entry(struct sigma_dut * dut,const uint8_t * mac_addr,int ap_ne_class,int ap_ne_op_ch,int ap_ne_pref)11901 static void mbo_add_nebor_entry(struct sigma_dut *dut, const uint8_t *mac_addr,
11902 int ap_ne_class, int ap_ne_op_ch,
11903 int ap_ne_pref)
11904 {
11905 struct mbo_pref_ap *entry;
11906 uint8_t self_mac[ETH_ALEN];
11907 char ifname[50];
11908
11909 get_if_name(dut, ifname, sizeof(ifname), 1);
11910 get_hwaddr(ifname, self_mac);
11911
11912 if (memcmp(mac_addr, self_mac, ETH_ALEN) == 0)
11913 entry = &dut->mbo_self_ap_tuple;
11914 else
11915 entry = mbo_find_nebor_ap_entry(dut, mac_addr);
11916
11917 if (!entry) {
11918 if (dut->mbo_pref_ap_cnt >= MBO_MAX_PREF_BSSIDS) {
11919 sigma_dut_print(dut, DUT_MSG_ERROR,
11920 "Nebor AP List is full. Not adding");
11921 return;
11922 }
11923 entry = &dut->mbo_pref_aps[dut->mbo_pref_ap_cnt];
11924 dut->mbo_pref_ap_cnt++;
11925 memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
11926 entry->ap_ne_class = -1;
11927 entry->ap_ne_op_ch = -1;
11928 entry->ap_ne_pref = -1;
11929 }
11930 if (ap_ne_class != -1)
11931 entry->ap_ne_class = ap_ne_class;
11932 if (ap_ne_op_ch != -1)
11933 entry->ap_ne_op_ch = ap_ne_op_ch;
11934 if (ap_ne_pref != -1)
11935 entry->ap_ne_pref = ap_ne_pref;
11936 }
11937
11938
ath_set_nebor_bssid(struct sigma_dut * dut,const char * ifname,struct sigma_cmd * cmd)11939 static int ath_set_nebor_bssid(struct sigma_dut *dut, const char *ifname,
11940 struct sigma_cmd *cmd)
11941 {
11942 unsigned char mac_addr[ETH_ALEN];
11943 const char *val;
11944 /*
11945 * -1 is invalid value for the following
11946 * to differentiate between unset and set values
11947 * -1 => implies not set by CAPI
11948 */
11949 int ap_ne_class = -1, ap_ne_op_ch = -1, ap_ne_pref = -1;
11950 int list_offset = dut->mbo_pref_ap_cnt;
11951
11952 if (list_offset >= MBO_MAX_PREF_BSSIDS) {
11953 sigma_dut_print(dut, DUT_MSG_ERROR,
11954 "AP Pref Entry list is full");
11955 return -1;
11956 }
11957
11958 val = get_param(cmd, "Nebor_Op_Class");
11959 if (val)
11960 ap_ne_class = atoi(val);
11961
11962 val = get_param(cmd, "Nebor_Op_Ch");
11963 if (val)
11964 ap_ne_op_ch = atoi(val);
11965
11966 val = get_param(cmd, "Nebor_Pref");
11967 if (val)
11968 ap_ne_pref = atoi(val);
11969
11970 val = get_param(cmd, "Nebor_BSSID");
11971 if (!val || parse_mac_address(dut, val, mac_addr) < 0)
11972 return -1;
11973
11974 mbo_add_nebor_entry(dut, mac_addr, ap_ne_class, ap_ne_op_ch,
11975 ap_ne_pref);
11976 apply_mbo_pref_ap_list(dut);
11977 return 0;
11978 }
11979
11980
he_ltf(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val)11981 static enum sigma_cmd_result he_ltf(struct sigma_dut *dut,
11982 struct sigma_conn *conn,
11983 const char *ifname, const char *val)
11984 {
11985 const char *var;
11986
11987 if (dut->ap_he_ulofdma == VALUE_ENABLED)
11988 var = "he_ul_ltf";
11989 else
11990 var = "he_ltf";
11991
11992 if (strcmp(val, "6.4") == 0) {
11993 run_iwpriv(dut, ifname, "%s 2", var);
11994 } else if (strcmp(val, "12.8") == 0) {
11995 run_iwpriv(dut, ifname, "%s 3", var);
11996 } else if (strcmp(val, "3.2") == 0) {
11997 run_iwpriv(dut, ifname, "%s 1", var);
11998 } else {
11999 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported LTF");
12000 return STATUS_SENT_ERROR;
12001 }
12002
12003 return SUCCESS_SEND_STATUS;
12004 }
12005
12006
he_shortgi(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val)12007 static enum sigma_cmd_result he_shortgi(struct sigma_dut *dut,
12008 struct sigma_conn *conn,
12009 const char *ifname,
12010 const char *val)
12011 {
12012 const char *var;
12013
12014 if (dut->ap_he_ulofdma == VALUE_ENABLED)
12015 var = "he_ul_shortgi";
12016 else
12017 var = "shortgi";
12018
12019 if (strcmp(val, "0.8") == 0) {
12020 run_iwpriv(dut, ifname, "%s 0", var);
12021 } else if (strcmp(val, "1.6") == 0) {
12022 run_iwpriv(dut, ifname, "%s 2", var);
12023 } else if (strcmp(val, "3.2") == 0) {
12024 run_iwpriv(dut, ifname, "%s 3", var);
12025 } else {
12026 send_resp(dut, conn, SIGMA_ERROR,
12027 "errorCode,Unsupported shortGI");
12028 return STATUS_SENT_ERROR;
12029 }
12030
12031 return SUCCESS_SEND_STATUS;
12032 }
12033
12034
he_ar_gi_ltf_mask(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val)12035 static enum sigma_cmd_result he_ar_gi_ltf_mask(struct sigma_dut *dut,
12036 struct sigma_conn *conn,
12037 const char *ifname,
12038 const char *val)
12039 {
12040
12041 uint32_t he_ar_gi_ltf;
12042 uint16_t he_ar_gi, he_ar_ltf;
12043
12044 if (strcmp(val, "0.4") == 0) {
12045 he_ar_gi = 0x01;
12046 } else if (strcmp(val, "0.8") == 0) {
12047 he_ar_gi = 0x02;
12048 } else if (strcmp(val, "1.6") == 0) {
12049 he_ar_gi = 0x04;
12050 } else if (strcmp(val, "3.2") == 0) {
12051 he_ar_gi = 0x08;
12052 } else {
12053 send_resp(dut, conn, SIGMA_ERROR,
12054 "errorCode,Unsupported shortGI");
12055 return STATUS_SENT_ERROR;
12056 }
12057
12058 if (dut->ar_ltf && strcmp(dut->ar_ltf, "6.4") == 0) {
12059 he_ar_ltf = 0x02;
12060 } else if (dut->ar_ltf && strcmp(dut->ar_ltf, "12.8") == 0) {
12061 he_ar_ltf = 0x04;
12062 } else if (dut->ar_ltf && strcmp(dut->ar_ltf, "3.2") == 0) {
12063 he_ar_ltf = 0x01;
12064 } else {
12065 send_resp(dut, conn, SIGMA_ERROR,
12066 "errorCode,Unsupported LTF");
12067 return STATUS_SENT_ERROR;
12068 }
12069
12070 he_ar_gi_ltf = (he_ar_gi << 8) | he_ar_ltf;
12071 run_iwpriv(dut, ifname, "he_ar_gi_ltf %lu", he_ar_gi_ltf);
12072
12073 return SUCCESS_SEND_STATUS;
12074 }
12075
12076
he_rualloctones(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val)12077 static enum sigma_cmd_result he_rualloctones(struct sigma_dut *dut,
12078 struct sigma_conn *conn,
12079 const char *ifname,
12080 const char *val)
12081 {
12082 char *token, *result;
12083 int value;
12084 char *saveptr;
12085 int rualloc_type;
12086 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
12087
12088 token = strdup(val);
12089 if (!token)
12090 return -1;
12091 result = strtok_r(token, ":", &saveptr);
12092 if (!result) {
12093 free(token);
12094 send_resp(dut, conn, SIGMA_ERROR,
12095 "errorCode,RUAllocTones not specified");
12096 return STATUS_SENT_ERROR;
12097 }
12098
12099 /*
12100 * ru_allocation_type can take the values of:
12101 * 1 - DL OFDMA data RU allocation
12102 * 3 - UL OFDMA data RU allocation
12103 */
12104 rualloc_type = dut->ap_he_ulofdma == VALUE_ENABLED ? 3 : 1;
12105
12106
12107 value = atoi(result);
12108 if (value == 106) {
12109 enum value_not_set_enabled_disabled ap_he_rualloc_106_80 =
12110 VALUE_NOT_SET;
12111
12112 result = strtok_r(NULL, ":", &saveptr);
12113 if (result) {
12114 result = strtok_r(NULL, ":", &saveptr);
12115 if (result)
12116 ap_he_rualloc_106_80 = VALUE_ENABLED;
12117 else
12118 ap_he_rualloc_106_80 = VALUE_DISABLED;
12119 }
12120 if (ap_he_rualloc_106_80 == VALUE_ENABLED) {
12121 run_system_wrapper(dut,
12122 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 2 1 2 2 2 3 2",
12123 ifname, rualloc_type);
12124 } else {
12125 run_system_wrapper(dut,
12126 "wifitool %s setUnitTestCmd 0x4b 5 %d 0 2 1 2",
12127 ifname, rualloc_type);
12128 }
12129 } else if (value == 242) {
12130 run_system_wrapper(
12131 dut,
12132 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 3 1 3 2 3 3 3",
12133 ifname, rualloc_type);
12134 } else if (value == 26) {
12135 run_system_wrapper(
12136 dut,
12137 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 0 2 0 5 0 7 0",
12138 ifname, rualloc_type);
12139 } else if (value == 52) {
12140 run_system_wrapper(
12141 dut,
12142 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 1 1 1 2 1 3 1",
12143 ifname, rualloc_type);
12144 } else if (value == 484) {
12145 run_system_wrapper(
12146 dut,
12147 "wifitool %s setUnitTestCmd 0x4b 5 %d 0 4 1 4",
12148 ifname, rualloc_type);
12149 } else if (value == 996) {
12150 run_system_wrapper(dut,
12151 "wifitool %s setUnitTestCmd 0x4b 3 %d 0 5",
12152 ifname, rualloc_type);
12153 } else {
12154 send_resp(dut, conn, SIGMA_ERROR,
12155 "errorCode,Unsupported RUAllocTones");
12156 ret = STATUS_SENT_ERROR;
12157 }
12158
12159 free(token);
12160 return ret;
12161 }
12162
12163
ath_set_trigger_type_0(struct sigma_dut * dut,const char * ifname)12164 static void ath_set_trigger_type_0(struct sigma_dut *dut, const char *ifname)
12165 {
12166 /* TriggerType "0" for Basic trigger */
12167 if (dut->ap_channel >= 36) {
12168 /* 1 and 2 here is interpreted to 5g and 2g (bitmasks) */
12169 run_system_wrapper(dut,
12170 "wifitool %s setUnitTestCmd 0x47 2 42 1",
12171 ifname);
12172 } else {
12173 run_system_wrapper(dut,
12174 "wifitool %s setUnitTestCmd 0x47 2 42 2",
12175 ifname);
12176 }
12177 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 6",
12178 ifname);
12179 }
12180
12181
ath_set_trigger_type_1(struct sigma_dut * dut,const char * ifname)12182 static void ath_set_trigger_type_1(struct sigma_dut *dut, const char *ifname)
12183 {
12184 /* TriggerType "1" for MU BRP */
12185 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 1",
12186 ifname);
12187 mubrp_commands(dut, ifname);
12188 }
12189
12190
ath_set_trigger_type_2(struct sigma_dut * dut,const char * ifname)12191 static void ath_set_trigger_type_2(struct sigma_dut *dut, const char *ifname)
12192 {
12193 /* TriggerType "2" for MU BAR */
12194 if (dut->ap_channel >= 36) {
12195 /* RU allocation RU 242 - DL OFDMA data */
12196 run_system_wrapper(dut,
12197 "wifitool %s setUnitTestCmd 0x4b 5 9 0 3 1 3 2 3 3 3",
12198 ifname);
12199 /* RU allocation RU 52 - UL BA */
12200 run_system_wrapper(dut,
12201 "wifitool %s setUnitTestCmd 0x4b 5 9 0 2 1 2 2 2 3 2",
12202 ifname);
12203 } else {
12204 /* RU allocation RU 52 - DL ofdma data */
12205 run_system_wrapper(dut,
12206 "wifitool %s setUnitTestCmd 0x4b 5 9 0 1 1 1 2 1 3 1",
12207 ifname);
12208 }
12209 /* Force TBPPDU duration to 400 us */
12210 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 400",
12211 ifname);
12212 /* 0 to enable MU BAR, 1 to enable SU BAR */
12213 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 49 0",
12214 ifname);
12215 /* MU BAR */
12216 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 64 0",
12217 ifname);
12218 }
12219
12220
ath_set_trigger_type_3(struct sigma_dut * dut,const char * ifname)12221 static void ath_set_trigger_type_3(struct sigma_dut *dut, const char *ifname)
12222 {
12223 /* TriggerType "3" for MU RTS */
12224 /* Send MU RTS Trigger - '1' is to enable MU RTS */
12225 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 101 1",
12226 ifname);
12227 }
12228
12229
ath_set_trigger_type_4(struct sigma_dut * dut,const char * ifname,const char * basedev)12230 static void ath_set_trigger_type_4(struct sigma_dut *dut, const char *ifname,
12231 const char *basedev)
12232 {
12233 /* TriggerType "4" for BSRP */
12234 run_system_wrapper(dut, "cfg80211tool %s he_ul_trig_int 200", basedev);
12235 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 1000",
12236 ifname);
12237 if (dut->ap_channel >= 36) {
12238 run_system_wrapper(dut,
12239 "wifitool %s setUnitTestCmd 0x47 2 42 1",
12240 ifname);
12241 } else {
12242 run_system_wrapper(dut,
12243 "wifitool %s setUnitTestCmd 0x47 2 42 2",
12244 ifname);
12245 }
12246 /* Send BSRP command */
12247 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 7",
12248 ifname);
12249 }
12250
12251
ath_ap_set_rfeature(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)12252 static enum sigma_cmd_result ath_ap_set_rfeature(struct sigma_dut *dut,
12253 struct sigma_conn *conn,
12254 struct sigma_cmd *cmd)
12255 {
12256 const char *val;
12257 const char *ifname;
12258 enum sigma_cmd_result res;
12259 const char *basedev = "wifi0";
12260 int trigtype;
12261 int he_ackpolicymac = 0;
12262 char *num_ss = NULL;
12263 char *nss[4] = { NULL, NULL, NULL, NULL };
12264 char *aid[4] = { NULL, NULL, NULL, NULL };
12265 char *aid_ss = NULL;
12266 int omctrl_rxnss = 0, omctrl_chwidth = 0;
12267 int param;
12268 unsigned char mac_addr[ETH_ALEN];
12269
12270 memset(mac_addr, 0x00, ETH_ALEN);
12271
12272 ifname = get_main_ifname(dut);
12273
12274 if (sigma_radio_ifname[0])
12275 basedev = sigma_radio_ifname[0];
12276
12277 /* Disable vap reset between the commands */
12278 novap_reset(dut, ifname, 1);
12279
12280 val = get_param(cmd, "Opt_md_notif_ie");
12281 if (val && ath_vht_op_mode_notif(dut, ifname, val) < 0)
12282 return ERROR_SEND_STATUS;
12283
12284 /* TODO: Optional arguments */
12285
12286 val = get_param(cmd, "nss_mcs_opt");
12287 if (val && ath_vht_nss_mcs(dut, ifname, val) < 0)
12288 return ERROR_SEND_STATUS;
12289
12290 val = get_param(cmd, "chnum_band");
12291 if (val && ath_vht_chnum_band(dut, ifname, val) < 0)
12292 return ERROR_SEND_STATUS;
12293
12294 val = get_param(cmd, "RTS_FORCE");
12295 if (val)
12296 ath_config_rts_force(dut, ifname, val);
12297
12298 val = get_param(cmd, "DYN_BW_SGNL");
12299 if (val)
12300 ath_config_dyn_bw_sig(dut, ifname, val);
12301
12302 val = get_param(cmd, "CTS_WIDTH");
12303 if (val)
12304 ath_set_cts_width(dut, ifname, val);
12305
12306 val = get_param(cmd, "Ndpa_stainfo_mac");
12307 if (val && ath_ndpa_stainfo_mac(dut, ifname, val) < 0)
12308 return ERROR_SEND_STATUS;
12309
12310 val = get_param(cmd, "txBandwidth");
12311 if (val && ath_set_width(dut, conn, ifname, val) < 0)
12312 return ERROR_SEND_STATUS;
12313
12314 val = get_param(cmd, "Assoc_Disallow");
12315 if (val)
12316 ath_set_assoc_disallow(dut, ifname, val);
12317
12318
12319 ath_set_nebor_bssid(dut, ifname, cmd);
12320 val = get_param(cmd, "BTMReq_DisAssoc_Imnt");
12321 if (val) {
12322 dut->ap_btmreq_disassoc_imnt = atoi(val);
12323 dut->ap_disassoc_timer = 1000;
12324 }
12325
12326 val = get_param(cmd, "BTMReq_Term_Bit");
12327 if (val)
12328 dut->ap_btmreq_term_bit = atoi(val);
12329
12330 val = get_param(cmd, "Assoc_Delay");
12331 if (val) {
12332 dut->ap_assoc_delay = 1;
12333 run_iwpriv(dut, ifname, "mbo_asoc_ret %s", val);
12334 }
12335
12336 val = get_param(cmd, "Disassoc_Timer");
12337 if (val)
12338 dut->ap_disassoc_timer = atoi(val);
12339
12340 val = get_param(cmd, "BSS_Term_Duration");
12341 if (val)
12342 dut->ap_btmreq_bss_term_dur = atoi(val);
12343
12344 val = get_param(cmd, "BSS_Term_TSF");
12345 if (val)
12346 dut->ap_btmreq_bss_term_tsf = atoi(val);
12347
12348 val = get_param(cmd, "TxPower");
12349 if (val)
12350 ath_set_txpower(dut, ifname, val);
12351
12352 val = get_param(cmd, "DownlinkAvailCap");
12353 if (val)
12354 dut->ap_dl_availcap = atoi(val);
12355
12356 val = get_param(cmd, "UplinkAvailCap");
12357 if (val) {
12358 dut->ap_ul_availcap = atoi(val);
12359 run_iwpriv(dut, ifname, "oce_wan_mtr %d %d",
12360 dut->ap_dl_availcap, dut->ap_ul_availcap);
12361 }
12362
12363 val = get_param(cmd, "RSSIthreshold");
12364 if (val) {
12365 int rssithreshold;
12366
12367 run_iwpriv(dut, ifname, "oce_asoc_rej 1");
12368 rssithreshold = atoi(val);
12369 run_iwpriv(dut, ifname, "oce_asoc_rssi %d", rssithreshold);
12370 }
12371
12372 val = get_param(cmd, "RetryDelay");
12373 if (val) {
12374 int retrydelay;
12375
12376 run_iwpriv(dut, ifname, "oce_asoc_rej 1");
12377 retrydelay = atoi(val);
12378 run_iwpriv(dut, ifname, "oce_asoc_dly %d", retrydelay);
12379 }
12380
12381 val = get_param(cmd, "LTF");
12382 if (val) {
12383 if (dut->ap_fixed_rate) {
12384 res = he_ltf(dut, conn, ifname, val);
12385 if (res != SUCCESS_SEND_STATUS)
12386 return res;
12387 } else {
12388 free(dut->ar_ltf);
12389 dut->ar_ltf = strdup(val);
12390 if (!dut->ar_ltf)
12391 return ERROR_SEND_STATUS;
12392 }
12393 }
12394
12395 val = get_param(cmd, "GI");
12396 if (val) {
12397 if (dut->ap_fixed_rate)
12398 res = he_shortgi(dut, conn, ifname, val);
12399 else
12400 res = he_ar_gi_ltf_mask(dut, conn, ifname, val);
12401 if (res != SUCCESS_SEND_STATUS)
12402 return res;
12403 }
12404
12405 val = get_param(cmd, "RUAllocTones");
12406 if (val) {
12407 res = he_rualloctones(dut, conn, ifname, val);
12408 if (res != SUCCESS_SEND_STATUS)
12409 return res;
12410 }
12411
12412 val = get_param(cmd, "MPDU_MU_SpacingFactor");
12413 if (val)
12414 run_system_wrapper(dut,
12415 "wifitool %s setUnitTestCmd 0x48 2 119, %s",
12416 ifname, val);
12417
12418 val = get_param(cmd, "PPDUTxType");
12419 if (val) {
12420 if (strcasecmp(val, "HE-SU") == 0) {
12421 /* Change PPDU format type to HE-SU MCS 1 */
12422 run_system_wrapper(dut,
12423 "wifitool %s setUnitTestCmd 0x48 2 89 0x401",
12424 ifname);
12425 } else if (strcasecmp(val, "legacy") == 0) {
12426 /* Change PPDU format type to non-HT */
12427 run_system_wrapper(dut,
12428 "wifitool %s setUnitTestCmd 0x48 2 89 3",
12429 ifname);
12430 } else {
12431 send_resp(dut, conn, SIGMA_ERROR,
12432 "errorCode,Unsupported PPDUTxType");
12433 return STATUS_SENT_ERROR;
12434 }
12435 }
12436
12437 val = get_param(cmd, "TXOPDuration");
12438 if (val) {
12439 if (strcasecmp(val, "UNSPECIFIED") == 0) {
12440 /* The hardware is hardcoded with 0x7f; do nothing */
12441 } else {
12442 send_resp(dut, conn, SIGMA_ERROR,
12443 "errorCode,Unsupported TXOPDuration");
12444 return STATUS_SENT_ERROR;
12445 }
12446 }
12447
12448 val = get_param(cmd, "Trig_Usrinfo_UL-MCS");
12449 if (val)
12450 run_iwpriv(dut, ifname, "he_ul_mcs %d", atoi(val));
12451
12452 val = get_param(cmd, "Trig_Usrinfo_UL-Target-RSSI");
12453 if (val) {
12454 /* Set target RSSI to -55 dBm */
12455 run_system_wrapper(dut,
12456 "wifitool %s setUnitTestCmd 0x4b 2 7 %d",
12457 ifname, atoi(val) - 110);
12458 }
12459
12460 val = get_param(cmd, "Trig_Interval");
12461 if (val)
12462 run_iwpriv(dut, basedev, "he_ul_trig_int %d", atoi(val));
12463
12464 val = get_param(cmd, "Trig_ComInfo_ULLength");
12465 if (val)
12466 run_system_wrapper(dut,
12467 "wifitool %s setUnitTestCmd 0x48 2 141 %d",
12468 ifname, atoi(val));
12469
12470 val = get_param(cmd, "DisableTriggerType");
12471 if (val) {
12472 trigtype = atoi(val);
12473 switch (trigtype) {
12474 case 0:
12475 /* DisableTriggerType "0" for basic trigger */
12476 run_system_wrapper(dut,
12477 "wifitool %s setUnitTestCmd 0x47 2 42 0",
12478 ifname);
12479 break;
12480 default:
12481 /* Nothing to be done for now */
12482 break;
12483 }
12484 }
12485
12486 val = get_param(cmd, "Trigger_TxBF");
12487 if (val) {
12488 if (strcasecmp(val, "enable") == 0) {
12489 run_iwpriv(dut, ifname, "he_sounding_mode 0x9");
12490 } else if (strcasecmp(val, "disable") == 0) {
12491 run_iwpriv(dut, ifname, "he_sounding_mode 0x1");
12492 } else {
12493 send_resp(dut, conn, SIGMA_ERROR,
12494 "errorCode,Unsupported trigger_txbf");
12495 return STATUS_SENT_ERROR;
12496 }
12497 }
12498
12499 val = get_param(cmd, "Trig_UsrInfo_RUAlloc");
12500 if (val) {
12501 res = he_rualloctones(dut, conn, ifname, val);
12502 if (res != SUCCESS_SEND_STATUS)
12503 return res;
12504 }
12505
12506 val = get_param(cmd, "TriggerCoding");
12507 if (val) {
12508 if (strcasecmp(val, "BCC") == 0) {
12509 /* In case of LDPC enable this command can force BCC if
12510 * RU size <= 242 */
12511 run_iwpriv(dut, ifname, "he_ul_ldpc 0");
12512 } else if (strcasecmp(val, "LDPC") == 0) {
12513 novap_reset(dut, ifname, 0);
12514 run_iwpriv(dut, ifname, "he_ul_ldpc 1");
12515 novap_reset(dut, ifname, 1);
12516 } else {
12517 send_resp(dut, conn, SIGMA_ERROR,
12518 "errorCode,Unsupported TriggerCoding");
12519 return STATUS_SENT_ERROR;
12520 }
12521 }
12522
12523 val = get_param(cmd, "AckPolicy_MAC");
12524 if (val) {
12525 if (parse_mac_address(dut, val, mac_addr) < 0) {
12526 send_resp(dut, conn, SIGMA_ERROR,
12527 "errorCode,MAC Address not in proper format");
12528 return STATUS_SENT_ERROR;
12529 }
12530 he_ackpolicymac = 1;
12531 }
12532
12533 val = get_param(cmd, "AckPolicy");
12534 if (val) {
12535 int ap_he_ackpolicy;
12536
12537 ap_he_ackpolicy = atoi(val);
12538 if (ap_he_ackpolicy == 0 && he_ackpolicymac) {
12539 /* Disable all-BAR ackpolicy for MU-MIMO */
12540 run_system_wrapper(dut,
12541 "wifitool %s setUnitTestCmd 0x48 2 62 0",
12542 ifname);
12543 /* Disable all-BAR ackpolicy first */
12544 run_system_wrapper(dut,
12545 "wifitool %s setUnitTestCmd 0x48 2 64 0",
12546 ifname);
12547 /* Set normal ack policy for the STA with the specified
12548 * MAC address in DL-TX case */
12549 run_system_wrapper(dut,
12550 "wifitool %s setUnitTestCmd 0x4b 8 8 1 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
12551 ifname, mac_addr[0], mac_addr[1],
12552 mac_addr[2], mac_addr[3],
12553 mac_addr[4], mac_addr[5]);
12554 } else if (ap_he_ackpolicy == 3) {
12555 /* Enable all-BAR ackpolicy for MU-MIMO DL */
12556 run_system_wrapper(dut,
12557 "wifitool %s setUnitTestCmd 0x48 2 62 1",
12558 ifname);
12559 /* Enable all-BAR ackpolicy */
12560 run_system_wrapper(dut,
12561 "wifitool %s setUnitTestCmd 0x48 2 64 1",
12562 ifname);
12563 } else if (ap_he_ackpolicy == 4) {
12564 /* Enable htp-ack ackpolicy */
12565 run_system_wrapper(dut,
12566 "wifitool %s setUnitTestCmd 0x47 2 99 1",
12567 ifname);
12568 } else {
12569 send_resp(dut, conn, SIGMA_ERROR,
12570 "errorCode,Invalid AckPolicy setting");
12571 return STATUS_SENT_ERROR;
12572 }
12573 }
12574
12575 val = get_param(cmd, "Trig_ComInfo_GI-LTF");
12576 if (val) {
12577 int trig_gi_ltf;
12578
12579 trig_gi_ltf = atoi(val);
12580 if (trig_gi_ltf == 0) {
12581 he_ltf(dut, conn, ifname, "3.2");
12582 he_shortgi(dut, conn, ifname, "1.6");
12583 } else if (trig_gi_ltf == 1) {
12584 he_ltf(dut, conn, ifname, "6.4");
12585 he_shortgi(dut, conn, ifname, "1.6");
12586 } else if (trig_gi_ltf == 2) {
12587 he_ltf(dut, conn, ifname, "12.8");
12588 he_shortgi(dut, conn, ifname, "3.2");
12589 } else {
12590 send_resp(dut, conn, SIGMA_ERROR,
12591 "errorCode,Unsupported Trig_ComInfo_GI-LTF");
12592 return STATUS_SENT_ERROR;
12593 }
12594 }
12595
12596 val = get_param(cmd, "Trig_ComInfo_BW");
12597 if (val) {
12598 int chwidth;
12599
12600 chwidth = atoi(val);
12601 /* Set the channel width */
12602 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
12603 }
12604
12605 val = get_param(cmd, "NumSS");
12606 if (val) {
12607 int i = 0;
12608 char *numss_val;
12609 char *saveptr;
12610
12611 num_ss = strdup(val);
12612 if (!num_ss)
12613 return ERROR_SEND_STATUS;
12614
12615 numss_val = strtok_r(num_ss, " ", &saveptr);
12616 for (i = 0; numss_val && i < 4; i++) {
12617 nss[i] = numss_val;
12618 numss_val = strtok_r(NULL, " ", &saveptr);
12619 }
12620 }
12621
12622 val = get_param(cmd, "NumSS_MAC");
12623 if (val) {
12624 char *sta_mac_str;
12625 char *saveptr;
12626 char *sta_mac_list_str;
12627
12628 sta_mac_list_str = strdup(val);
12629 if (!sta_mac_list_str) {
12630 free(num_ss);
12631 return ERROR_SEND_STATUS;
12632 }
12633
12634 sta_mac_str = strtok_r(sta_mac_list_str, " ", &saveptr);
12635 if (sta_mac_str && nss[0]) {
12636 run_system_wrapper(dut,
12637 "wifitool %s chmask_persta %s %s",
12638 ifname, sta_mac_str, nss[0]);
12639 }
12640
12641 sta_mac_str = strtok_r(NULL, " ", &saveptr);
12642 if (sta_mac_str && nss[1]) {
12643 run_system_wrapper(dut,
12644 "wifitool %s chmask_persta %s %s",
12645 ifname, sta_mac_str, nss[1]);
12646 }
12647
12648 sta_mac_str = strtok_r(NULL, " ", &saveptr);
12649 if (sta_mac_str && nss[2]) {
12650 run_system_wrapper(dut,
12651 "wifitool %s chmask_persta %s %s",
12652 ifname, sta_mac_str, nss[2]);
12653 }
12654
12655 sta_mac_str = strtok_r(NULL, " ", &saveptr);
12656 if (sta_mac_str && nss[3]) {
12657 run_system_wrapper(dut,
12658 "wifitool %s chmask_persta %s %s",
12659 ifname, sta_mac_str, nss[3]);
12660 }
12661
12662 free(sta_mac_list_str);
12663 }
12664
12665 free(num_ss);
12666 num_ss = NULL;
12667
12668 val = get_param(cmd, "AID");
12669 if (val) {
12670 int i = 0;
12671 char *aid_val;
12672 char *saveptr;
12673
12674 aid_ss = strdup(val);
12675 if (!aid_ss)
12676 return ERROR_SEND_STATUS;
12677
12678 aid_val = strtok_r(aid_ss, " ", &saveptr);
12679 for (i = 0; aid_val && i < 4; i++) {
12680 aid[i] = aid_val;
12681 aid_val = strtok_r(NULL, " ", &saveptr);
12682 }
12683 }
12684
12685 val = get_param(cmd, "AddbaReq");
12686 if (val) {
12687 if (strcasecmp(val, "enable") == 0) {
12688 run_iwpriv(dut, ifname, "setaddbaoper 1");
12689 run_system_wrapper(dut,
12690 "wifitool %s sendaddba %s 0 64",
12691 ifname, aid[0]);
12692 } else {
12693 send_resp(dut, conn, SIGMA_ERROR,
12694 "errorCode,Unsupported AddbaReq value");
12695 free(aid_ss);
12696 return STATUS_SENT_ERROR;
12697 }
12698 }
12699
12700 val = get_param(cmd, "AddbaResp");
12701 if (val) {
12702 if (aid_ss && strcasecmp(val, "accepted") == 0) {
12703 int aid_1 = atoi(aid_ss);
12704
12705 if (aid_1 == 1)
12706 aid_1 = 2;
12707 else
12708 aid_1 = aid_1 - 1;
12709
12710 /* There is no mechanism in place to reject Add BA Req
12711 * from all STAs and selectively accept Add BA Req from
12712 * a specified STA. Instead, it can accept Add BA Req
12713 * from all STAs and selectively reject from specified
12714 * STAs. Make changes for the same using the below
12715 * commands. */
12716 run_system_wrapper(dut, ifname, "setaddbaoper 1");
12717 run_system_wrapper(dut, "wifitool %s refusealladdbas 0",
12718 ifname);
12719 run_system_wrapper(dut,
12720 "wifitool %s setaddbaresp %d 0 37",
12721 ifname, aid_1);
12722 } else {
12723 send_resp(dut, conn, SIGMA_ERROR,
12724 "errorCode,Unsupported Addbaresp value");
12725 free(aid_ss);
12726 return STATUS_SENT_ERROR;
12727 }
12728 }
12729
12730 val = get_param(cmd, "Trig_UsrInfo_SSAlloc_RA-RU");
12731 if (val) {
12732 char *ssalloc_str;
12733 char *saveptr;
12734 char *ssalloc_list_str;
12735
12736 ssalloc_list_str = strdup(val);
12737 if (!ssalloc_list_str) {
12738 free(aid_ss);
12739 return ERROR_SEND_STATUS;
12740 }
12741
12742 ssalloc_str = strtok_r(ssalloc_list_str, ":", &saveptr);
12743 if (ssalloc_str && aid[0]) {
12744 run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12745 ifname, aid[0], ssalloc_str);
12746 }
12747
12748 ssalloc_str = strtok_r(NULL, " ", &saveptr);
12749 if (ssalloc_str && aid[1]) {
12750 run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12751 ifname, aid[1], ssalloc_str);
12752 }
12753
12754 ssalloc_str = strtok_r(NULL, " ", &saveptr);
12755 if (ssalloc_str && aid[2]) {
12756 run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12757 ifname, aid[2], ssalloc_str);
12758 }
12759
12760 ssalloc_str = strtok_r(NULL, " ", &saveptr);
12761 if (ssalloc_str && aid[3]) {
12762 run_system_wrapper(dut, "wifitool %s peer_nss %s %s",
12763 ifname, aid[3], ssalloc_str);
12764 }
12765
12766 free(ssalloc_list_str);
12767 }
12768
12769 free(aid_ss);
12770 aid_ss = NULL;
12771
12772 val = get_param(cmd, "OMCtrl_RxNSS");
12773 if (val)
12774 omctrl_rxnss = atoi(val);
12775
12776 val = get_param(cmd, "OMCtrl_ChnlWidth");
12777 if (val)
12778 omctrl_chwidth = atoi(val);
12779
12780 val = get_param(cmd, "Client_mac");
12781 if (val) {
12782 if (parse_mac_address(dut, val, mac_addr) < 0) {
12783 send_resp(dut, conn, SIGMA_ERROR,
12784 "errorCode,MAC Address not in proper format");
12785 return STATUS_SENT_ERROR;
12786 }
12787
12788 /* setUnitTestCmd 13 7 1 mac3mac2mac1mac0 mac5mac4 <rx_nss>
12789 * <bw> <ulmu> <tx_nss> */
12790 run_system_wrapper(dut,
12791 "wifitool %s setUnitTestCmd 13 7 1 0x%02x%02x%02x%02x 0x%02x%02x %d %d 1 %d",
12792 ifname, mac_addr[3], mac_addr[2],
12793 mac_addr[1], mac_addr[0], mac_addr[5],
12794 mac_addr[4], omctrl_rxnss,
12795 omctrl_chwidth, omctrl_rxnss);
12796 }
12797
12798 val = get_param(cmd, "TriggerType");
12799 if (val) {
12800 trigtype = atoi(val);
12801 switch (trigtype) {
12802 case 0:
12803 ath_set_trigger_type_0(dut, ifname);
12804 break;
12805 case 1:
12806 ath_set_trigger_type_1(dut, ifname);
12807 break;
12808 case 2:
12809 ath_set_trigger_type_2(dut, ifname);
12810 break;
12811 case 3:
12812 ath_set_trigger_type_3(dut, ifname);
12813 break;
12814 case 4:
12815 ath_set_trigger_type_4(dut, ifname, basedev);
12816 break;
12817 default:
12818 send_resp(dut, conn, SIGMA_ERROR,
12819 "errorCode,TriggerType not supported");
12820 return STATUS_SENT_ERROR;
12821 }
12822 }
12823
12824 val = get_param(cmd, "HE_TXOPDurRTSThr");
12825 if (val)
12826 run_iwpriv(dut, ifname, "he_rtsthrshld %d", atoi(val));
12827
12828 val = get_param(cmd, "NAV_Update");
12829 if (val) {
12830 if (strcasecmp(val, "disable") == 0) {
12831 run_iwpriv(dut, basedev, "nav_config 1 0");
12832 } else if (strcasecmp(val, "enable") == 0) {
12833 /* Do nothing */
12834 } else {
12835 send_resp(dut, conn, SIGMA_ERROR,
12836 "errorCode,Unsupported NAV update");
12837 return STATUS_SENT_ERROR;
12838 }
12839 }
12840
12841 /* Configure WMM Parameter Elements */
12842 val = get_param(cmd, "STA_WMMPE_ECWmin_BE");
12843 if (val) {
12844 param = atoi(val);
12845 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BE, param);
12846 }
12847
12848 val = get_param(cmd, "STA_WMMPE_ECWmin_BK");
12849 if (val) {
12850 param = atoi(val);
12851 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BK, param);
12852 }
12853
12854 val = get_param(cmd, "STA_WMMPE_ECWmin_VI");
12855 if (val) {
12856 param = atoi(val);
12857 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VI, param);
12858 }
12859
12860 val = get_param(cmd, "STA_WMMPE_ECWmin_VO");
12861 if (val) {
12862 param = atoi(val);
12863 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VO, param);
12864 }
12865
12866 val = get_param(cmd, "STA_WMMPE_ECWmax_BE");
12867 if (val) {
12868 param = atoi(val);
12869 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BE, param);
12870 }
12871
12872 val = get_param(cmd, "STA_WMMPE_ECWmax_BK");
12873 if (val) {
12874 param = atoi(val);
12875 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BK, param);
12876 }
12877
12878 val = get_param(cmd, "STA_WMMPE_ECWmax_VI");
12879 if (val) {
12880 param = atoi(val);
12881 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VI, param);
12882 }
12883
12884 val = get_param(cmd, "STA_WMMPE_ECWmax_VO");
12885 if (val) {
12886 param = atoi(val);
12887 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VO, param);
12888 }
12889
12890 val = get_param(cmd, "STA_WMMPE_AIFSN_BE");
12891 if (val) {
12892 param = atoi(val);
12893 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BE, param);
12894 }
12895
12896 val = get_param(cmd, "STA_WMMPE_AIFSN_BK");
12897 if (val) {
12898 param = atoi(val);
12899 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BK, param);
12900 }
12901
12902 val = get_param(cmd, "STA_WMMPE_AIFSN_VI");
12903 if (val) {
12904 param = atoi(val);
12905 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VI, param);
12906 }
12907
12908 val = get_param(cmd, "STA_WMMPE_AIFSN_VO");
12909 if (val) {
12910 param = atoi(val);
12911 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VO, param);
12912 }
12913
12914
12915 val = get_param(cmd, "STA_WMMPE_TXOP_BE");
12916 if (val) {
12917 param = atoi(val);
12918 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BE, param);
12919 }
12920
12921 val = get_param(cmd, "STA_WMMPE_TOXP_BK");
12922 if (val) {
12923 param = atoi(val);
12924 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BK, param);
12925 }
12926
12927 val = get_param(cmd, "STA_WMMPE_TXOP_VI");
12928 if (val) {
12929 param = atoi(val);
12930 run_iwpriv(dut, ifname, "txoplimit %d %d", AP_AC_VI, param);
12931 }
12932
12933 val = get_param(cmd, "STA_WMMPE_TXOP_VO");
12934 if (val) {
12935 param = atoi(val);
12936 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_VO, param);
12937 }
12938
12939 /* Configure MU EDCA */
12940 val = get_param(cmd, "STA_MUEDCA_ECWmin_BE");
12941 if (val) {
12942 param = atoi(val);
12943 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BE, param);
12944 }
12945
12946 val = get_param(cmd, "STA_MUEDCA_ECWmin_BK");
12947 if (val) {
12948 param = atoi(val);
12949 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BK, param);
12950 }
12951
12952 val = get_param(cmd, "STA_MUEDCA_ECWmin_VI");
12953 if (val) {
12954 param = atoi(val);
12955 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VI, param);
12956 }
12957
12958 val = get_param(cmd, "STA_MUEDCA_ECWmin_VO");
12959 if (val) {
12960 param = atoi(val);
12961 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VO, param);
12962 }
12963
12964 val = get_param(cmd, "STA_MUEDCA_ECWmax_BE");
12965 if (val) {
12966 param = atoi(val);
12967 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BE, param);
12968 }
12969
12970 val = get_param(cmd, "STA_MUEDCA_ECWmax_BK");
12971 if (val) {
12972 param = atoi(val);
12973 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BK, param);
12974 }
12975
12976 val = get_param(cmd, "STA_MUEDCA_ECWmax_VI");
12977 if (val) {
12978 param = atoi(val);
12979 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VI, param);
12980 }
12981
12982 val = get_param(cmd, "STA_MUEDCA_ECWmax_VO");
12983 if (val) {
12984 param = atoi(val);
12985 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VO, param);
12986 }
12987
12988 val = get_param(cmd, "STA_MUEDCA_AIFSN_BE");
12989 if (val) {
12990 param = atoi(val);
12991 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BE, param);
12992 }
12993
12994 val = get_param(cmd, "STA_MUEDCA_AIFSN_BK");
12995 if (val) {
12996 param = atoi(val);
12997 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BK, param);
12998 }
12999
13000 val = get_param(cmd, "STA_MUEDCA_AIFSN_VI");
13001 if (val) {
13002 param = atoi(val);
13003 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VI, param);
13004 }
13005
13006 val = get_param(cmd, "STA_MUEDCA_AIFSN_VO");
13007 if (val) {
13008 param = atoi(val);
13009 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VO, param);
13010 }
13011
13012 val = get_param(cmd, "STA_MUEDCA_Timer_BE");
13013 if (val) {
13014 param = atoi(val);
13015 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BE, param);
13016 }
13017
13018 val = get_param(cmd, "STA_MUEDCA_Timer_BK");
13019 if (val) {
13020 param = atoi(val);
13021 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BK, param);
13022 }
13023
13024 val = get_param(cmd, "STA_MUEDCA_Timer_VI");
13025 if (val) {
13026 param = atoi(val);
13027 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VI, param);
13028 }
13029
13030 val = get_param(cmd, "STA_MUEDCA_Timer_VO");
13031 if (val) {
13032 param = atoi(val);
13033 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VO, param);
13034 }
13035
13036 return SUCCESS_SEND_STATUS;
13037 }
13038
13039
wcn_vht_chnum_band(struct sigma_dut * dut,const char * ifname,const char * val)13040 static int wcn_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
13041 const char *val)
13042 {
13043 char *token, *result;
13044 int channel = 36;
13045 char *saveptr;
13046
13047 /* Extract the channel info */
13048 token = strdup(val);
13049 if (!token)
13050 return -1;
13051 result = strtok_r(token, ";", &saveptr);
13052 if (result)
13053 channel = atoi(result);
13054
13055 /* Issue the channel switch command */
13056 run_iwpriv(dut, ifname, "setChanChange %d", channel);
13057
13058 free(token);
13059 return 0;
13060 }
13061
13062
wcn_ap_set_rfeature(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13063 static enum sigma_cmd_result wcn_ap_set_rfeature(struct sigma_dut *dut,
13064 struct sigma_conn *conn,
13065 struct sigma_cmd *cmd)
13066 {
13067 const char *val;
13068 const char *ifname;
13069
13070 ifname = get_main_ifname(dut);
13071
13072 val = get_param(cmd, "chnum_band");
13073 if (val && wcn_vht_chnum_band(dut, ifname, val) < 0)
13074 return ERROR_SEND_STATUS;
13075
13076 val = get_param(cmd, "txBandwidth");
13077 if (val) {
13078 int old_ch_bw = dut->ap_chwidth;
13079
13080 if (strcasecmp(val, "Auto") == 0) {
13081 dut->ap_chwidth = 0;
13082 } else if (strcasecmp(val, "20") == 0) {
13083 dut->ap_chwidth = 0;
13084 } else if (strcasecmp(val, "40") == 0) {
13085 dut->ap_chwidth = 1;
13086 } else if (strcasecmp(val, "80") == 0) {
13087 dut->ap_chwidth = 2;
13088 } else if (strcasecmp(val, "160") == 0) {
13089 dut->ap_chwidth = 3;
13090 } else {
13091 send_resp(dut, conn, SIGMA_ERROR,
13092 "ErrorCode,WIDTH not supported");
13093 return STATUS_SENT_ERROR;
13094 }
13095 if (old_ch_bw != dut->ap_chwidth) {
13096 if (cmd_ap_config_commit(dut, conn, cmd) <= 0)
13097 return STATUS_SENT_ERROR;
13098 } else {
13099 sigma_dut_print(dut, DUT_MSG_DEBUG, "No change in BW");
13100 }
13101 }
13102
13103 val = get_param(cmd, "GI");
13104 if (val) {
13105 int fix_rate_sgi;
13106
13107 if (strcmp(val, "0.8") == 0) {
13108 run_iwpriv(dut, ifname, "enable_short_gi 9");
13109 fix_rate_sgi = 1;
13110 } else if (strcmp(val, "1.6") == 0) {
13111 run_iwpriv(dut, ifname, "enable_short_gi 10");
13112 fix_rate_sgi = 2;
13113 } else if (strcmp(val, "3.2") == 0) {
13114 run_iwpriv(dut, ifname, "enable_short_gi 11");
13115 fix_rate_sgi = 3;
13116 } else {
13117 send_resp(dut, conn, SIGMA_ERROR,
13118 "errorCode,GI value not supported");
13119 return STATUS_SENT_ERROR;
13120 }
13121 run_iwpriv(dut, ifname, "enable_short_gi %d", fix_rate_sgi);
13122 }
13123
13124 val = get_param(cmd, "LTF");
13125 if (val) {
13126 #ifdef NL80211_SUPPORT
13127 if (strcmp(val, "3.2") == 0) {
13128 wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_1X);
13129 } if (strcmp(val, "6.4") == 0) {
13130 wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_2X);
13131 } else if (strcmp(val, "12.8") == 0) {
13132 wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_4X);
13133 } else {
13134 send_resp(dut, conn, SIGMA_ERROR,
13135 "errorCode,LTF value not supported");
13136 return STATUS_SENT;
13137 }
13138 #else /* NL80211_SUPPORT */
13139 sigma_dut_print(dut, DUT_MSG_ERROR,
13140 "LTF cannot be set without NL80211_SUPPORT defined");
13141 return ERROR_SEND_STATUS;
13142 #endif /* NL80211_SUPPORT */
13143 }
13144
13145 return SUCCESS_SEND_STATUS;
13146 }
13147
13148
mac80211_vht_chnum_band(struct sigma_dut * dut,const char * ifname,const char * val)13149 static int mac80211_vht_chnum_band(struct sigma_dut *dut, const char *ifname,
13150 const char *val)
13151 {
13152 char *token, *result;
13153 int channel = 36, chwidth = 80, center_freq_idx, center_freq,
13154 channel_freq;
13155 char buf[100];
13156 char *saveptr;
13157 int res;
13158
13159 /* Extract the channel info */
13160 token = strdup(val);
13161 if (!token)
13162 return -1;
13163 result = strtok_r(token, ";", &saveptr);
13164 if (result)
13165 channel = atoi(result);
13166
13167 /* Extract the channel width info */
13168 result = strtok_r(NULL, ";", &saveptr);
13169 if (result)
13170 chwidth = atoi(result);
13171
13172 center_freq_idx = get_oper_centr_freq_seq_idx(chwidth, channel);
13173 if (center_freq_idx < 0) {
13174 free(token);
13175 return -1;
13176 }
13177
13178 center_freq = get_5g_channel_freq(center_freq_idx);
13179 channel_freq = get_5g_channel_freq(channel);
13180
13181 /* Issue the channel switch command */
13182 res = snprintf(buf, sizeof(buf),
13183 " -i %s chan_switch 10 %d sec_channel_offset=1 center_freq1=%d bandwidth=%d blocktx vht",
13184 ifname, channel_freq, center_freq, chwidth);
13185 if (res < 0 || res >= sizeof(buf) || run_hostapd_cli(dut, buf) != 0) {
13186 sigma_dut_print(dut, DUT_MSG_ERROR,
13187 "hostapd_cli chan_switch failed");
13188 }
13189
13190 free(token);
13191 return 0;
13192 }
13193
13194
13195 static enum sigma_cmd_result
mac80211_he_tx_bandwidth(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val,const char * type)13196 mac80211_he_tx_bandwidth(struct sigma_dut *dut, struct sigma_conn *conn,
13197 const char *ifname, const char *val, const char *type)
13198 {
13199 int width, center_freq_idx, center_freq, channel_freq, res;
13200 char *mode, buf[256];
13201
13202 if (!type) {
13203 send_resp(dut, conn, SIGMA_INVALID,
13204 "errorCode,Missing type parameter");
13205 return STATUS_SENT_ERROR;
13206 }
13207
13208 if (strcasecmp(type, "HE") == 0) {
13209 mode = "he";
13210 } else if (strcasecmp(type, "VHT") == 0) {
13211 mode = "vht";
13212 } else if (strcasecmp(type, "HT") == 0) {
13213 mode = "ht";
13214 } else {
13215 send_resp(dut, conn, SIGMA_ERROR,
13216 "errorCode,Unsupported type value");
13217 return STATUS_SENT_ERROR;
13218 }
13219
13220 width = atoi(val);
13221 center_freq_idx = get_oper_centr_freq_seq_idx(width, dut->ap_channel);
13222 if (center_freq_idx < 0)
13223 return ERROR_SEND_STATUS;
13224
13225 center_freq = get_5g_channel_freq(center_freq_idx);
13226 channel_freq = get_5g_channel_freq(dut->ap_channel);
13227
13228 res = snprintf(buf, sizeof(buf),
13229 "CHAN_SWITCH 10 %d sec_channel_offset=1 center_freq1=%d bandwidth=%d blocktx %s",
13230 channel_freq, center_freq, width, mode);
13231
13232 if (res < 0 || res >= sizeof(buf) || hapd_command(ifname, buf) != 0) {
13233 send_resp(dut, conn, SIGMA_ERROR, "CHAN_SWITCH command failed");
13234 return STATUS_SENT_ERROR;
13235 }
13236
13237 return SUCCESS_SEND_STATUS;
13238 }
13239
13240
mac80211_he_ltf_mapping(struct sigma_dut * dut,const char * val)13241 static int mac80211_he_ltf_mapping(struct sigma_dut *dut,
13242 const char *val)
13243 {
13244 if (strcmp(val, "3.2") == 0)
13245 return 0x01;
13246 if (strcmp(val, "6.4") == 0)
13247 return 0x02;
13248 if (strcmp(val, "12.8") == 0)
13249 return 0x04;
13250
13251 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported LTF value %s", val);
13252 return -1;
13253 }
13254
13255
mac80211_he_ltf(struct sigma_dut * dut,struct sigma_conn * conn,const char * ifname,const char * val)13256 static enum sigma_cmd_result mac80211_he_ltf(struct sigma_dut *dut,
13257 struct sigma_conn *conn,
13258 const char *ifname,
13259 const char *val)
13260 {
13261 free(dut->ar_ltf);
13262 dut->ar_ltf = strdup(val);
13263 if (!dut->ar_ltf) {
13264 send_resp(dut, conn, SIGMA_ERROR,
13265 "errorCode,Failed to store new LTF");
13266 return STATUS_SENT_ERROR;
13267 }
13268 return SUCCESS_SEND_STATUS;
13269 }
13270
13271
mac80211_he_gi(struct sigma_dut * dut,const char * ifname,const char * val)13272 static enum sigma_cmd_result mac80211_he_gi(struct sigma_dut *dut,
13273 const char *ifname,
13274 const char *val)
13275 {
13276 int16_t he_ltf = 0xFF;
13277 char *mode = dut->use_5g ? "5" : "2.4";
13278 int ret = -1;
13279
13280 if (dut->ar_ltf) {
13281 he_ltf = mac80211_he_ltf_mapping(dut, dut->ar_ltf);
13282 free(dut->ar_ltf);
13283 dut->ar_ltf = NULL;
13284
13285 if (he_ltf < 0)
13286 return ERROR_SEND_STATUS;
13287
13288 if (val) {
13289 ret = run_system_wrapper(
13290 dut,
13291 "iw %s set bitrates he-gi-%s %s he-ltf-%s %u",
13292 ifname, mode, val, mode,
13293 he_ltf);
13294 } else {
13295 ret = run_system_wrapper(
13296 dut,
13297 "iw %s set bitrates he-ltf-%s %u",
13298 ifname, mode, he_ltf);
13299 }
13300 } else if (val) {
13301 ret = run_system_wrapper(dut,
13302 "iw %s set bitrates he-gi-%s %s",
13303 ifname, mode, val);
13304 }
13305 if (ret < 0)
13306 return ERROR_SEND_STATUS;
13307 return SUCCESS_SEND_STATUS;
13308 }
13309
13310
mac80211_set_ackpolicy_0(struct sigma_dut * dut,const char * ifname,unsigned char * mac_addr)13311 static void mac80211_set_ackpolicy_0(struct sigma_dut *dut, const char *ifname,
13312 unsigned char *mac_addr)
13313 {
13314 char cmd[256];
13315
13316 /* Disable all-BAR ackpolicy for MU-MIMO */
13317 fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 62 0", ifname);
13318 /* Disable all-BAR ackpolicy first */
13319 fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 64 0", ifname);
13320
13321 /*
13322 * Set the normal ack policy for the STA with the specified
13323 * MAC address in the DL TX case.
13324 */
13325 snprintf(cmd, sizeof(cmd),
13326 "-m 0x4b -v 0 8 1 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
13327 mac_addr[0], mac_addr[1], mac_addr[2],
13328 mac_addr[3], mac_addr[4], mac_addr[5]);
13329
13330 fwtest_cmd_wrapper(dut, cmd, ifname);
13331 }
13332
13333
mac80211_set_ackpolicy_3(struct sigma_dut * dut,const char * ifname)13334 static void mac80211_set_ackpolicy_3(struct sigma_dut *dut, const char *ifname)
13335 {
13336 /* Enable all-BAR ackpolicy for MU-MIMO DL */
13337 fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 62 1", ifname);
13338 /* Enable all-BAR ackpolicy */
13339 fwtest_cmd_wrapper(dut, "-m 0x48 -v 0 64 1", ifname);
13340 }
13341
13342
mac80211_set_ackpolicy_4(struct sigma_dut * dut,const char * ifname)13343 static void mac80211_set_ackpolicy_4(struct sigma_dut *dut, const char *ifname)
13344 {
13345 /* Enable htp-ack ackpolicy */
13346 fwtest_cmd_wrapper(dut, "-m 0x47 -v 0 99 1", ifname);
13347 }
13348
13349
mac80211_ap_set_rfeature(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13350 static enum sigma_cmd_result mac80211_ap_set_rfeature(struct sigma_dut *dut,
13351 struct sigma_conn *conn,
13352 struct sigma_cmd *cmd)
13353 {
13354 const char *val;
13355 const char *ifname;
13356 enum sigma_cmd_result res;
13357 unsigned char mac_addr[ETH_ALEN];
13358 int he_ackpolicymac = 0;
13359 int ap_he_ackpolicy;
13360
13361 ifname = get_main_ifname(dut);
13362
13363 val = get_param(cmd, "RTS_FORCE");
13364 if (val)
13365 mac80211_config_rts_force(dut, ifname, val);
13366
13367 val = get_param(cmd, "chnum_band");
13368 if (val && mac80211_vht_chnum_band(dut, ifname, val) < 0)
13369 return -1;
13370
13371 val = get_param(cmd, "txBandwidth");
13372 if (val) {
13373 res = mac80211_he_tx_bandwidth(dut, conn, ifname, val,
13374 get_param(cmd, "type"));
13375 if (res != SUCCESS_SEND_STATUS)
13376 return res;
13377 }
13378
13379 val = get_param(cmd, "LTF");
13380 if (val) {
13381 res = mac80211_he_ltf(dut, conn, ifname, val);
13382 if (res != SUCCESS_SEND_STATUS)
13383 return res;
13384 }
13385
13386 val = get_param(cmd, "GI");
13387 if (val || dut->ar_ltf) {
13388 res = mac80211_he_gi(dut, ifname, val);
13389 if (res != SUCCESS_SEND_STATUS)
13390 return res;
13391 }
13392
13393 val = get_param(cmd, "AckPolicy_MAC");
13394 if (val) {
13395 if (parse_mac_address(dut, val, mac_addr) < 0) {
13396 send_resp(dut, conn, SIGMA_ERROR,
13397 "errorCode,MAC address not in proper format");
13398 return STATUS_SENT_ERROR;
13399 }
13400
13401 he_ackpolicymac = 1;
13402 }
13403
13404 val = get_param(cmd, "AckPolicy");
13405 if (val) {
13406 ap_he_ackpolicy = atoi(val);
13407
13408 switch (ap_he_ackpolicy) {
13409 case 0:
13410 if (!he_ackpolicymac)
13411 break;
13412 mac80211_set_ackpolicy_0(dut, ifname, mac_addr);
13413 break;
13414 case 3:
13415 mac80211_set_ackpolicy_3(dut, ifname);
13416 break;
13417 case 4:
13418 mac80211_set_ackpolicy_4(dut, ifname);
13419 break;
13420 default:
13421 send_resp(dut, conn, SIGMA_ERROR,
13422 "errorCode,Invalid AckPolicy setting");
13423 return STATUS_SENT_ERROR;
13424 }
13425 }
13426
13427 return SUCCESS_SEND_STATUS;
13428 }
13429
13430
13431 #ifdef __linux__
wil6210_ap_set_rfeature(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13432 static int wil6210_ap_set_rfeature(struct sigma_dut *dut,
13433 struct sigma_conn *conn,
13434 struct sigma_cmd *cmd)
13435 {
13436 const char *val;
13437
13438 val = get_param(cmd, "ExtSchIE");
13439 if (val && !strcasecmp(val, "Enable")) {
13440 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
13441 int count = MAX_ESE_ALLOCS;
13442
13443 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
13444 return -1;
13445 if (wil6210_set_ese(dut, count, allocs))
13446 return -1;
13447 return 1;
13448 }
13449
13450 send_resp(dut, conn, SIGMA_ERROR,
13451 "errorCode,Invalid ap_set_rfeature(60G)");
13452 return 0;
13453 }
13454 #endif /* __linux__ */
13455
13456
cmd_ap_set_rfeature(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13457 static enum sigma_cmd_result cmd_ap_set_rfeature(struct sigma_dut *dut,
13458 struct sigma_conn *conn,
13459 struct sigma_cmd *cmd)
13460 {
13461 /* const char *name = get_param(cmd, "NAME"); */
13462 /* const char *type = get_param(cmd, "Type"); */
13463 const char *val, *oci_chan, *oci_frametype;
13464 char buf[100];
13465 const char *ifname = get_hostapd_ifname(dut);
13466
13467 val = get_param(cmd, "ReassocResp_RSNXE_Used");
13468 if (val) {
13469 if (atoi(val) == 0)
13470 snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 2");
13471 else
13472 snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 1");
13473 if (hapd_command(ifname, buf) < 0) {
13474 send_resp(dut, conn, SIGMA_ERROR,
13475 "ErrorCode,Failed to set ft_rsnxe_used");
13476 return STATUS_SENT_ERROR;
13477 }
13478 }
13479
13480 oci_chan = get_param(cmd, "OCIChannel");
13481 oci_frametype = get_param(cmd, "OCIFrameType");
13482 if (oci_chan && oci_frametype) {
13483 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
13484
13485 if (!oci_freq) {
13486 send_resp(dut, conn, SIGMA_ERROR,
13487 "errorCode,Invalid OCIChannel number");
13488 return STATUS_SENT_ERROR;
13489 }
13490
13491 if (strcasecmp(oci_frametype, "eapolM3") == 0) {
13492 snprintf(buf, sizeof(buf),
13493 "SET oci_freq_override_eapol_m3 %d", oci_freq);
13494 } else if (strcasecmp(oci_frametype, "eapolG1") == 0) {
13495 snprintf(buf, sizeof(buf),
13496 "SET oci_freq_override_eapol_g1 %d", oci_freq);
13497 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
13498 snprintf(buf, sizeof(buf),
13499 "SET oci_freq_override_saquery_req %d",
13500 oci_freq);
13501 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
13502 snprintf(buf, sizeof(buf),
13503 "SET oci_freq_override_saquery_resp %d",
13504 oci_freq);
13505 } else {
13506 send_resp(dut, conn, SIGMA_ERROR,
13507 "errorCode,Unsupported OCIFrameType");
13508 return STATUS_SENT_ERROR;
13509 }
13510 if (hapd_command(ifname, buf) < 0) {
13511 send_resp(dut, conn, SIGMA_ERROR,
13512 "errorCode,Failed to set oci_freq_override");
13513 return STATUS_SENT_ERROR;
13514 }
13515 return SUCCESS_SEND_STATUS;
13516 }
13517
13518 val = get_param(cmd, "Transition_Disable");
13519 if (val) {
13520 if (atoi(val)) {
13521 val = get_param(cmd, "Transition_Disable_Index");
13522 if (!val) {
13523 send_resp(dut, conn, SIGMA_INVALID,
13524 "errorCode,Transition_Disable without Transition_Disable_Index");
13525 return STATUS_SENT;
13526 }
13527 dut->ap_transition_disable = 1 << atoi(val);
13528 } else {
13529 dut->ap_transition_disable = 0;
13530 }
13531
13532 snprintf(buf, sizeof(buf), "SET transition_disable 0x%02x",
13533 dut->ap_transition_disable);
13534 if (hapd_command(ifname, buf) < 0) {
13535 send_resp(dut, conn, SIGMA_ERROR,
13536 "errorCode,Failed to update transition mode disabled indication");
13537 return STATUS_SENT_ERROR;
13538 }
13539 return SUCCESS_SEND_STATUS;
13540 }
13541
13542 switch (get_driver_type(dut)) {
13543 case DRIVER_ATHEROS:
13544 return ath_ap_set_rfeature(dut, conn, cmd);
13545 case DRIVER_OPENWRT:
13546 switch (get_openwrt_driver_type()) {
13547 case OPENWRT_DRIVER_ATHEROS:
13548 return ath_ap_set_rfeature(dut, conn, cmd);
13549 default:
13550 send_resp(dut, conn, SIGMA_ERROR,
13551 "errorCode,Unsupported ap_set_rfeature with the current openwrt driver");
13552 return 0;
13553 }
13554 case DRIVER_LINUX_WCN:
13555 case DRIVER_WCN:
13556 return wcn_ap_set_rfeature(dut, conn, cmd);
13557 case DRIVER_MAC80211:
13558 return mac80211_ap_set_rfeature(dut, conn, cmd);
13559 #ifdef __linux__
13560 case DRIVER_WIL6210:
13561 return wil6210_ap_set_rfeature(dut, conn, cmd);
13562 #endif /* __linux__ */
13563 default:
13564 send_resp(dut, conn, SIGMA_ERROR,
13565 "errorCode,Unsupported ap_set_rfeature with the current driver");
13566 return 0;
13567 }
13568 }
13569
13570
cmd_accesspoint(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13571 static enum sigma_cmd_result cmd_accesspoint(struct sigma_dut *dut,
13572 struct sigma_conn *conn,
13573 struct sigma_cmd *cmd)
13574 {
13575 /* const char *name = get_param(cmd, "NAME"); */
13576 return 1;
13577 }
13578
13579
13580 static enum sigma_cmd_result
cmd_ap_preset_testparameters(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)13581 cmd_ap_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
13582 struct sigma_cmd *cmd)
13583 {
13584 const char *val;
13585
13586 val = get_param(cmd, "Oper_Chn");
13587 if (val) {
13588 dut->ap_oper_chn = 1;
13589 dut->ap_channel = atoi(val);
13590 }
13591
13592 val = get_param(cmd, "DPPConfiguratorAddress");
13593 if (val) {
13594 free(dut->ap_dpp_conf_addr);
13595 dut->ap_dpp_conf_addr = strdup(val);
13596 }
13597
13598 val = get_param(cmd, "DPPConfiguratorPKHash");
13599 if (val) {
13600 free(dut->ap_dpp_conf_pkhash);
13601 dut->ap_dpp_conf_pkhash = strdup(val);
13602 }
13603
13604 return 1;
13605 }
13606
13607
ap_register_cmds(void)13608 void ap_register_cmds(void)
13609 {
13610 sigma_dut_reg_cmd("ap_ca_version", NULL, cmd_ap_ca_version);
13611 sigma_dut_reg_cmd("ap_set_wireless", NULL, cmd_ap_set_wireless);
13612 sigma_dut_reg_cmd("ap_send_addba_req", NULL, cmd_ap_send_addba_req);
13613 sigma_dut_reg_cmd("ap_set_11n_wireless", NULL, cmd_ap_set_wireless);
13614 sigma_dut_reg_cmd("ap_set_11n", NULL, cmd_ap_set_wireless);
13615 sigma_dut_reg_cmd("ap_set_11d", NULL, cmd_ap_set_wireless);
13616 sigma_dut_reg_cmd("ap_set_11h", NULL, cmd_ap_set_wireless);
13617 sigma_dut_reg_cmd("ap_set_security", NULL, cmd_ap_set_security);
13618 sigma_dut_reg_cmd("ap_set_apqos", NULL, cmd_ap_set_apqos);
13619 sigma_dut_reg_cmd("ap_set_staqos", NULL, cmd_ap_set_staqos);
13620 sigma_dut_reg_cmd("ap_set_radius", NULL, cmd_ap_set_radius);
13621 sigma_dut_reg_cmd("ap_reboot", NULL, cmd_ap_reboot);
13622 sigma_dut_reg_cmd("ap_config_commit", NULL, cmd_ap_config_commit);
13623 sigma_dut_reg_cmd("ap_reset_default", NULL, cmd_ap_reset_default);
13624 sigma_dut_reg_cmd("ap_get_info", NULL, cmd_ap_get_info);
13625 sigma_dut_reg_cmd("ap_deauth_sta", NULL, cmd_ap_deauth_sta);
13626 sigma_dut_reg_cmd("ap_send_frame", NULL, cmd_ap_send_frame);
13627 sigma_dut_reg_cmd("ap_get_mac_address", NULL, cmd_ap_get_mac_address);
13628 sigma_dut_reg_cmd("ap_set_pmf", NULL, cmd_ap_set_pmf);
13629 sigma_dut_reg_cmd("ap_set_hs2", NULL, cmd_ap_set_hs2);
13630 sigma_dut_reg_cmd("ap_set_rfeature", NULL, cmd_ap_set_rfeature);
13631 sigma_dut_reg_cmd("ap_nfc_action", NULL, cmd_ap_nfc_action);
13632 sigma_dut_reg_cmd("ap_wps_read_pin", NULL, cmd_ap_wps_read_pin);
13633 sigma_dut_reg_cmd("ap_wps_enter_pin", NULL, cmd_ap_wps_enter_pin);
13634 sigma_dut_reg_cmd("ap_wps_set_pbc", NULL, cmd_ap_wps_set_pbc);
13635 sigma_dut_reg_cmd("ap_get_parameter", NULL, cmd_ap_get_parameter);
13636 sigma_dut_reg_cmd("AccessPoint", NULL, cmd_accesspoint);
13637 sigma_dut_reg_cmd("ap_preset_testparameters", NULL,
13638 cmd_ap_preset_testparameters);
13639 }
13640