1 /* 2 * Sigma Control API DUT (station/AP) 3 * Copyright (c) 2010-2011, Atheros Communications, Inc. 4 * Copyright (c) 2011-2017, Qualcomm Atheros, Inc. 5 * Copyright (c) 2018-2019, The Linux Foundation 6 * All Rights Reserved. 7 * Licensed under the Clear BSD license. See README for more details. 8 */ 9 10 #include "sigma_dut.h" 11 #include <sys/stat.h> 12 #include <sys/wait.h> 13 #include <sys/utsname.h> 14 #include <sys/ioctl.h> 15 #ifdef __linux__ 16 #include <limits.h> 17 #include <dirent.h> 18 #include <string.h> 19 #include <sys/types.h> 20 #include <unistd.h> 21 #endif /* __linux__ */ 22 #ifdef __QNXNTO__ 23 #include <ifaddrs.h> 24 #include <net/if_dl.h> 25 #endif /* __QNXNTO__ */ 26 #include "wpa_ctrl.h" 27 #include "wpa_helpers.h" 28 #ifdef ANDROID 29 #include <hardware_legacy/wifi.h> 30 #include <grp.h> 31 #include <pwd.h> 32 #endif /* ANDROID */ 33 34 /* Temporary files for ap_send_addba_req */ 35 #define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp" 36 #define VI_QOS_FILE "/tmp/vi-qos.txt" 37 #define VI_QOS_REFFILE "/etc/vi-qos.txt" 38 39 /* Configuration file name on Android */ 40 #ifndef ANDROID_CONFIG_FILE 41 #define ANDROID_CONFIG_FILE "/data/misc/wifi/hostapd.conf" 42 #endif /* ANDROID_CONFIG_FILE */ 43 /* Maximum length of the line in the configuration file */ 44 #define MAX_CONF_LINE_LEN (156) 45 46 #ifndef SIGMA_DUT_HOSTAPD_PID_FILE 47 #define SIGMA_DUT_HOSTAPD_PID_FILE "/tmp/sigma_dut-ap-hostapd.pid" 48 #endif /* SIGMA_DUT_HOSTAPD_PID_FILE */ 49 50 /* The following is taken from Hotspot 2.0 testplan Appendix B.1 */ 51 #define ANQP_VENUE_NAME_1 "02019c0002083d656e6757692d466920416c6c69616e63650a3239383920436f7070657220526f61640a53616e746120436c6172612c2043412039353035312c205553415b63686957692d4669e88194e79b9fe5ae9ee9aa8ce5aea40ae4ba8ce4b99de585abe4b99de5b9b4e5ba93e69f8fe8b7af0ae59ca3e5858be68b89e68b892c20e58aa0e588a9e7a68fe5b0bce4ba9a39353035312c20e7be8ee59bbd" 52 #define ANQP_VENUE_NAME_1_CHI "P\"\x63\x68\x69\x3a\x57\x69\x2d\x46\x69\xe8\x81\x94\xe7\x9b\x9f\xe5\xae\x9e\xe9\xaa\x8c\xe5\xae\xa4\\n\xe4\xba\x8c\xe4\xb9\x9d\xe5\x85\xab\xe4\xb9\x9d\xe5\xb9\xb4\xe5\xba\x93\xe6\x9f\x8f\xe8\xb7\xaf\\n\xe5\x9c\xa3\xe5\x85\x8b\xe6\x8b\x89\xe6\x8b\x89\x2c\x20\xe5\x8a\xa0\xe5\x88\xa9\xe7\xa6\x8f\xe5\xb0\xbc\xe4\xba\x9a\x39\x35\x30\x35\x31\x2c\x20\xe7\xbe\x8e\xe5\x9b\xbd\"" 53 #define ANQP_IP_ADDR_TYPE_1 "060101000c" 54 #define ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "dddd2700506f9a11030011656e6757692d466920416c6c69616e63650e63686957692d4669e88194e79b9f" 55 #define ANQP_HS20_WAN_METRICS_1 "dddd1300506f9a11040001c40900008001000000000000" 56 #define ANQP_HS20_CONNECTION_CAPABILITY_1 "dddd3200506f9a1105000100000006140001061600000650000106bb010106bb060006c4130011f4010111c413001194110132000001" 57 #define QOS_MAP_SET_1 "53,2,22,6,8,15,0,7,255,255,16,31,32,39,255,255,40,47,255,255" 58 #define QOS_MAP_SET_2 "8,15,0,7,255,255,16,31,32,39,255,255,40,47,48,63" 59 60 #define ADV_OF_CHARGE_1 \ 61 "bc01000000d200454e475553443c3f786d6c2076657273696f6e3d22312e30222065" \ 62 "6e636f64696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f77" \ 63 "77772e77692d66692e6f72672f73706563696669636174696f6e732f686f7473706f7432646f" \ 64 "74302f76312e302f616f637069223e3c4465736372697074696f6e3e57692d46692061636365" \ 65 "737320666f72203120686f75722c207768696c6520796f752077616974206174207468652067" \ 66 "6174652c2024302e39393c2f4465736372697074696f6e3e3c2f506c616e3ee3004652414341" \ 67 "443c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f" \ 68 "3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77692d66692e6f72672f737065" \ 69 "63696669636174696f6e732f686f7473706f7432646f74302f76312e302f616f637069223e3c" \ 70 "4465736372697074696f6e3e416363c3a8732057692d46692070656e64616e74203120686575" \ 71 "72652c2070656e64616e742071756520766f757320617474656e64657a20c3a0206c6120706f" \ 72 "7274652c20302c393920243c2f4465736372697074696f6e3e3c2f506c616e3ea101010000c7" \ 73 "00454e475553443c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d2255" \ 74 "54462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77692d66692e6f" \ 75 "72672f73706563696669636174696f6e732f686f7473706f7432646f74302f76312e302f616f" \ 76 "637069223e3c4465736372697074696f6e3e446f776e6c6f616420766964656f7320666f7220" \ 77 "796f757220666c696768742c2024322e393920666f7220313047423c2f446573637269707469" \ 78 "6f6e3e3c2f506c616e3ed3004652414341443c3f786d6c2076657273696f6e3d22312e302220" \ 79 "656e636f64696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f" \ 80 "7777772e77692d66692e6f72672f73706563696669636174696f6e732f686f7473706f743264" \ 81 "6f74302f76312e302f616f637069223e3c4465736372697074696f6e3e54c3a96cc3a9636861" \ 82 "7267657a2064657320766964c3a96f7320706f757220766f74726520766f6c2c20322c393920" \ 83 "2420706f757220313020476f3c2f4465736372697074696f6e3e3c2f506c616e3ee40003002b" \ 84 "736572766963652d70726f76696465722e636f6d3b66656465726174696f6e2e6578616d706c" \ 85 "652e636f6db400454e475553443c3f786d6c2076657273696f6e3d22312e302220656e636f64" \ 86 "696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77" \ 87 "692d66692e6f72672f73706563696669636174696f6e732f686f7473706f7432646f74302f76" \ 88 "312e302f616f637069223e3c4465736372697074696f6e3e46726565207769746820796f7572" \ 89 "20737562736372697074696f6e213c2f4465736372697074696f6e3e3c2f506c616e3e" 90 91 /* 92 * MTU for Ethernet need to take into account 8-byte SNAP header 93 * to be added when encapsulating Ethernet frame into 802.11. 94 */ 95 #ifndef IEEE80211_MAX_DATA_LEN_DMG 96 #define IEEE80211_MAX_DATA_LEN_DMG 7920 97 #endif /* IEEE80211_MAX_DATA_LEN_DMG */ 98 #ifndef IEEE80211_SNAP_LEN_DMG 99 #define IEEE80211_SNAP_LEN_DMG 8 100 #endif /* IEEE80211_SNAP_LEN_DMG */ 101 102 extern char *sigma_wpas_ctrl; 103 extern char *sigma_hapd_ctrl; 104 extern char *ap_inet_addr; 105 extern char *ap_inet_mask; 106 extern char *sigma_radio_ifname[]; 107 108 static int ath_ap_start_hostapd(struct sigma_dut *dut); 109 static void ath_ap_set_params(struct sigma_dut *dut); 110 static int kill_process(struct sigma_dut *dut, char *proc_name, 111 unsigned char is_proc_instance_one, int sig); 112 113 114 static int ap_ft_enabled(struct sigma_dut *dut) 115 { 116 return dut->ap_ft_oa == 1 || 117 dut->ap_ft_ds == VALUE_ENABLED || 118 dut->ap_key_mgmt == AP_WPA2_FT_EAP || 119 dut->ap_key_mgmt == AP_WPA2_FT_PSK || 120 dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP || 121 (dut->ap_akm_values & 122 ((1 << AKM_FT_EAP) | 123 (1 << AKM_FT_PSK) | 124 (1 << AKM_FT_SAE) | 125 (1 << AKM_FT_SUITE_B) | 126 (1 << AKM_FT_FILS_SHA256) | 127 (1 << AKM_FT_FILS_SHA384))); 128 } 129 130 131 static enum sigma_cmd_result cmd_ap_ca_version(struct sigma_dut *dut, 132 struct sigma_conn *conn, 133 struct sigma_cmd *cmd) 134 { 135 /* const char *name = get_param(cmd, "NAME"); */ 136 send_resp(dut, conn, SIGMA_COMPLETE, "version,1.0"); 137 return 0; 138 } 139 140 141 static void kill_hostapd_process_pid(struct sigma_dut *dut) 142 { 143 FILE *f; 144 int pid, res; 145 char path[100]; 146 int count; 147 148 f = fopen(SIGMA_DUT_HOSTAPD_PID_FILE, "r"); 149 if (!f) 150 return; 151 res = fscanf(f, "%d", &pid); 152 fclose(f); 153 if (res != 1) 154 return; 155 sigma_dut_print(dut, DUT_MSG_INFO, "Killing hostapd pid %d", pid); 156 kill(pid, SIGTERM); 157 snprintf(path, sizeof(path), "/proc/%d", pid); 158 for (count = 0; count < 20 && file_exists(path); count++) 159 usleep(100000); 160 } 161 162 163 int get_hwaddr(const char *ifname, unsigned char *hwaddr) 164 { 165 #ifndef __QNXNTO__ 166 struct ifreq ifr; 167 int s; 168 169 s = socket(AF_INET, SOCK_DGRAM, 0); 170 if (s < 0) 171 return -1; 172 memset(&ifr, 0, sizeof(ifr)); 173 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 174 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { 175 perror("ioctl"); 176 close(s); 177 return -1; 178 } 179 close(s); 180 memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6); 181 #else /* __QNXNTO__ */ 182 struct ifaddrs *ifaddrshead = NULL; 183 int found = 0; 184 struct ifaddrs *temp_ifap = NULL; 185 struct sockaddr_dl *sdl = NULL; 186 187 if (getifaddrs(&ifaddrshead) != 0) { 188 perror("getifaddrs failed"); 189 return -1; 190 } 191 192 for (temp_ifap = ifaddrshead; ifaddrshead && !found; 193 ifaddrshead = ifaddrshead->ifa_next) { 194 if (ifaddrshead->ifa_addr->sa_family == AF_LINK && 195 strcmp(ifaddrshead->ifa_name, ifname) == 0) { 196 found = 1; 197 sdl = (struct sockaddr_dl *) ifaddrshead->ifa_addr; 198 if (sdl) 199 memcpy(hwaddr, LLADDR(sdl), sdl->sdl_alen); 200 } 201 } 202 203 if (temp_ifap) 204 freeifaddrs(temp_ifap); 205 206 if (!found) { 207 perror("Failed to get the interface"); 208 return -1; 209 } 210 #endif /* __QNXNTO__ */ 211 return 0; 212 } 213 214 215 static void ath_ap_set_group_id(struct sigma_dut *dut, const char *ifname, 216 const char *val) 217 { 218 char buf[60]; 219 220 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 55 %d", 221 ifname, atoi(val)); 222 if (system(buf) != 0) { 223 sigma_dut_print(dut, DUT_MSG_ERROR, 224 "wifitool ap_group_id failed"); 225 } 226 } 227 228 229 void ath_set_cts_width(struct sigma_dut *dut, const char *ifname, 230 const char *val) 231 { 232 char buf[60]; 233 234 /* TODO: Enable support for other values */ 235 if (strcasecmp(val, "40") == 0) { 236 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 1", 237 ifname); 238 if (system(buf) != 0) { 239 sigma_dut_print(dut, DUT_MSG_ERROR, 240 "wifitool cts_width failed"); 241 } 242 snprintf(buf, sizeof(buf), 243 "athdiag --set --address=0x10024 --val=0xd90b8a14"); 244 if (system(buf) != 0) { 245 sigma_dut_print(dut, DUT_MSG_ERROR, 246 "disabling phy restart failed"); 247 } 248 } else { 249 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported CTS_WIDTH"); 250 } 251 } 252 253 254 void ath_config_dyn_bw_sig(struct sigma_dut *dut, const char *ifname, 255 const char *val) 256 { 257 char buf[60]; 258 259 if (strcasecmp(val, "enable") == 0) { 260 dut->ap_dyn_bw_sig = VALUE_ENABLED; 261 run_iwpriv(dut, ifname, "cwmenable 1"); 262 263 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 96 1", 264 ifname); 265 if (system(buf) != 0) { 266 sigma_dut_print(dut, DUT_MSG_ERROR, 267 "disabling RTS from rate control logic failed"); 268 } 269 } else if (strcasecmp(val, "disable") == 0) { 270 dut->ap_dyn_bw_sig = VALUE_DISABLED; 271 run_iwpriv(dut, ifname, "cwmenable 0"); 272 } else { 273 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported DYN_BW_SGL"); 274 } 275 } 276 277 278 static void wcn_config_ap_ldpc(struct sigma_dut *dut, const char *ifname) 279 { 280 if (dut->ap_ldpc == VALUE_NOT_SET) 281 return; 282 run_iwpriv(dut, ifname, "ldpc %d", dut->ap_ldpc != VALUE_DISABLED); 283 } 284 285 286 static void mac80211_config_rts_force(struct sigma_dut *dut, const char *ifname, 287 const char *val) 288 { 289 char buf[60]; 290 char fname[128], path[128], *pos; 291 ssize_t res; 292 293 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211", 294 ifname); 295 if (res < 0 || res >= sizeof(fname)) 296 return; 297 298 res = readlink(fname, path, sizeof(path)); 299 if (res < 0) 300 return; 301 302 if (res >= (int) sizeof(path)) 303 res = sizeof(path) - 1; 304 path[res] = '\0'; 305 306 pos = strrchr(path, '/'); 307 if (!pos) 308 pos = path; 309 else 310 pos++; 311 312 if (strcasecmp(val, "enable") == 0) { 313 dut->ap_sig_rts = VALUE_ENABLED; 314 res = snprintf(buf, sizeof(buf), "iw %s set rts 64", pos); 315 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) { 316 sigma_dut_print(dut, DUT_MSG_ERROR, 317 "iw set rts 64 failed"); 318 } 319 } else if (strcasecmp(val, "disable") == 0) { 320 dut->ap_sig_rts = VALUE_DISABLED; 321 res = snprintf(buf, sizeof(buf), "iw %s set rts 2347", pos); 322 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) { 323 sigma_dut_print(dut, DUT_MSG_ERROR, 324 "iw rts 2347 failed"); 325 } 326 } else { 327 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE"); 328 } 329 330 } 331 332 333 static void ath_config_rts_force(struct sigma_dut *dut, const char *ifname, 334 const char *val) 335 { 336 char buf[60]; 337 338 if (strcasecmp(val, "enable") == 0) { 339 dut->ap_sig_rts = VALUE_ENABLED; 340 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname); 341 if (system(buf) != 0) { 342 sigma_dut_print(dut, DUT_MSG_ERROR, 343 "iwconfig rts 64 failed"); 344 } 345 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 100 1", 346 ifname); 347 if (system(buf) != 0) { 348 sigma_dut_print(dut, DUT_MSG_ERROR, 349 "wifitool beeliner_fw_test 100 1 failed"); 350 } 351 } else if (strcasecmp(val, "disable") == 0) { 352 dut->ap_sig_rts = VALUE_DISABLED; 353 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname); 354 if (system(buf) != 0) { 355 sigma_dut_print(dut, DUT_MSG_ERROR, 356 "iwconfig rts 2347 failed"); 357 } 358 } else { 359 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE"); 360 } 361 } 362 363 364 static void ath_radio(struct sigma_dut *dut, const char *val) 365 { 366 if (strcasecmp(val, "on") == 0) { 367 if (dut->ap_interface_5g == 1) { 368 run_system(dut, "uci set wireless.wifi0.disabled=0"); 369 } else if (dut->ap_interface_2g == 1) { 370 run_system(dut, "uci set wireless.wifi1.disabled=0"); 371 } else { 372 run_system(dut, "uci set wireless.wifi0.disabled=0"); 373 run_system(dut, "uci set wireless.wifi1.disabled=0"); 374 } 375 run_system(dut, "uci commit"); 376 run_system(dut, "wifi down"); 377 run_system(dut, "wifi up"); 378 } else if (strcasecmp(val, "off") == 0) { 379 if (dut->ap_interface_5g == 1) { 380 run_system(dut, "uci set wireless.wifi0.disabled=1"); 381 } else if (dut->ap_interface_2g == 1) { 382 run_system(dut, "uci set wireless.wifi1.disabled=1"); 383 } else { 384 run_system(dut, "uci set wireless.wifi0.disabled=1"); 385 run_system(dut, "uci set wireless.wifi1.disabled=1"); 386 } 387 run_system(dut, "uci commit"); 388 run_system(dut, "wifi down"); 389 run_system(dut, "wifi up"); 390 } 391 } 392 393 394 static void deauth_disassoc(struct sigma_dut *dut, const char *ifname, 395 const char *val) 396 { 397 if (strcasecmp(val, "disable") == 0) 398 run_iwpriv(dut, ifname, "stealthdown 1"); 399 } 400 401 402 static void ath_set_txpower(struct sigma_dut *dut, const char *ifname, 403 const char *val) 404 { 405 char buf[60]; 406 407 if (strcasecmp(val, "high") == 0) 408 snprintf(buf, sizeof(buf), "iwconfig %s txpower 29", ifname); 409 else if (strcasecmp(val, "low") == 0) 410 snprintf(buf, sizeof(buf), "iwconfig %s txpower 1", ifname); 411 else 412 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported txpower"); 413 414 if (system(buf) != 0) 415 sigma_dut_print(dut, DUT_MSG_ERROR, "setting txpower failed"); 416 } 417 418 419 static enum ap_mode get_mode(const char *str) 420 { 421 if (strcasecmp(str, "11a") == 0) 422 return AP_11a; 423 else if (strcasecmp(str, "11g") == 0) 424 return AP_11g; 425 else if (strcasecmp(str, "11b") == 0) 426 return AP_11b; 427 else if (strcasecmp(str, "11na") == 0) 428 return AP_11na; 429 else if (strcasecmp(str, "11ng") == 0) 430 return AP_11ng; 431 else if (strcasecmp(str, "11ac") == 0 || strcasecmp(str, "ac") == 0) 432 return AP_11ac; 433 else if (strcasecmp(str, "11ad") == 0) 434 return AP_11ad; 435 else if (strcasecmp(str, "11ax") == 0) 436 return AP_11ax; 437 else 438 return AP_inval; 439 } 440 441 442 static int run_hostapd_cli(struct sigma_dut *dut, char *buf) 443 { 444 char command[1000]; 445 const char *bin; 446 enum driver_type drv = get_driver_type(dut); 447 char *sigma_hapd_file = sigma_hapd_ctrl; 448 449 if (file_exists("hostapd_cli")) 450 bin = "./hostapd_cli"; 451 else if (file_exists("../../hostapd/hostapd_cli")) 452 bin = "../../hostapd/hostapd_cli"; 453 else 454 bin = "hostapd_cli"; 455 456 if (drv == DRIVER_OPENWRT && sigma_hapd_ctrl == NULL) { 457 sigma_hapd_file = "/var/run/hostapd-wifi0"; 458 459 if (sigma_radio_ifname[0] && 460 strcmp(sigma_radio_ifname[0], "wifi1") == 0) 461 sigma_hapd_file = "/var/run/hostapd-wifi1"; 462 else if (sigma_radio_ifname[0] && 463 strcmp(sigma_radio_ifname[0], "wifi2") == 0) 464 sigma_hapd_file = "/var/run/hostapd-wifi2"; 465 } 466 467 if (sigma_hapd_file) 468 snprintf(command, sizeof(command), "%s -p %s %s", 469 bin, sigma_hapd_file, buf); 470 else 471 snprintf(command, sizeof(command), "%s %s", bin, buf); 472 return run_system(dut, command); 473 } 474 475 476 static int ath_set_lci_config(struct sigma_dut *dut, const char *val, 477 struct sigma_cmd *cmd) 478 { 479 FILE *f; 480 int i; 481 482 f = fopen("/tmp/lci_cfg.txt", "w"); 483 if (!f) { 484 sigma_dut_print(dut, DUT_MSG_ERROR, 485 "Failed to open /tmp/lci_cfg.txt"); 486 return -1; 487 } 488 489 for (i = 2; i < cmd->count; i++) 490 fprintf(f, "%s = %s \n", cmd->params[i], cmd->values[i]); 491 fprintf(f, "\n"); 492 fclose(f); 493 494 return 0; 495 } 496 497 498 static void set_ap_country_code(struct sigma_dut *dut) 499 { 500 #if defined(ANDROID) || defined(LINUX_EMBEDDED) 501 char buf[256]; 502 503 if (dut->ap_countrycode[0]) { 504 snprintf(buf, sizeof(buf), "DRIVER COUNTRY %s", 505 dut->ap_countrycode); 506 if (wpa_command(get_station_ifname(dut), buf) < 0) 507 sigma_dut_print(dut, DUT_MSG_ERROR, 508 "Failed to set country code"); 509 else 510 sigma_dut_print(dut, DUT_MSG_INFO, 511 "Successfully set country code to %s", 512 dut->ap_countrycode); 513 } 514 #endif 515 } 516 517 518 static void set_vht_mcsmap_nss(struct sigma_dut *dut, int nss, int mcs) 519 { 520 switch (nss) { 521 case 1: 522 switch (mcs) { 523 case 7: 524 dut->ap_vhtmcs_map = 0xfffc; 525 break; 526 case 8: 527 dut->ap_vhtmcs_map = 0xfffd; 528 break; 529 case 9: 530 dut->ap_vhtmcs_map = 0xfffe; 531 break; 532 default: 533 dut->ap_vhtmcs_map = 0xfffe; 534 break; 535 } 536 break; 537 case 2: 538 switch (mcs) { 539 case 7: 540 dut->ap_vhtmcs_map = 0xfff0; 541 break; 542 case 8: 543 dut->ap_vhtmcs_map = 0xfff5; 544 break; 545 case 9: 546 dut->ap_vhtmcs_map = 0xfffa; 547 break; 548 default: 549 dut->ap_vhtmcs_map = 0xfffa; 550 break; 551 } 552 break; 553 case 3: 554 switch (mcs) { 555 case 7: 556 dut->ap_vhtmcs_map = 0xffc0; 557 break; 558 case 8: 559 dut->ap_vhtmcs_map = 0xffd5; 560 break; 561 case 9: 562 dut->ap_vhtmcs_map = 0xffea; 563 break; 564 default: 565 dut->ap_vhtmcs_map = 0xffea; 566 break; 567 } 568 default: 569 dut->ap_vhtmcs_map = 0xffea; 570 break; 571 } 572 } 573 574 575 /* Get 2*nss bitmask */ 576 /* We are trying to pack 2-bit MCS values per NSS in a 16-bit wide field. 577 * IEEE P802.11ax/D5.0, 9.4.2.247.4 supported HE-MCS And NSS Set field 578 * defines the following format for the 16 bit value. */ 579 580 #define HE_GET_MCS_NSS_PACK_MASK(nss) ((1 << ((nss) << 1)) - 1) 581 582 static void he_reset_mcs_values_for_unsupported_ss(uint8_t *mcsnssmap, 583 uint8_t nss) 584 { 585 uint8_t nssmask; 586 587 if (nss <= 4) { 588 nssmask = ~HE_GET_MCS_NSS_PACK_MASK(nss); 589 mcsnssmap[0] |= nssmask; 590 mcsnssmap[1] = 0xff; 591 } else if (nss > 4 && nss <= 8) { 592 nssmask = ~HE_GET_MCS_NSS_PACK_MASK(nss - 4); 593 mcsnssmap[0] &= 0xff; 594 mcsnssmap[1] |= nssmask; 595 } 596 } 597 598 599 static void get_he_mcs_nssmap(uint8_t *mcsnssmap, uint8_t nss, 600 uint8_t mcs) 601 { 602 switch (mcs) { 603 case 11: 604 mcsnssmap[0] = 0xaa; 605 mcsnssmap[1] = 0xaa; 606 break; 607 case 9: 608 mcsnssmap[0] = 0x55; 609 mcsnssmap[1] = 0x55; 610 break; 611 case 7: 612 mcsnssmap[0] = 0x0; 613 mcsnssmap[1] = 0x0; 614 break; 615 } 616 he_reset_mcs_values_for_unsupported_ss(mcsnssmap, nss); 617 } 618 619 620 static enum sigma_cmd_result cmd_ap_set_wireless(struct sigma_dut *dut, 621 struct sigma_conn *conn, 622 struct sigma_cmd *cmd) 623 { 624 /* const char *name = get_param(cmd, "NAME"); */ 625 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 626 const char *val; 627 unsigned int wlan_tag = 1; 628 const char *ifname = get_main_ifname(dut); 629 char buf[128]; 630 631 /* Allow program to be overridden if specified in the ap_set_wireless 632 * to support some 60 GHz test scripts where the program may be 60 GHz 633 * or WPS. */ 634 val = get_param(cmd, "PROGRAM"); 635 if (val) 636 dut->program = sigma_program_to_enum(val); 637 638 val = get_param(cmd, "WLAN_TAG"); 639 if (val) { 640 wlan_tag = atoi(val); 641 if (wlan_tag < 1 || wlan_tag > 3) { 642 /* 643 * The only valid WLAN Tags as of now as per the latest 644 * WFA scripts are 1, 2, and 3. 645 */ 646 send_resp(dut, conn, SIGMA_INVALID, 647 "errorCode,Invalid WLAN_TAG"); 648 return STATUS_SENT; 649 } 650 } 651 652 val = get_param(cmd, "Interface"); 653 if (val) { 654 if (strcasecmp(val, "5G") == 0) 655 dut->ap_interface_5g = 1; 656 else 657 dut->ap_interface_2g = 1; 658 659 if (dut->ap_interface_5g && dut->ap_interface_2g) 660 dut->ap_is_dual = 1; 661 } 662 663 val = get_param(cmd, "CountryCode"); 664 if (val) { 665 if (strlen(val) > sizeof(dut->ap_countrycode) - 1) 666 return INVALID_SEND_STATUS; 667 snprintf(dut->ap_countrycode, sizeof(dut->ap_countrycode), 668 "%s", val); 669 670 /* 671 * Regdomain self-managed driver does not accept hostapd country 672 * code setting in all cases. Try to use wpa_supplicant DRIVER 673 * command first to set the driver to a specific country code 674 * before starting AP functionality. This is targeting cases 675 * where wpa_supplicant is running on the device as well for 676 * non-AP mode functionality. 677 */ 678 if (get_driver_type(dut) == DRIVER_LINUX_WCN) 679 set_ap_country_code(dut); 680 } 681 682 val = get_param(cmd, "regulatory_mode"); 683 if (val) { 684 if (strcasecmp(val, "11d") == 0 || strcasecmp(val, "11h") == 0) 685 dut->ap_regulatory_mode = AP_80211D_MODE_ENABLED; 686 } 687 688 val = get_param(cmd, "SSID"); 689 if (val) { 690 if (strlen(val) > sizeof(dut->ap_ssid) - 1) 691 return INVALID_SEND_STATUS; 692 693 if (wlan_tag == 1) { 694 /* 695 * If tag is not specified, it is deemed to be 1. 696 * Hence tag of 1 is a special case and the values 697 * corresponding to wlan-tag=1 are stored separately 698 * from the values corresponding tags 2 and 3. 699 * This approach minimises the changes to existing code 700 * since most of the sigma_dut code does not deal with 701 * WLAN-TAG CAPI variable. 702 */ 703 snprintf(dut->ap_ssid, 704 sizeof(dut->ap_ssid), "%s", val); 705 } else { 706 snprintf(dut->ap_tag_ssid[wlan_tag - 2], 707 sizeof(dut->ap_tag_ssid[wlan_tag - 2]), 708 "%s", val); 709 } 710 } 711 712 val = get_param(cmd, "CHANNEL"); 713 if (val) { 714 const char *pos; 715 dut->ap_channel = atoi(val); 716 pos = strchr(val, ';'); 717 if (pos) { 718 pos++; 719 dut->ap_channel_1 = atoi(pos); 720 } 721 } 722 723 /* Overwrite the AP channel with DFS channel if configured */ 724 val = get_param(cmd, "dfs_chan"); 725 if (val) { 726 dut->ap_channel = atoi(val); 727 } 728 729 val = get_param(cmd, "dfs_mode"); 730 if (val) { 731 if (strcasecmp(val, "Enable") == 0) 732 dut->ap_dfs_mode = AP_DFS_MODE_ENABLED; 733 else if (strcasecmp(val, "Disable") == 0) 734 dut->ap_dfs_mode = AP_DFS_MODE_DISABLED; 735 else 736 sigma_dut_print(dut, DUT_MSG_ERROR, 737 "Unsupported dfs_mode value: %s", val); 738 } 739 740 val = get_param(cmd, "MODE"); 741 if (val) { 742 char *str, *pos; 743 744 str = strdup(val); 745 if (str == NULL) 746 return INVALID_SEND_STATUS; 747 pos = strchr(str, ';'); 748 if (pos) 749 *pos++ = '\0'; 750 751 dut->ap_is_dual = 0; 752 dut->ap_mode = get_mode(str); 753 if (dut->ap_mode == AP_inval) { 754 send_resp(dut, conn, SIGMA_INVALID, 755 "errorCode,Unsupported MODE"); 756 free(str); 757 return STATUS_SENT; 758 } 759 if (dut->ap_mode == AP_11ac && dut->ap_80plus80 != 1) 760 dut->ap_chwidth = AP_80; 761 762 if (pos) { 763 dut->ap_mode_1 = get_mode(pos); 764 if (dut->ap_mode_1 == AP_inval) { 765 send_resp(dut, conn, SIGMA_INVALID, 766 "errorCode,Unsupported MODE"); 767 free(str); 768 return STATUS_SENT; 769 } 770 if (dut->ap_mode_1 == AP_11ac) 771 dut->ap_chwidth_1 = AP_80; 772 dut->ap_is_dual = 1; 773 } 774 775 free(str); 776 } else if (dut->ap_mode == AP_inval) { 777 if (dut->ap_channel <= 11) 778 dut->ap_mode = AP_11ng; 779 else if (dut->program == PROGRAM_VHT) 780 dut->ap_mode = AP_11ac; 781 else 782 dut->ap_mode = AP_11na; 783 } 784 785 /* Override the AP mode in case of 60 GHz */ 786 if (dut->program == PROGRAM_60GHZ) { 787 dut->ap_mode = AP_11ad; 788 /* Workaround to force channel 2 if not specified */ 789 if (!dut->ap_channel) 790 dut->ap_channel = 2; 791 } 792 793 switch (dut->ap_mode) { 794 case AP_11g: 795 case AP_11b: 796 case AP_11ng: 797 dut->use_5g = 0; 798 break; 799 case AP_11a: 800 case AP_11na: 801 case AP_11ac: 802 dut->use_5g = 1; 803 break; 804 case AP_11ax: 805 if (dut->ap_channel >= 1 && dut->ap_channel <= 14) 806 dut->use_5g = 0; 807 else if (dut->ap_channel >= 36 && dut->ap_channel <= 171) 808 dut->use_5g = 1; 809 break; 810 case AP_11ad: 811 case AP_inval: 812 break; 813 } 814 815 val = get_param(cmd, "WME"); 816 if (val) { 817 if (strcasecmp(val, "on") == 0) 818 dut->ap_wme = AP_WME_ON; 819 else if (strcasecmp(val, "off") == 0) 820 dut->ap_wme = AP_WME_OFF; 821 else 822 sigma_dut_print(dut, DUT_MSG_ERROR, 823 "Unsupported WME value: %s", val); 824 } 825 826 val = get_param(cmd, "WMMPS"); 827 if (val) { 828 if (strcasecmp(val, "on") == 0) 829 dut->ap_wmmps = AP_WMMPS_ON; 830 else if (strcasecmp(val, "off") == 0) 831 dut->ap_wmmps = AP_WMMPS_OFF; 832 else 833 sigma_dut_print(dut, DUT_MSG_ERROR, 834 "Unsupported WMMPS value: %s", val); 835 } 836 837 val = get_param(cmd, "RTS"); 838 if (val) 839 dut->ap_rts = atoi(val); 840 841 val = get_param(cmd, "FRGMNT"); 842 if (val) 843 dut->ap_frgmnt = atoi(val); 844 845 /* TODO: PWRSAVE */ 846 847 val = get_param(cmd, "BCNINT"); 848 if (val) 849 dut->ap_bcnint = atoi(val); 850 851 val = get_param(cmd, "RADIO"); 852 if (val) { 853 enum driver_type drv = get_driver_type(dut); 854 855 if (strcasecmp(val, "on") == 0) { 856 if (drv == DRIVER_OPENWRT) 857 ath_radio(dut, val); 858 if (drv == DRIVER_ATHEROS) 859 ath_ap_start_hostapd(dut); 860 else if (cmd_ap_config_commit(dut, conn, cmd) <= 0) 861 return STATUS_SENT; 862 } else if (strcasecmp(val, "off") == 0) { 863 if (drv == DRIVER_OPENWRT) { 864 ath_radio(dut, val); 865 } else if (dut->use_hostapd_pid_file) { 866 kill_hostapd_process_pid(dut); 867 } else if (kill_process(dut, "(hostapd)", 1, 868 SIGTERM) == 0 || 869 system("killall hostapd") == 0) { 870 sigma_dut_print(dut, DUT_MSG_INFO, 871 "Killed hostapd on radio,off"); 872 } 873 } else { 874 send_resp(dut, conn, SIGMA_INVALID, 875 "errorCode,Unsupported RADIO value"); 876 return STATUS_SENT; 877 } 878 } 879 880 val = get_param(cmd, "P2PMgmtBit"); 881 if (val) 882 dut->ap_p2p_mgmt = atoi(val); 883 884 /* TODO: ChannelUsage */ 885 886 /* TODO: 40_INTOLERANT */ 887 888 val = get_param(cmd, "ADDBA_REJECT"); 889 if (val) { 890 if (strcasecmp(val, "Enable") == 0) 891 dut->ap_addba_reject = VALUE_ENABLED; 892 else if (strcasecmp(val, "Disable") == 0) 893 dut->ap_addba_reject = VALUE_DISABLED; 894 } 895 896 val = get_param(cmd, "AMPDU"); 897 if (val) { 898 if (strcasecmp(val, "Enable") == 0) 899 dut->ap_ampdu = VALUE_ENABLED; 900 else if (strcasecmp(val, "Disable") == 0) 901 dut->ap_ampdu = VALUE_DISABLED; 902 } 903 904 val = get_param(cmd, "AMPDU_EXP"); 905 if (val) 906 dut->ap_ampdu_exp = atoi(val); 907 908 val = get_param(cmd, "AMSDU"); 909 if (val) { 910 if (strcasecmp(val, "Enable") == 0) 911 dut->ap_amsdu = VALUE_ENABLED; 912 else if (strcasecmp(val, "Disable") == 0) 913 dut->ap_amsdu = VALUE_DISABLED; 914 } 915 916 val = get_param(cmd, "NoAck"); 917 if (val) { 918 if (strcasecmp(val, "on") == 0) 919 dut->ap_noack = VALUE_ENABLED; 920 else if (strcasecmp(val, "off") == 0) 921 dut->ap_noack = VALUE_DISABLED; 922 } 923 924 /* TODO: GREENFIELD */ 925 /* TODO: MCS_32 */ 926 927 val = get_param(cmd, "OFFSET"); 928 if (val) { 929 if (strcasecmp(val, "Above") == 0) 930 dut->ap_chwidth_offset = SEC_CH_40ABOVE; 931 else if (strcasecmp(val, "Below") == 0) 932 dut->ap_chwidth_offset = SEC_CH_40BELOW; 933 } 934 935 val = get_param(cmd, "MCS_FIXEDRATE"); 936 if (val) { 937 dut->ap_fixed_rate = 1; 938 dut->ap_mcs = atoi(val); 939 } 940 941 val = get_param(cmd, "SPATIAL_RX_STREAM"); 942 if (val) { 943 if (strcasecmp(val, "1SS") == 0 || strcasecmp(val, "1") == 0) { 944 dut->ap_rx_streams = 1; 945 if (dut->device_type == AP_testbed) 946 dut->ap_vhtmcs_map = 0xfffc; 947 } else if (strcasecmp(val, "2SS") == 0 || 948 strcasecmp(val, "2") == 0) { 949 dut->ap_rx_streams = 2; 950 if (dut->device_type == AP_testbed) 951 dut->ap_vhtmcs_map = 0xfff0; 952 } else if (strcasecmp(val, "3SS") == 0 || 953 strcasecmp(val, "3") == 0) { 954 dut->ap_rx_streams = 3; 955 if (dut->device_type == AP_testbed) 956 dut->ap_vhtmcs_map = 0xffc0; 957 } else if (strcasecmp(val, "4SS") == 0 || 958 strcasecmp(val, "4") == 0) { 959 dut->ap_rx_streams = 4; 960 } 961 } 962 963 val = get_param(cmd, "SPATIAL_TX_STREAM"); 964 if (val) { 965 if (strcasecmp(val, "1SS") == 0 || 966 strcasecmp(val, "1") == 0) { 967 dut->ap_tx_streams = 1; 968 if (dut->device_type == AP_testbed) 969 dut->ap_vhtmcs_map = 0xfffc; 970 } else if (strcasecmp(val, "2SS") == 0 || 971 strcasecmp(val, "2") == 0) { 972 dut->ap_tx_streams = 2; 973 if (dut->device_type == AP_testbed) 974 dut->ap_vhtmcs_map = 0xfff0; 975 } else if (strcasecmp(val, "3SS") == 0 || 976 strcasecmp(val, "3") == 0) { 977 dut->ap_tx_streams = 3; 978 if (dut->device_type == AP_testbed) 979 dut->ap_vhtmcs_map = 0xffc0; 980 } else if (strcasecmp(val, "4SS") == 0 || 981 strcasecmp(val, "4") == 0) { 982 dut->ap_tx_streams = 4; 983 } 984 } 985 986 val = get_param(cmd, "BSS_max_idle"); 987 if (val) { 988 if (strncasecmp(val, "Enable", 7) == 0) { 989 dut->wnm_bss_max_feature = VALUE_ENABLED; 990 } else if (strncasecmp(val, "Disable", 8) == 0) { 991 dut->wnm_bss_max_feature = VALUE_DISABLED; 992 } else { 993 send_resp(dut, conn, SIGMA_ERROR, 994 "errorCode,Invalid value for BSS_max_Feature"); 995 return STATUS_SENT; 996 } 997 } 998 999 val = get_param(cmd, "BSS_Idle_Protection_options"); 1000 if (val) { 1001 int protection = (int) strtol(val, (char **) NULL, 10); 1002 1003 if (protection != 1 && protection != 0) { 1004 send_resp(dut, conn, SIGMA_ERROR, 1005 "errorCode,Invalid value for BSS_Idle_Protection_options"); 1006 return STATUS_SENT; 1007 } 1008 dut->wnm_bss_max_protection = protection ? 1009 VALUE_ENABLED : VALUE_DISABLED; 1010 } 1011 1012 val = get_param(cmd, "BSS_max_Idle_period"); 1013 if (val) { 1014 long int idle_time = strtol(val, (char **) NULL, 10); 1015 1016 if (idle_time == LONG_MIN || idle_time == LONG_MAX) { 1017 send_resp(dut, conn, SIGMA_ERROR, 1018 "errorCode,Invalid value for BSS_max_Idle_period"); 1019 return STATUS_SENT; 1020 } 1021 dut->wnm_bss_max_idle_time = (int) idle_time; 1022 } 1023 1024 val = get_param(cmd, "PROXY_ARP"); 1025 if (val) 1026 dut->ap_proxy_arp = (int) strtol(val, (char **) NULL, 10); 1027 1028 val = get_param(cmd, "nss_mcs_cap"); 1029 if (val) { 1030 int nss, mcs; 1031 char token[20]; 1032 char *result = NULL; 1033 char *saveptr; 1034 1035 if (strlen(val) >= sizeof(token)) 1036 return INVALID_SEND_STATUS; 1037 strlcpy(token, val, sizeof(token)); 1038 result = strtok_r(token, ";", &saveptr); 1039 if (!result) { 1040 send_resp(dut, conn, SIGMA_ERROR, 1041 "errorCode,VHT NSS not specified"); 1042 return STATUS_SENT; 1043 } 1044 nss = atoi(result); 1045 result = strtok_r(NULL, ";", &saveptr); 1046 if (result == NULL) { 1047 send_resp(dut, conn, SIGMA_ERROR, 1048 "errorCode,VHTMCS not specified"); 1049 return STATUS_SENT; 1050 } 1051 result = strtok_r(result, "-", &saveptr); 1052 result = strtok_r(NULL, "-", &saveptr); 1053 if (!result) { 1054 send_resp(dut, conn, SIGMA_ERROR, 1055 "errorCode,VHT MCS not specified"); 1056 return STATUS_SENT; 1057 } 1058 mcs = atoi(result); 1059 if (dut->program == PROGRAM_HE) { 1060 uint16_t mcsnssmap = 0; 1061 1062 get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs); 1063 dut->he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap; 1064 dut->he_ul_mcs = mcs; 1065 } else { 1066 set_vht_mcsmap_nss(dut, nss, mcs); 1067 } 1068 } 1069 1070 /* TODO: MPDU_MIN_START_SPACING */ 1071 /* TODO: RIFS_TEST */ 1072 /* TODO: SGI20 */ 1073 1074 val = get_param(cmd, "STBC_TX"); 1075 if (val) 1076 dut->ap_tx_stbc = atoi(val); 1077 1078 val = get_param(cmd, "WIDTH"); 1079 if (val) { 1080 if (strcasecmp(val, "20") == 0) 1081 dut->ap_chwidth = AP_20; 1082 else if (strcasecmp(val, "40") == 0) 1083 dut->ap_chwidth = AP_40; 1084 else if (strcasecmp(val, "80") == 0) 1085 dut->ap_chwidth = AP_80; 1086 else if (strcasecmp(val, "160") == 0) 1087 dut->ap_chwidth = AP_160; 1088 else if (strcasecmp(val, "80plus80") == 0) { 1089 dut->ap_80plus80 = 1; 1090 dut->ap_chwidth = AP_80_80; 1091 } else if (strcasecmp(val, "Auto") == 0) 1092 dut->ap_chwidth = AP_AUTO; 1093 else { 1094 send_resp(dut, conn, SIGMA_INVALID, 1095 "errorCode,Unsupported WIDTH"); 1096 return STATUS_SENT; 1097 } 1098 } 1099 1100 /* TODO: WIDTH_SCAN */ 1101 1102 val = get_param(cmd, "TDLSProhibit"); 1103 dut->ap_tdls_prohibit = val && strcasecmp(val, "Enabled") == 0; 1104 val = get_param(cmd, "TDLSChswitchProhibit"); 1105 dut->ap_tdls_prohibit_chswitch = 1106 val && strcasecmp(val, "Enabled") == 0; 1107 val = get_param(cmd, "HS2"); 1108 if (val && wlan_tag == 1) 1109 dut->ap_hs2 = atoi(val); 1110 val = get_param(cmd, "P2P_CROSS_CONNECT"); 1111 if (val) 1112 dut->ap_p2p_cross_connect = strcasecmp(val, "Enabled") == 0; 1113 1114 val = get_param(cmd, "FakePubKey"); 1115 dut->ap_fake_pkhash = val && atoi(val); 1116 1117 val = get_param(cmd, "vht_tkip"); 1118 dut->ap_allow_vht_tkip = val && strcasecmp(val, "Enable") == 0; 1119 val = get_param(cmd, "vht_wep"); 1120 dut->ap_allow_vht_wep = val && strcasecmp(val, "Enable") == 0; 1121 1122 val = get_param(cmd, "Protect_mode"); 1123 dut->ap_disable_protection = val && strcasecmp(val, "Disable") == 0; 1124 1125 val = get_param(cmd, "DYN_BW_SGNL"); 1126 if (val) { 1127 switch (get_driver_type(dut)) { 1128 case DRIVER_OPENWRT: 1129 switch (get_openwrt_driver_type()) { 1130 case OPENWRT_DRIVER_ATHEROS: 1131 ath_config_dyn_bw_sig(dut, ifname, val); 1132 break; 1133 default: 1134 send_resp(dut, conn, SIGMA_ERROR, 1135 "errorCode,Unsupported DYN_BW_SGNL with OpenWrt driver"); 1136 return STATUS_SENT; 1137 } 1138 break; 1139 case DRIVER_WCN: 1140 case DRIVER_LINUX_WCN: 1141 ath_config_dyn_bw_sig(dut, ifname, val); 1142 break; 1143 default: 1144 sigma_dut_print(dut, DUT_MSG_ERROR, 1145 "Unsupported DYN_BW_SGL with the current driver"); 1146 break; 1147 } 1148 } 1149 1150 val = get_param(cmd, "SGI80"); 1151 if (val) { 1152 if (strcasecmp(val, "enable") == 0) 1153 dut->ap_sgi80 = 1; 1154 else if (strcasecmp(val, "disable") == 0) 1155 dut->ap_sgi80 = 0; 1156 else { 1157 send_resp(dut, conn, SIGMA_INVALID, 1158 "errorCode,Unsupported SGI80"); 1159 return STATUS_SENT; 1160 } 1161 } 1162 1163 val = get_param(cmd, "LDPC"); 1164 if (val) { 1165 if (strcasecmp(val, "enable") == 0) 1166 dut->ap_ldpc = VALUE_ENABLED; 1167 else if (strcasecmp(val, "disable") == 0) 1168 dut->ap_ldpc = VALUE_DISABLED; 1169 else { 1170 send_resp(dut, conn, SIGMA_INVALID, 1171 "errorCode,Unsupported LDPC"); 1172 return STATUS_SENT; 1173 } 1174 switch (get_driver_type(dut)) { 1175 case DRIVER_WCN: 1176 case DRIVER_LINUX_WCN: 1177 wcn_config_ap_ldpc(dut, ifname); 1178 break; 1179 default: 1180 break; 1181 } 1182 } 1183 1184 val = get_param(cmd, "BW_SGNL"); 1185 if (val) { 1186 /* 1187 * With dynamic bandwidth signaling enabled we should see 1188 * RTS if the threshold is met. 1189 */ 1190 if (strcasecmp(val, "enable") == 0) { 1191 dut->ap_sig_rts = VALUE_ENABLED; 1192 } else if (strcasecmp(val, "disable") == 0) { 1193 dut->ap_sig_rts = VALUE_DISABLED; 1194 } else { 1195 send_resp(dut, conn, SIGMA_INVALID, 1196 "errorCode,Unsupported BW_SGNL"); 1197 return STATUS_SENT; 1198 } 1199 } 1200 1201 val = get_param(cmd, "RTS_FORCE"); 1202 if (val) { 1203 switch (get_driver_type(dut)) { 1204 case DRIVER_OPENWRT: 1205 switch (get_openwrt_driver_type()) { 1206 case OPENWRT_DRIVER_ATHEROS: 1207 ath_config_rts_force(dut, ifname, val); 1208 break; 1209 default: 1210 send_resp(dut, conn, SIGMA_ERROR, 1211 "errorCode,Unsupported RTS_FORCE with OpenWrt driver"); 1212 return STATUS_SENT; 1213 } 1214 break; 1215 case DRIVER_MAC80211: 1216 mac80211_config_rts_force(dut, ifname, val); 1217 break; 1218 default: 1219 sigma_dut_print(dut, DUT_MSG_ERROR, 1220 "Unsupported RTS_FORCE with the current driver"); 1221 break; 1222 } 1223 } 1224 1225 val = get_param(cmd, "Zero_crc"); 1226 if (val) { 1227 switch (get_driver_type(dut)) { 1228 case DRIVER_ATHEROS: 1229 ath_set_zero_crc(dut, val); 1230 break; 1231 case DRIVER_OPENWRT: 1232 switch (get_openwrt_driver_type()) { 1233 case OPENWRT_DRIVER_ATHEROS: 1234 ath_set_zero_crc(dut, val); 1235 break; 1236 default: 1237 send_resp(dut, conn, SIGMA_ERROR, 1238 "errorCode,Unsupported zero_crc with the current driver"); 1239 return STATUS_SENT; 1240 } 1241 break; 1242 default: 1243 send_resp(dut, conn, SIGMA_ERROR, 1244 "errorCode,Unsupported zero_crc with the current driver"); 1245 return STATUS_SENT; 1246 } 1247 } 1248 1249 val = get_param(cmd, "TxBF"); 1250 if (val) { 1251 dut->ap_txBF = strcasecmp(val, "enable") == 0; 1252 dut->he_sounding = VALUE_DISABLED; 1253 dut->he_set_sta_1x1 = VALUE_ENABLED; 1254 } 1255 1256 val = get_param(cmd, "MU_TxBF"); 1257 if (val) { 1258 if (strcasecmp(val, "enable") == 0) { 1259 dut->ap_txBF = 1; 1260 dut->ap_mu_txBF = 1; 1261 dut->he_sounding = VALUE_DISABLED; 1262 } else if (strcasecmp(val, "disable") == 0) { 1263 dut->ap_txBF = 0; 1264 dut->ap_mu_txBF = 0; 1265 } else { 1266 sigma_dut_print(dut, DUT_MSG_ERROR, 1267 "Unsupported MU_TxBF"); 1268 } 1269 } 1270 1271 /* UNSUPPORTED: tx_lgi_rate */ 1272 1273 val = get_param(cmd, "wpsnfc"); 1274 if (val) 1275 dut->ap_wpsnfc = atoi(val); 1276 1277 val = get_param(cmd, "GROUP_ID"); 1278 if (val) { 1279 switch (get_driver_type(dut)) { 1280 case DRIVER_OPENWRT: 1281 switch (get_openwrt_driver_type()) { 1282 case OPENWRT_DRIVER_ATHEROS: 1283 ath_ap_set_group_id(dut, ifname, val); 1284 break; 1285 default: 1286 send_resp(dut, conn, SIGMA_ERROR, 1287 "errorCode,Unsupported group_id with the current driver"); 1288 return STATUS_SENT; 1289 } 1290 break; 1291 default: 1292 send_resp(dut, conn, SIGMA_ERROR, 1293 "errorCode,Unsupported group_id with the current driver"); 1294 return STATUS_SENT; 1295 } 1296 } 1297 1298 val = get_param(cmd, "CTS_WIDTH"); 1299 if (val) { 1300 switch (get_driver_type(dut)) { 1301 case DRIVER_OPENWRT: 1302 switch (get_openwrt_driver_type()) { 1303 case OPENWRT_DRIVER_ATHEROS: 1304 ath_set_cts_width(dut, ifname, val); 1305 break; 1306 default: 1307 send_resp(dut, conn, SIGMA_ERROR, 1308 "errorCode,Unsupported cts_width with the current driver"); 1309 return STATUS_SENT; 1310 } 1311 break; 1312 default: 1313 send_resp(dut, conn, SIGMA_ERROR, 1314 "errorCode,Unsupported cts_width with the current driver"); 1315 return STATUS_SENT; 1316 } 1317 } 1318 1319 val = get_param(cmd, "MU_NDPA_FrameFormat"); 1320 if (val) 1321 dut->ap_ndpa_frame = atoi(val); 1322 1323 val = get_param(cmd, "interworking"); 1324 if (val && strcmp(val, "1") == 0) 1325 dut->ap_interworking = 1; 1326 1327 val = get_param(cmd, "GAS_CB_DELAY"); 1328 if (val) 1329 dut->ap_gas_cb_delay = atoi(val); 1330 1331 val = get_param(cmd, "LCI"); 1332 if (val) { 1333 if (strlen(val) > sizeof(dut->ap_val_lci) - 1) 1334 return INVALID_SEND_STATUS; 1335 dut->ap_lci = 1; 1336 snprintf(dut->ap_val_lci, sizeof(dut->ap_val_lci), "%s", val); 1337 ath_set_lci_config(dut, val, cmd); 1338 } 1339 1340 val = get_param(cmd, "InfoZ"); 1341 if (val) { 1342 if (strlen(val) > sizeof(dut->ap_infoz) - 1) 1343 return INVALID_SEND_STATUS; 1344 snprintf(dut->ap_infoz, sizeof(dut->ap_infoz), "%s", val); 1345 } 1346 1347 val = get_param(cmd, "LocCivicAddr"); 1348 if (val) { 1349 if (strlen(val) > sizeof(dut->ap_val_lcr) - 1) 1350 return INVALID_SEND_STATUS; 1351 dut->ap_lcr = 1; 1352 snprintf(dut->ap_val_lcr, sizeof(dut->ap_val_lcr), "%s", val); 1353 if (dut->ap_lci == 0) 1354 ath_set_lci_config(dut, val, cmd); 1355 } 1356 1357 val = get_param(cmd, "NeighAPBSSID"); 1358 if (val) { 1359 if (dut->ap_neighap < 3) { 1360 if (parse_mac_address( 1361 dut, val, 1362 dut->ap_val_neighap[dut->ap_neighap]) < 0) { 1363 send_resp(dut, conn, SIGMA_INVALID, 1364 "Failed to parse MAC address"); 1365 return STATUS_SENT; 1366 } 1367 dut->ap_neighap++; 1368 if (dut->ap_lci == 1) 1369 dut->ap_scan = 1; 1370 } 1371 } 1372 1373 val = get_param(cmd, "OpChannel"); 1374 if (val) { 1375 if (dut->ap_opchannel < 3) { 1376 dut->ap_val_opchannel[dut->ap_opchannel] = atoi(val); 1377 dut->ap_opchannel++; 1378 } 1379 } 1380 1381 val = get_param(cmd, "URI-FQDNdescriptor"); 1382 if (val) { 1383 if (strcasecmp(val, "HELD") == 0) { 1384 dut->ap_fqdn_held = 1; 1385 } else if (strcasecmp(val, "SUPL") == 0) { 1386 dut->ap_fqdn_supl = 1; 1387 } else { 1388 send_resp(dut, conn, SIGMA_INVALID, 1389 "errorCode,Unsupported URI-FQDNdescriptor"); 1390 return STATUS_SENT; 1391 } 1392 } 1393 1394 val = get_param(cmd, "Reg_Domain"); 1395 if (val) { 1396 if (strcasecmp(val, "Local") == 0) { 1397 dut->ap_reg_domain = REG_DOMAIN_LOCAL; 1398 } else if (strcasecmp(val, "Global") == 0) { 1399 dut->ap_reg_domain = REG_DOMAIN_GLOBAL; 1400 } else { 1401 send_resp(dut, conn, SIGMA_ERROR, 1402 "errorCode,Wrong value for Reg_Domain"); 1403 return STATUS_SENT; 1404 } 1405 } 1406 1407 val = get_param(cmd, "NAME"); 1408 if (val) { 1409 if (strcasecmp(val, "ap1mbo") == 0) 1410 dut->ap_name = 1; 1411 else if (strcasecmp(val, "ap2mbo") == 0) 1412 dut->ap_name = 2; 1413 else 1414 dut->ap_name = 0; 1415 } 1416 1417 val = get_param(cmd, "FT_OA"); 1418 if (val) { 1419 if (strcasecmp(val, "Enable") == 0) { 1420 dut->ap_ft_oa = 1; 1421 } else if (strcasecmp(val, "Disable") == 0) { 1422 dut->ap_ft_oa = 0; 1423 } else { 1424 send_resp(dut, conn, SIGMA_ERROR, 1425 "errorCode,Wrong value for FT_OA"); 1426 return STATUS_SENT; 1427 } 1428 } 1429 1430 val = get_param(cmd, "FT_DS"); 1431 if (val) { 1432 if (strcasecmp(val, "Enable") == 0) { 1433 dut->ap_ft_ds = VALUE_ENABLED; 1434 } else if (strcasecmp(val, "Disable") == 0) { 1435 dut->ap_ft_ds = VALUE_DISABLED; 1436 } else { 1437 send_resp(dut, conn, SIGMA_ERROR, 1438 "errorCode,Unsupported value for FT_DS"); 1439 return STATUS_SENT_ERROR; 1440 } 1441 } 1442 1443 val = get_param(cmd, "Cellular_Cap_Pref"); 1444 if (val) 1445 dut->ap_cell_cap_pref = atoi(val); 1446 1447 val = get_param(cmd, "DOMAIN"); 1448 if (val) { 1449 if (strlen(val) >= sizeof(dut->ap_mobility_domain)) { 1450 send_resp(dut, conn, SIGMA_ERROR, 1451 "errorCode,Too long DOMAIN"); 1452 return STATUS_SENT; 1453 } 1454 snprintf(dut->ap_mobility_domain, 1455 sizeof(dut->ap_mobility_domain), "%s", val); 1456 } 1457 1458 val = get_param(cmd, "ft_bss_list"); 1459 if (val) { 1460 char *mac_str; 1461 int i; 1462 char *saveptr; 1463 char *mac_list_str; 1464 1465 mac_list_str = strdup(val); 1466 if (!mac_list_str) 1467 return INVALID_SEND_STATUS; 1468 mac_str = strtok_r(mac_list_str, " ", &saveptr); 1469 for (i = 0; mac_str && i < MAX_FT_BSS_LIST; i++) { 1470 if (parse_mac_address(dut, mac_str, 1471 dut->ft_bss_mac_list[i]) < 0) { 1472 sigma_dut_print(dut, DUT_MSG_ERROR, 1473 "MAC Address not in proper format"); 1474 break; 1475 } 1476 dut->ft_bss_mac_cnt++; 1477 mac_str = strtok_r(NULL, " ", &saveptr); 1478 } 1479 sigma_dut_print(dut, DUT_MSG_DEBUG, 1480 "Storing the following FT BSS MAC List"); 1481 for (i = 0; i < dut->ft_bss_mac_cnt; i++) { 1482 sigma_dut_print(dut, DUT_MSG_DEBUG, 1483 "MAC[%d] %02x:%02x:%02x:%02x:%02x:%02x", 1484 i, 1485 dut->ft_bss_mac_list[i][0], 1486 dut->ft_bss_mac_list[i][1], 1487 dut->ft_bss_mac_list[i][2], 1488 dut->ft_bss_mac_list[i][3], 1489 dut->ft_bss_mac_list[i][4], 1490 dut->ft_bss_mac_list[i][5]); 1491 } 1492 free(mac_list_str); 1493 } 1494 1495 val = get_param(cmd, "OCESupport"); 1496 if (val) { 1497 if (strcasecmp(val, "enable") == 0) { 1498 dut->ap_oce = VALUE_ENABLED; 1499 } else if (strcasecmp(val, "disable") == 0) { 1500 dut->ap_oce = VALUE_DISABLED; 1501 dut->ap_filsdscv = VALUE_DISABLED; 1502 } else { 1503 send_resp(dut, conn, SIGMA_INVALID, 1504 "errorCode,Unsupported OCE"); 1505 return STATUS_SENT; 1506 } 1507 } 1508 1509 val = get_param(cmd, "FILSDscvInterval"); 1510 if (val) 1511 dut->ap_fils_dscv_int = atoi(val); 1512 1513 val = get_param(cmd, "BroadcastSSID"); 1514 if (val) { 1515 if (strcasecmp(val, "enable") == 0) { 1516 dut->ap_broadcast_ssid = VALUE_ENABLED; 1517 } else if (strcasecmp(val, "disable") == 0) { 1518 dut->ap_broadcast_ssid = VALUE_DISABLED; 1519 } else { 1520 send_resp(dut, conn, SIGMA_INVALID, 1521 "errorCode,Unsupported hidden SSID"); 1522 return STATUS_SENT; 1523 } 1524 } 1525 1526 val = get_param(cmd, "FILSDscv"); 1527 if (val) { 1528 if (strcasecmp(val, "enable") == 0) { 1529 dut->ap_filsdscv = VALUE_ENABLED; 1530 } else if (strcasecmp(val, "disable") == 0) { 1531 dut->ap_filsdscv = VALUE_DISABLED; 1532 } else { 1533 send_resp(dut, conn, SIGMA_INVALID, 1534 "errorCode,Unsupported FILSDscv"); 1535 return STATUS_SENT; 1536 } 1537 } 1538 1539 val = get_param(cmd, "FILSHLP"); 1540 if (val) { 1541 if (strcasecmp(val, "enable") == 0) { 1542 dut->ap_filshlp = VALUE_ENABLED; 1543 } else if (strcasecmp(val, "disable") == 0) { 1544 dut->ap_filshlp = VALUE_DISABLED; 1545 } else { 1546 send_resp(dut, conn, SIGMA_INVALID, 1547 "errorCode,Unsupported FILSHLP"); 1548 return STATUS_SENT; 1549 } 1550 } 1551 1552 val = get_param(cmd, "NAIRealm"); 1553 if (val) { 1554 dut->ap_nairealm_int = 1; 1555 if (strlen(val) > sizeof(dut->ap_nairealm) - 1) 1556 return INVALID_SEND_STATUS; 1557 snprintf(dut->ap_nairealm, sizeof(dut->ap_nairealm), "%s", val); 1558 } 1559 1560 val = get_param(cmd, "DeauthDisassocTx"); 1561 if (val) { 1562 if (strcasecmp(val, "disable") == 0) { 1563 deauth_disassoc(dut, ifname, val); 1564 } else { 1565 send_resp(dut, conn, SIGMA_INVALID, 1566 "errorCode,Unsupported DeauthDisassocTx"); 1567 return STATUS_SENT; 1568 } 1569 } 1570 1571 val = get_param(cmd, "RNR"); 1572 if (val) { 1573 if (strcasecmp(val, "enable") == 0) { 1574 dut->ap_rnr = VALUE_ENABLED; 1575 } else if (strcasecmp(val, "disable") == 0) { 1576 dut->ap_rnr = VALUE_DISABLED; 1577 } else { 1578 send_resp(dut, conn, SIGMA_INVALID, 1579 "errorCode,Unsupported RNR"); 1580 return STATUS_SENT; 1581 } 1582 } 1583 1584 val = get_param(cmd, "BLEChannelUtil"); 1585 if (val) 1586 dut->ap_blechanutil = atoi(val); 1587 1588 val = get_param(cmd, "BLEAvailAdminCap"); 1589 if (val) 1590 dut->ap_ble_admit_cap = atoi(val); 1591 1592 val = get_param(cmd, "DataPPDUDuration"); 1593 if (val) 1594 dut->ap_datappdudura = atoi(val); 1595 1596 val = get_param(cmd, "AirTimeFract"); 1597 if (val) 1598 dut->ap_airtimefract = atoi(val); 1599 1600 val = get_param(cmd, "dhcpServIPADDR"); 1601 if (val) { 1602 if (strlen(val) > sizeof(dut->ap_dhcpserv_ipaddr) - 1) 1603 return INVALID_SEND_STATUS; 1604 snprintf(dut->ap_dhcpserv_ipaddr, 1605 sizeof(dut->ap_dhcpserv_ipaddr), "%s", val); 1606 dut->ap_dhcp_stop = 1; 1607 } 1608 1609 val = get_param(cmd, "ESP_IE"); 1610 if (val) { 1611 if (strcasecmp(val, "enable") == 0) { 1612 dut->ap_esp = VALUE_ENABLED; 1613 } else if (strcasecmp(val, "disable") == 0) { 1614 dut->ap_esp = VALUE_DISABLED; 1615 } else { 1616 send_resp(dut, conn, SIGMA_INVALID, 1617 "errorCode,Unsupported ESP_IE"); 1618 return STATUS_SENT; 1619 } 1620 } 1621 1622 val = get_param(cmd, "BAWinSize"); 1623 if (val) 1624 dut->ap_bawinsize = atoi(val); 1625 1626 val = get_param(cmd, "BLEStaCount"); 1627 if (val) 1628 dut->ap_blestacnt = atoi(val); 1629 1630 val = get_param(cmd, "PPDUTxType"); 1631 if (val) { 1632 if (strcasecmp(val, "MU") == 0) { 1633 dut->ap_he_ppdu = PPDU_MU; 1634 } else if (strcasecmp(val, "HE-SU") == 0) { 1635 /* Do nothing */ 1636 } else if (strcasecmp(val, "SU") == 0) { 1637 /* Do nothing */ 1638 } else if (strcasecmp(val, "legacy") == 0) { 1639 /* Do nothing */ 1640 } else if (strcasecmp(val, "ER") == 0) { 1641 /* Do nothing */ 1642 } else if (strcasecmp(val, "TB") == 0) { 1643 /* Do nothing */ 1644 } else { 1645 send_resp(dut, conn, SIGMA_ERROR, 1646 "errorCode,Unsupported PPDUTxType"); 1647 return STATUS_SENT_ERROR; 1648 } 1649 } 1650 1651 val = get_param(cmd, "WscIEFragment"); 1652 if (val && strcasecmp(val, "enable") == 0) { 1653 sigma_dut_print(dut, DUT_MSG_DEBUG, 1654 "Enable WSC IE fragmentation"); 1655 dut->wsc_fragment = 1; 1656 } 1657 1658 val = get_param(cmd, "WpsVersion"); 1659 if (val) 1660 dut->wps_forced_version = get_wps_forced_version(dut, val); 1661 1662 val = get_param(cmd, "WscEAPFragment"); 1663 if (val && strcasecmp(val, "enable") == 0) 1664 dut->eap_fragment = 1; 1665 1666 val = get_param(cmd, "MSDUSize"); 1667 if (val) { 1668 int mtu; 1669 1670 dut->amsdu_size = atoi(val); 1671 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG || 1672 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) { 1673 sigma_dut_print(dut, DUT_MSG_ERROR, 1674 "MSDUSize %d is above max %d or below min %d", 1675 dut->amsdu_size, 1676 IEEE80211_MAX_DATA_LEN_DMG, 1677 IEEE80211_SNAP_LEN_DMG); 1678 dut->amsdu_size = 0; 1679 return ERROR_SEND_STATUS; 1680 } 1681 1682 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG; 1683 sigma_dut_print(dut, DUT_MSG_DEBUG, 1684 "Setting amsdu_size to %d", mtu); 1685 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d", 1686 get_station_ifname(dut), mtu); 1687 1688 if (system(buf) != 0) { 1689 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s", 1690 buf); 1691 return ERROR_SEND_STATUS; 1692 } 1693 } 1694 1695 val = get_param(cmd, "BAckRcvBuf"); 1696 if (val) { 1697 dut->back_rcv_buf = atoi(val); 1698 if (dut->back_rcv_buf == 0) { 1699 sigma_dut_print(dut, DUT_MSG_ERROR, 1700 "Failed to convert %s or value is 0", 1701 val); 1702 return ERROR_SEND_STATUS; 1703 } 1704 1705 sigma_dut_print(dut, DUT_MSG_DEBUG, 1706 "Setting BAckRcvBuf to %s", val); 1707 } 1708 1709 val = get_param(cmd, "ExtSchIE"); 1710 if (val && !strcasecmp(val, "Enable")) { 1711 int num_allocs = MAX_ESE_ALLOCS; 1712 1713 if (sta_extract_60g_ese(dut, cmd, dut->ap_ese_allocs, 1714 &num_allocs)) { 1715 send_resp(dut, conn, SIGMA_INVALID, 1716 "errorCode,Invalid ExtSchIE"); 1717 return STATUS_SENT; 1718 } 1719 dut->ap_num_ese_allocs = num_allocs; 1720 } 1721 1722 if (is_60g_sigma_dut(dut)) { 1723 unsigned int abft_len = 1; /* default is one slot */ 1724 1725 val = get_param(cmd, "ABFTLRang"); 1726 if (val) { 1727 sigma_dut_print(dut, DUT_MSG_DEBUG, 1728 "ABFTLRang parameter %s", val); 1729 if (strcasecmp(val, "Gt1") == 0) 1730 abft_len = 2; /* 2 slots in this case */ 1731 } 1732 1733 if (sta_set_60g_abft_len(dut, conn, abft_len)) { 1734 send_resp(dut, conn, SIGMA_ERROR, 1735 "ErrorCode,Can't set ABFT length"); 1736 return STATUS_SENT; 1737 } 1738 } 1739 1740 val = get_param(cmd, "OFDMA"); 1741 if (val) { 1742 if (strcasecmp(val, "UL") == 0) { 1743 dut->ap_he_ulofdma = VALUE_ENABLED; 1744 } else if (strcasecmp(val, "DL") == 0) { 1745 dut->ap_he_dlofdma = VALUE_ENABLED; 1746 } else if (strcasecmp(val, "DL-20and80") == 0) { 1747 dut->ap_he_dlofdma = VALUE_ENABLED; 1748 } else { 1749 send_resp(dut, conn, SIGMA_ERROR, 1750 "errorCode,Unsupported OFDMA value"); 1751 return STATUS_SENT_ERROR; 1752 } 1753 } 1754 1755 val = get_param(cmd, "NumSoundDim"); 1756 if (val) 1757 dut->ap_numsounddim = atoi(val); 1758 1759 val = get_param(cmd, "BCC"); 1760 if (val) { 1761 if (strcasecmp(val, "enable") == 0) { 1762 dut->ap_bcc = VALUE_ENABLED; 1763 dut->ap_ldpc = VALUE_DISABLED; 1764 } else if (strcasecmp(val, "disable") == 0) { 1765 dut->ap_ldpc = VALUE_ENABLED; 1766 dut->ap_bcc = VALUE_DISABLED; 1767 } else { 1768 send_resp(dut, conn, SIGMA_ERROR, 1769 "errorCode,Unsupported BCC value"); 1770 return STATUS_SENT_ERROR; 1771 } 1772 switch (get_driver_type(dut)) { 1773 case DRIVER_WCN: 1774 case DRIVER_LINUX_WCN: 1775 wcn_config_ap_ldpc(dut, ifname); 1776 break; 1777 default: 1778 break; 1779 } 1780 } 1781 1782 val = get_param(cmd, "FrgmntSupport"); 1783 if (val) { 1784 if (strcasecmp(val, "enable") == 0) { 1785 dut->ap_he_frag = VALUE_ENABLED; 1786 } else if (strcasecmp(val, "disable") == 0) { 1787 dut->ap_he_frag = VALUE_DISABLED; 1788 } else { 1789 send_resp(dut, conn, SIGMA_ERROR, 1790 "errorCode,Unsupported FrgmntSupport value"); 1791 return STATUS_SENT_ERROR; 1792 } 1793 } 1794 1795 val = get_param(cmd, "ADDBAReq_BufSize"); 1796 if (val) { 1797 if (strcasecmp(val, "le64") == 0) { 1798 dut->ap_ba_bufsize = BA_BUFSIZE_64; 1799 } else if (strcasecmp(val, "gt64") == 0) { 1800 dut->ap_ba_bufsize = BA_BUFSIZE_256; 1801 } else { 1802 send_resp(dut, conn, SIGMA_ERROR, 1803 "errorCode,Unsupported ADDBAReq Buffer Size"); 1804 return STATUS_SENT_ERROR; 1805 } 1806 } 1807 1808 val = get_param(cmd, "ADDBAResp_BufSize"); 1809 if (val) { 1810 if (strcasecmp(val, "gt64") == 0) { 1811 dut->ap_ba_bufsize = BA_BUFSIZE_256; 1812 } else { 1813 send_resp(dut, conn, SIGMA_ERROR, 1814 "errorCode,Unsupported ADDBAResp Buffer Size"); 1815 return STATUS_SENT_ERROR; 1816 } 1817 } 1818 1819 val = get_param(cmd, "MU_EDCA"); 1820 if (val) { 1821 if (strcasecmp(val, "override") == 0) { 1822 dut->ap_mu_edca = VALUE_ENABLED; 1823 } else if (strcasecmp(val, "disable") == 0) { 1824 dut->ap_mu_edca = VALUE_DISABLED; 1825 } else { 1826 send_resp(dut, conn, SIGMA_ERROR, 1827 "errorCode,Unsupported mu_edca param value"); 1828 return STATUS_SENT_ERROR; 1829 } 1830 } 1831 1832 val = get_param(cmd, "MIMO"); 1833 if (val) { 1834 if (strcasecmp(val, "DL") == 0) { 1835 dut->ap_he_mimo = MIMO_DL; 1836 dut->he_sounding = VALUE_DISABLED; 1837 } else if (strcasecmp(val, "UL") == 0) { 1838 dut->ap_he_mimo = MIMO_UL; 1839 } else { 1840 send_resp(dut, conn, SIGMA_ERROR, 1841 "errorCode,Unsupported mimo param value"); 1842 return STATUS_SENT_ERROR; 1843 } 1844 } 1845 1846 val = get_param(cmd, "HE_TXOPDurRTSThr"); 1847 if (val) { 1848 if (strcasecmp(val, "enable") == 0) { 1849 dut->ap_he_rtsthrshld = VALUE_ENABLED; 1850 } else if (strcasecmp(val, "disable") == 0) { 1851 dut->ap_he_rtsthrshld = VALUE_DISABLED; 1852 } else { 1853 send_resp(dut, conn, SIGMA_ERROR, 1854 "errorCode,Unsupported HE_TXOPDurRTSThr value"); 1855 return STATUS_SENT_ERROR; 1856 } 1857 } 1858 1859 val = get_param(cmd, "MBSSID"); 1860 if (val) { 1861 if (strcasecmp(val, "enable") == 0) { 1862 dut->ap_mbssid = VALUE_ENABLED; 1863 } else if (strcasecmp(val, "disable") == 0) { 1864 dut->ap_mbssid = VALUE_DISABLED; 1865 } else { 1866 send_resp(dut, conn, SIGMA_ERROR, 1867 "errorCode,Unsupported MBSSID Value"); 1868 return STATUS_SENT_ERROR; 1869 } 1870 } 1871 1872 val = get_param(cmd, "TWT_RespSupport"); 1873 if (val) { 1874 if (strcasecmp(val, "enable") == 0) { 1875 dut->ap_twtresp = VALUE_ENABLED; 1876 } else if (strcasecmp(val, "disable") == 0) { 1877 dut->ap_twtresp = VALUE_DISABLED; 1878 } else { 1879 send_resp(dut, conn, SIGMA_ERROR, 1880 "errorCode,Unsupported TWT_RespSupport value"); 1881 return STATUS_SENT_ERROR; 1882 } 1883 } 1884 1885 val = get_param(cmd, "MinMPDUStartSpacing"); 1886 if (val) 1887 dut->he_mmss = atoi(val); 1888 1889 val = get_param(cmd, "SRCtrl_SRValue15Allowed"); 1890 if (val) 1891 dut->he_srctrl_allow = atoi(val); 1892 1893 return SUCCESS_SEND_STATUS; 1894 } 1895 1896 1897 static void ath_inject_frame(struct sigma_dut *dut, const char *ifname, int tid) 1898 { 1899 char buf[256]; 1900 int tid_to_dscp[] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 }; 1901 1902 if (tid < 0 || 1903 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) { 1904 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid); 1905 return; 1906 } 1907 1908 snprintf(buf, sizeof(buf), 1909 "wlanconfig %s list sta | grep : | cut -b 1-17 > %s", 1910 ifname, VI_QOS_TMP_FILE); 1911 if (system(buf) != 0) 1912 return; 1913 1914 snprintf(buf, sizeof(buf), 1915 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s", 1916 ifname, VI_QOS_TMP_FILE); 1917 if (system(buf) != 0) 1918 sigma_dut_print(dut, DUT_MSG_ERROR, "Retrieve HWaddr failed"); 1919 1920 snprintf(buf, sizeof(buf), "sed -n '3,$p' %s >> %s", 1921 VI_QOS_REFFILE, VI_QOS_TMP_FILE); 1922 if (system(buf) != 0) { 1923 sigma_dut_print(dut, DUT_MSG_ERROR, 1924 "Output redirection to VI_QOS_TMP_FILE failed"); 1925 } 1926 1927 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s", 1928 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE); 1929 if (system(buf) != 0) { 1930 sigma_dut_print(dut, DUT_MSG_ERROR, 1931 "Append TID to VI_QOS_FILE failed "); 1932 } 1933 1934 snprintf(buf, sizeof(buf), "ethinject %s %s", ifname, VI_QOS_FILE); 1935 if (system(buf) != 0) 1936 sigma_dut_print(dut, DUT_MSG_ERROR, "Ethinject frame failed"); 1937 } 1938 1939 1940 static int ath_ap_send_addba_req(struct sigma_dut *dut, struct sigma_conn *conn, 1941 struct sigma_cmd *cmd) 1942 { 1943 const char *val; 1944 const char *ifname; 1945 char buf[256]; 1946 int tid = 0; 1947 1948 ifname = get_main_ifname(dut); 1949 val = get_param(cmd, "TID"); 1950 if (val) { 1951 tid = atoi(val); 1952 if (tid) 1953 ath_inject_frame(dut, ifname, tid); 1954 } 1955 1956 /* NOTE: This is the command sequence on Peregrine for ADDBA */ 1957 run_iwpriv(dut, ifname, "setaddbaoper 1"); 1958 1959 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", 1960 ifname, tid); 1961 if (system(buf) != 0) { 1962 sigma_dut_print(dut, DUT_MSG_ERROR, 1963 "wifitool senddelba failed"); 1964 } 1965 1966 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", 1967 ifname, tid); 1968 if (system(buf) != 0) { 1969 sigma_dut_print(dut, DUT_MSG_ERROR, 1970 "wifitool sendaddba failed"); 1971 } 1972 1973 return 1; 1974 } 1975 1976 1977 static int ath10k_debug_enable_addba_req(struct sigma_dut *dut, int tid, 1978 const char *sta_mac, 1979 const char *dir_path) 1980 { 1981 DIR *dir; 1982 struct dirent *entry; 1983 char buf[128], path[128]; 1984 int ret = 0, res; 1985 1986 dir = opendir(dir_path); 1987 if (!dir) 1988 return 0; 1989 1990 while ((entry = readdir(dir))) { 1991 ret = 1; 1992 1993 if (strcmp(entry->d_name, ".") == 0 || 1994 strcmp(entry->d_name, "..") == 0) 1995 continue; 1996 1997 res = snprintf(path, sizeof(path) - 1, "%s/%s", 1998 dir_path, entry->d_name); 1999 if (res < 0 || res >= sizeof(path)) 2000 continue; 2001 2002 if (strcmp(entry->d_name, sta_mac) == 0) { 2003 res = snprintf(buf, sizeof(buf), 2004 "echo 1 > %s/aggr_mode", path); 2005 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) { 2006 sigma_dut_print(dut, DUT_MSG_ERROR, 2007 "Failed to set aggr mode for ath10k"); 2008 } 2009 2010 res = snprintf(buf, sizeof(buf), 2011 "echo %d 32 > %s/addba", tid, path); 2012 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) { 2013 sigma_dut_print(dut, DUT_MSG_ERROR, 2014 "Failed to set addbareq for ath10k"); 2015 } 2016 2017 break; 2018 } 2019 2020 /* Recursively search subdirectories */ 2021 ath10k_debug_enable_addba_req(dut, tid, sta_mac, path); 2022 } 2023 2024 closedir(dir); 2025 2026 return ret; 2027 } 2028 2029 2030 static int ath10k_ap_send_addba_req(struct sigma_dut *dut, 2031 struct sigma_cmd *cmd) 2032 { 2033 const char *val; 2034 int tid = 0; 2035 2036 val = get_param(cmd, "TID"); 2037 if (val) 2038 tid = atoi(val); 2039 2040 val = get_param(cmd, "sta_mac_address"); 2041 if (!val) { 2042 sigma_dut_print(dut, DUT_MSG_ERROR, 2043 "Failed to parse station MAC address"); 2044 return 0; 2045 } 2046 2047 return ath10k_debug_enable_addba_req(dut, tid, val, 2048 "/sys/kernel/debug/ieee80211"); 2049 } 2050 2051 2052 static enum sigma_cmd_result cmd_ap_send_addba_req(struct sigma_dut *dut, 2053 struct sigma_conn *conn, 2054 struct sigma_cmd *cmd) 2055 { 2056 /* const char *name = get_param(cmd, "NAME"); */ 2057 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 2058 struct stat s; 2059 2060 switch (get_driver_type(dut)) { 2061 case DRIVER_ATHEROS: 2062 return ath_ap_send_addba_req(dut, conn, cmd); 2063 #ifdef __linux__ 2064 case DRIVER_WIL6210: 2065 return send_addba_60g(dut, conn, cmd, "sta_mac_address"); 2066 #endif /* __linux__ */ 2067 case DRIVER_OPENWRT: 2068 switch (get_openwrt_driver_type()) { 2069 case OPENWRT_DRIVER_ATHEROS: 2070 return ath_ap_send_addba_req(dut, conn, cmd); 2071 default: 2072 send_resp(dut, conn, SIGMA_ERROR, 2073 "errorCode,ap_send_addba_req not supported with this driver"); 2074 return 0; 2075 } 2076 case DRIVER_WCN: 2077 case DRIVER_LINUX_WCN: 2078 /* AP automatically sends ADDBA request after association. */ 2079 sigma_dut_print(dut, DUT_MSG_INFO, 2080 "ap_send_addba_req command ignored"); 2081 return 1; 2082 case DRIVER_MAC80211: 2083 if (stat("/sys/module/ath10k_core", &s) == 0) 2084 return ath10k_ap_send_addba_req(dut, cmd); 2085 /* fall through */ 2086 default: 2087 send_resp(dut, conn, SIGMA_ERROR, 2088 "errorCode,ap_send_addba_req not supported with this driver"); 2089 return 0; 2090 } 2091 } 2092 2093 2094 static enum sigma_cmd_result cmd_ap_set_security(struct sigma_dut *dut, 2095 struct sigma_conn *conn, 2096 struct sigma_cmd *cmd) 2097 { 2098 /* const char *name = get_param(cmd, "NAME"); */ 2099 const char *val; 2100 unsigned int wlan_tag = 1; 2101 const char *security; 2102 2103 val = get_param(cmd, "WLAN_TAG"); 2104 if (val) 2105 wlan_tag = atoi(val); 2106 2107 security = get_param(cmd, "Security"); 2108 2109 if (wlan_tag > 1) { 2110 val = get_param(cmd, "KEYMGNT"); 2111 if (!val) 2112 val = get_param(cmd, "KeyMgmtType"); 2113 if (val) { 2114 if (strcasecmp(val, "NONE") == 0) { 2115 dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OPEN; 2116 } else if (strcasecmp(val, "OSEN") == 0 && 2117 wlan_tag == 2) { 2118 /* 2119 * OSEN only supported on WLAN_TAG = 2 for now 2120 */ 2121 dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OSEN; 2122 } else if (strcasecmp(val, "WPA2-PSK") == 0 || 2123 (security && 2124 strcasecmp(security, "PSK") == 0 && 2125 strcasecmp(val, "WPA2") == 0)) { 2126 dut->ap_tag_key_mgmt[wlan_tag - 2] = 2127 AP2_WPA2_PSK; 2128 } else if (strcasecmp(val, "OWE") == 0 && 2129 wlan_tag == 2) { 2130 dut->ap_tag_key_mgmt[wlan_tag - 2] = 2131 AP2_WPA2_OWE; 2132 } else { 2133 send_resp(dut, conn, SIGMA_INVALID, 2134 "errorCode,Unsupported KEYMGNT"); 2135 return 0; 2136 } 2137 return 1; 2138 } 2139 } 2140 2141 val = get_param(cmd, "KEYMGNT"); 2142 if (!val) 2143 val = get_param(cmd,"KeyMgmtType"); 2144 if (val) { 2145 if (strcasecmp(val, "WPA2-PSK") == 0 || 2146 (security && strcasecmp(security, "PSK") == 0 && 2147 strcasecmp(val, "WPA2") == 0)) { 2148 dut->ap_key_mgmt = AP_WPA2_PSK; 2149 dut->ap_cipher = AP_CCMP; 2150 } else if (strcasecmp(val, "WPA2-EAP") == 0 || 2151 strcasecmp(val, "WPA2-Ent") == 0) { 2152 dut->ap_key_mgmt = AP_WPA2_EAP; 2153 dut->ap_cipher = AP_CCMP; 2154 } else if (strcasecmp(val, "SuiteB") == 0) { 2155 dut->ap_key_mgmt = AP_SUITEB; 2156 dut->ap_cipher = AP_GCMP_256; 2157 dut->ap_pmf = AP_PMF_REQUIRED; 2158 } else if (strcasecmp(val, "WPA-PSK") == 0) { 2159 dut->ap_key_mgmt = AP_WPA_PSK; 2160 dut->ap_cipher = AP_TKIP; 2161 } else if (strcasecmp(val, "WPA-EAP") == 0 || 2162 strcasecmp(val, "WPA-Ent") == 0) { 2163 dut->ap_key_mgmt = AP_WPA_EAP; 2164 dut->ap_cipher = AP_TKIP; 2165 } else if (strcasecmp(val, "WPA2-Mixed") == 0) { 2166 dut->ap_key_mgmt = AP_WPA2_EAP_MIXED; 2167 dut->ap_cipher = AP_CCMP_TKIP; 2168 } else if (strcasecmp(val, "WPA2-PSK-Mixed") == 0) { 2169 dut->ap_key_mgmt = AP_WPA2_PSK_MIXED; 2170 dut->ap_cipher = AP_CCMP_TKIP; 2171 } else if (strcasecmp(val, "WPA2-SAE") == 0 || 2172 strcasecmp(val, "SAE") == 0) { 2173 dut->ap_key_mgmt = AP_WPA2_SAE; 2174 dut->ap_cipher = AP_CCMP; 2175 dut->ap_pmf = AP_PMF_REQUIRED; 2176 } else if (strcasecmp(val, "WPA2-PSK-SAE") == 0) { 2177 dut->ap_key_mgmt = AP_WPA2_PSK_SAE; 2178 dut->ap_cipher = AP_CCMP; 2179 dut->ap_pmf = AP_PMF_OPTIONAL; 2180 } else if (strcasecmp(val, "OWE") == 0) { 2181 dut->ap_key_mgmt = AP_WPA2_OWE; 2182 dut->ap_cipher = AP_CCMP; 2183 dut->ap_pmf = AP_PMF_REQUIRED; 2184 } else if (strcasecmp(val, "WPA2-ENT-OSEN") == 0) { 2185 dut->ap_key_mgmt = AP_WPA2_EAP_OSEN; 2186 dut->ap_cipher = AP_CCMP; 2187 dut->ap_pmf = AP_PMF_OPTIONAL; 2188 } else if (strcasecmp(val, "OSEN") == 0) { 2189 dut->ap_key_mgmt = AP_OSEN; 2190 dut->ap_cipher = AP_CCMP; 2191 } else if (strcasecmp(val, "FT-EAP") == 0) { 2192 dut->ap_key_mgmt = AP_WPA2_FT_EAP; 2193 dut->ap_cipher = AP_CCMP; 2194 dut->ap_pmf = AP_PMF_OPTIONAL; 2195 } else if (strcasecmp(val, "FT-PSK") == 0) { 2196 dut->ap_key_mgmt = AP_WPA2_FT_PSK; 2197 dut->ap_cipher = AP_CCMP; 2198 dut->ap_pmf = AP_PMF_OPTIONAL; 2199 } else if (strcasecmp(val, "WPA2-ENT-256") == 0) { 2200 dut->ap_key_mgmt = AP_WPA2_EAP_SHA256; 2201 dut->ap_cipher = AP_CCMP; 2202 dut->ap_pmf = AP_PMF_OPTIONAL; 2203 } else if (strcasecmp(val, "WPA2-PSK-256") == 0) { 2204 dut->ap_key_mgmt = AP_WPA2_PSK_SHA256; 2205 dut->ap_cipher = AP_CCMP; 2206 dut->ap_pmf = AP_PMF_OPTIONAL; 2207 } else if (strcasecmp(val, "WPA2-ENT-FT-EAP") == 0) { 2208 dut->ap_key_mgmt = AP_WPA2_ENT_FT_EAP; 2209 dut->ap_cipher = AP_CCMP; 2210 dut->ap_pmf = AP_PMF_OPTIONAL; 2211 } else if (strcasecmp(val, "NONE") == 0) { 2212 dut->ap_key_mgmt = AP_OPEN; 2213 dut->ap_cipher = AP_PLAIN; 2214 } else { 2215 send_resp(dut, conn, SIGMA_INVALID, 2216 "errorCode,Unsupported KEYMGNT"); 2217 return 0; 2218 } 2219 } 2220 2221 val = get_param(cmd, "ECGroupID"); 2222 if (val) { 2223 free(dut->ap_sae_groups); 2224 dut->ap_sae_groups = strdup(val); 2225 } 2226 2227 val = get_param(cmd, "AntiCloggingThreshold"); 2228 if (val) 2229 dut->sae_anti_clogging_threshold = atoi(val); 2230 2231 val = get_param(cmd, "Reflection"); 2232 if (val) 2233 dut->sae_reflection = strcasecmp(val, "SAE") == 0; 2234 2235 val = get_param(cmd, "InvalidSAEElement"); 2236 if (val) { 2237 free(dut->sae_commit_override); 2238 dut->sae_commit_override = strdup(val); 2239 } 2240 2241 val = get_param(cmd, "SAEPasswords"); 2242 if (val) { 2243 free(dut->ap_sae_passwords); 2244 dut->ap_sae_passwords = strdup(val); 2245 } 2246 2247 val = get_param(cmd, "SAE_Confirm_Immediate"); 2248 if (val) 2249 dut->sae_confirm_immediate = get_enable_disable(val); 2250 2251 val = get_param(cmd, "sae_pwe"); 2252 if (val) { 2253 if (strcasecmp(val, "h2e") == 0) { 2254 dut->sae_pwe = SAE_PWE_H2E; 2255 } else if (strcasecmp(val, "loop") == 0 || 2256 strcasecmp(val, "looping") == 0) { 2257 dut->sae_pwe = SAE_PWE_LOOP; 2258 } else { 2259 send_resp(dut, conn, SIGMA_ERROR, 2260 "errorCode,Unsupported sae_pwe value"); 2261 return STATUS_SENT_ERROR; 2262 } 2263 } 2264 2265 val = get_param(cmd, "RSNXE_Content"); 2266 if (val) { 2267 if (strncasecmp(val, "EapolM3:", 8) != 0) { 2268 send_resp(dut, conn, SIGMA_ERROR, 2269 "errorCode,Unsupported RSNXE_Content value"); 2270 return STATUS_SENT_ERROR; 2271 } 2272 val += 8; 2273 free(dut->rsnxe_override_eapol); 2274 dut->rsnxe_override_eapol = strdup(val); 2275 } 2276 2277 val = get_param(cmd, "ENCRYPT"); 2278 if (!val) 2279 val = get_param(cmd, "EncpType"); 2280 if (val) { 2281 if (strcasecmp(val, "WEP") == 0) { 2282 dut->ap_cipher = AP_WEP; 2283 } else if (strcasecmp(val, "TKIP") == 0) { 2284 dut->ap_cipher = AP_TKIP; 2285 } else if (strcasecmp(val, "AES") == 0 || 2286 strcasecmp(val, "AES-CCMP") == 0) { 2287 dut->ap_cipher = AP_CCMP; 2288 } else if (strcasecmp(val, "AES-GCMP") == 0) { 2289 dut->ap_cipher = AP_GCMP_128; 2290 } else { 2291 send_resp(dut, conn, SIGMA_INVALID, 2292 "errorCode,Unsupported ENCRYPT"); 2293 return 0; 2294 } 2295 } 2296 2297 val = get_param(cmd, "PairwiseCipher"); 2298 if (val) { 2299 if (strcasecmp(val, "AES-GCMP-256") == 0) { 2300 dut->ap_cipher = AP_GCMP_256; 2301 } else if (strcasecmp(val, "AES-CCMP-256") == 0) { 2302 dut->ap_cipher = AP_CCMP_256; 2303 } else if (strcasecmp(val, "AES-GCMP-128") == 0) { 2304 dut->ap_cipher = AP_GCMP_128; 2305 } else if (strcasecmp(val, "AES-CCMP-128") == 0) { 2306 dut->ap_cipher = AP_CCMP; 2307 } else if (strcasecmp(val, "AES-CCMP-128 AES-GCMP-256") == 0 || 2308 strcasecmp(val, "AES-GCMP-256 AES-CCMP-128") == 0) { 2309 dut->ap_cipher = AP_CCMP_128_GCMP_256; 2310 } else { 2311 send_resp(dut, conn, SIGMA_INVALID, 2312 "errorCode,Unsupported PairwiseCipher"); 2313 return 0; 2314 } 2315 } 2316 2317 val = get_param(cmd, "GroupCipher"); 2318 if (val) { 2319 if (strcasecmp(val, "AES-GCMP-256") == 0) { 2320 dut->ap_group_cipher = AP_GCMP_256; 2321 } else if (strcasecmp(val, "AES-CCMP-256") == 0) { 2322 dut->ap_group_cipher = AP_CCMP_256; 2323 } else if (strcasecmp(val, "AES-GCMP-128") == 0) { 2324 dut->ap_group_cipher = AP_GCMP_128; 2325 } else if (strcasecmp(val, "AES-CCMP-128") == 0) { 2326 dut->ap_group_cipher = AP_CCMP; 2327 } else { 2328 send_resp(dut, conn, SIGMA_INVALID, 2329 "errorCode,Unsupported GroupCipher"); 2330 return 0; 2331 } 2332 } 2333 2334 val = get_param(cmd, "GroupMgntCipher"); 2335 if (val) { 2336 if (strcasecmp(val, "BIP-GMAC-256") == 0) { 2337 dut->ap_group_mgmt_cipher = AP_BIP_GMAC_256; 2338 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) { 2339 dut->ap_group_mgmt_cipher = AP_BIP_CMAC_256; 2340 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) { 2341 dut->ap_group_mgmt_cipher = AP_BIP_GMAC_128; 2342 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) { 2343 dut->ap_group_mgmt_cipher = AP_BIP_CMAC_128; 2344 } else { 2345 send_resp(dut, conn, SIGMA_INVALID, 2346 "errorCode,Unsupported GroupMgntCipher"); 2347 return 0; 2348 } 2349 } 2350 2351 val = get_param(cmd, "WEPKEY"); 2352 if (val) { 2353 size_t len; 2354 if (dut->ap_cipher != AP_WEP) { 2355 send_resp(dut, conn, SIGMA_INVALID, 2356 "errorCode,Unexpected WEPKEY without WEP " 2357 "configuration"); 2358 return 0; 2359 } 2360 len = strlen(val); 2361 if (len != 10 && len != 26) { 2362 send_resp(dut, conn, SIGMA_INVALID, 2363 "errorCode,Unexpected WEPKEY length"); 2364 return 0; 2365 } 2366 snprintf(dut->ap_wepkey, sizeof(dut->ap_wepkey), "%s", val); 2367 } 2368 2369 val = get_param(cmd, "PSK"); 2370 if (!val) 2371 val = get_param(cmd, "passphrase"); 2372 if (val) { 2373 if (dut->ap_key_mgmt != AP_WPA2_SAE && 2374 (dut->ap_akm_values & (AKM_WPA_PSK | AKM_SAE)) != 2375 AKM_SAE && 2376 strlen(val) > 64) { 2377 sigma_dut_print(dut, DUT_MSG_ERROR, 2378 "Too long PSK/passphtase"); 2379 return -1; 2380 } 2381 if (strlen(val) > sizeof(dut->ap_passphrase) - 1) 2382 return -1; 2383 snprintf(dut->ap_passphrase, sizeof(dut->ap_passphrase), 2384 "%s", val); 2385 } 2386 2387 val = get_param(cmd, "PSKHEX"); 2388 if (val) { 2389 if (strlen(val) != 64) 2390 return -1; 2391 strlcpy(dut->ap_psk, val, sizeof(dut->ap_psk)); 2392 } 2393 2394 if (dut->program == PROGRAM_OCE && dut->dev_role == DEVROLE_STA_CFON) 2395 dut->ap_pmf = AP_PMF_OPTIONAL; 2396 2397 val = get_param(cmd, "PMF"); 2398 if (val) { 2399 if (strcasecmp(val, "Disabled") == 0) { 2400 dut->ap_pmf = AP_PMF_DISABLED; 2401 } else if (strcasecmp(val, "Optional") == 0) { 2402 dut->ap_pmf = AP_PMF_OPTIONAL; 2403 } else if (strcasecmp(val, "Required") == 0) { 2404 dut->ap_pmf = AP_PMF_REQUIRED; 2405 } else { 2406 send_resp(dut, conn, SIGMA_INVALID, 2407 "errorCode,Unsupported PMF"); 2408 return 0; 2409 } 2410 } 2411 2412 dut->ap_add_sha256 = 0; 2413 val = get_param(cmd, "SHA256AD"); 2414 if (val == NULL) 2415 val = get_param(cmd, "SHA256"); 2416 if (val) { 2417 if (strcasecmp(val, "Disabled") == 0) { 2418 } else if (strcasecmp(val, "Enabled") == 0) { 2419 dut->ap_add_sha256 = 1; 2420 } else { 2421 send_resp(dut, conn, SIGMA_INVALID, 2422 "errorCode,Unsupported SHA256"); 2423 return 0; 2424 } 2425 } 2426 2427 val = get_param(cmd, "PreAuthentication"); 2428 if (val) { 2429 if (strcasecmp(val, "disabled") == 0) { 2430 dut->ap_rsn_preauth = 0; 2431 } else if (strcasecmp(val, "enabled") == 0) { 2432 dut->ap_rsn_preauth = 1; 2433 } else { 2434 send_resp(dut, conn, SIGMA_INVALID, 2435 "errorCode,Unsupported PreAuthentication value"); 2436 return 0; 2437 } 2438 } 2439 2440 val = get_param(cmd, "AKMSuiteType"); 2441 if (val) { 2442 const char *in_pos = val; 2443 2444 dut->ap_akm_values = 0; 2445 while (*in_pos) { 2446 int akm = atoi(in_pos); 2447 2448 if (akm < 0 || akm >= 32) { 2449 send_resp(dut, conn, SIGMA_ERROR, 2450 "errorCode,Unsupported AKMSuiteType value"); 2451 return STATUS_SENT; 2452 } 2453 2454 dut->ap_akm_values |= 1 << akm; 2455 2456 in_pos = strchr(in_pos, ';'); 2457 if (!in_pos) 2458 break; 2459 while (*in_pos == ';') 2460 in_pos++; 2461 } 2462 dut->ap_akm = 1; 2463 if (dut->ap_akm_values & (1 << 14)) 2464 dut->ap_add_sha384 = 1; 2465 if (dut->ap_akm_values & (1 << 15)) 2466 dut->ap_add_sha384 = 1; 2467 } 2468 2469 if (dut->ap_key_mgmt == AP_OPEN && !dut->ap_akm_values) { 2470 dut->ap_hs2 = 0; 2471 dut->ap_pmf = AP_PMF_DISABLED; 2472 } 2473 2474 val = get_param(cmd, "PMKSACaching"); 2475 if (val) { 2476 dut->ap_pmksa = 1; 2477 if (strcasecmp(val, "disabled") == 0) { 2478 dut->ap_pmksa_caching = 1; 2479 } else if (strcasecmp(val, "enabled") == 0) { 2480 dut->ap_pmksa_caching = 0; 2481 } else { 2482 send_resp(dut, conn, SIGMA_INVALID, 2483 "errorCode,Unsupported PMKSACaching value"); 2484 return 0; 2485 } 2486 } 2487 2488 val = get_param(cmd, "BeaconProtection"); 2489 if (val) 2490 dut->ap_beacon_prot = atoi(val); 2491 2492 val = get_param(cmd, "Transition_Disable"); 2493 if (val) { 2494 if (atoi(val)) { 2495 val = get_param(cmd, "Transition_Disable_Index"); 2496 if (!val) { 2497 send_resp(dut, conn, SIGMA_INVALID, 2498 "errorCode,Transition_Disable without Transition_Disable_Index"); 2499 return STATUS_SENT; 2500 } 2501 dut->ap_transition_disable = 1 << atoi(val); 2502 } else { 2503 dut->ap_transition_disable = 0; 2504 } 2505 } 2506 2507 return 1; 2508 } 2509 2510 2511 int sta_cfon_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn, 2512 struct sigma_cmd *cmd) 2513 { 2514 int status; 2515 2516 status = cmd_ap_set_wireless(dut, conn, cmd); 2517 if (status != 1) 2518 return status; 2519 status = cmd_ap_set_security(dut, conn, cmd); 2520 if (status != 1) 2521 return status; 2522 return cmd_ap_config_commit(dut, conn, cmd); 2523 } 2524 2525 2526 static enum sigma_cmd_result cmd_ap_set_radius(struct sigma_dut *dut, 2527 struct sigma_conn *conn, 2528 struct sigma_cmd *cmd) 2529 { 2530 /* const char *name = get_param(cmd, "NAME"); */ 2531 const char *val; 2532 unsigned int wlan_tag = 1, radius_port = 0; 2533 char *radius_ipaddr = NULL, *radius_password = NULL; 2534 2535 val = get_param(cmd, "WLAN_TAG"); 2536 if (val) { 2537 wlan_tag = atoi(val); 2538 if (wlan_tag != 1 && wlan_tag != 2) { 2539 send_resp(dut, conn, SIGMA_INVALID, 2540 "errorCode,Invalid WLAN_TAG"); 2541 return 0; 2542 } 2543 } 2544 2545 val = get_param(cmd, "PORT"); 2546 if (val) 2547 radius_port = atoi(val); 2548 2549 if (wlan_tag == 1) { 2550 if (radius_port) 2551 dut->ap_radius_port = radius_port; 2552 radius_ipaddr = dut->ap_radius_ipaddr; 2553 radius_password = dut->ap_radius_password; 2554 } else if (wlan_tag == 2) { 2555 if (radius_port) 2556 dut->ap2_radius_port = radius_port; 2557 radius_ipaddr = dut->ap2_radius_ipaddr; 2558 radius_password = dut->ap2_radius_password; 2559 } 2560 2561 val = get_param(cmd, "IPADDR"); 2562 if (val) { 2563 if (strlen(val) > sizeof(dut->ap_radius_ipaddr) - 1) 2564 return -1; 2565 snprintf(radius_ipaddr, sizeof(dut->ap_radius_ipaddr), 2566 "%s", val); 2567 } 2568 2569 val = get_param(cmd, "PASSWORD"); 2570 if (val) { 2571 if (strlen(val) > sizeof(dut->ap_radius_password) - 1) 2572 return -1; 2573 snprintf(radius_password, 2574 sizeof(dut->ap_radius_password), "%s", val); 2575 } 2576 2577 return 1; 2578 } 2579 2580 2581 static void owrt_ap_set_qcawifi(struct sigma_dut *dut, const char *key, 2582 const char *val) 2583 { 2584 if (!val) { 2585 run_system_wrapper(dut, "uci delete wireless.qcawifi.%s", key); 2586 return; 2587 } 2588 2589 run_system(dut, "uci set wireless.qcawifi=qcawifi"); 2590 run_system_wrapper(dut, "uci set wireless.qcawifi.%s=%s", key, val); 2591 } 2592 2593 2594 static void owrt_ap_set_radio(struct sigma_dut *dut, int id, 2595 const char *key, const char *val) 2596 { 2597 char buf[100]; 2598 2599 if (val == NULL) { 2600 snprintf(buf, sizeof(buf), 2601 "uci delete wireless.wifi%d.%s", id, key); 2602 run_system(dut, buf); 2603 return; 2604 } 2605 2606 snprintf(buf, sizeof(buf), "uci set wireless.wifi%d.%s=%s", 2607 id, key, val); 2608 run_system(dut, buf); 2609 } 2610 2611 2612 static void owrt_ap_set_list_radio(struct sigma_dut *dut, int id, 2613 const char *key, const char *val) 2614 { 2615 char buf[256]; 2616 2617 if (val == NULL) { 2618 snprintf(buf, sizeof(buf), 2619 "uci del_list wireless.wifi%d.%s", id, key); 2620 run_system(dut, buf); 2621 return; 2622 } 2623 2624 snprintf(buf, sizeof(buf), "uci add_list wireless.wifi%d.%s=%s", 2625 id, key, val); 2626 run_system(dut, buf); 2627 } 2628 2629 2630 static void owrt_ap_set_vap(struct sigma_dut *dut, int id, const char *key, 2631 const char *val) 2632 { 2633 char buf[256]; 2634 2635 if (val == NULL) { 2636 snprintf(buf, sizeof(buf), 2637 "uci delete wireless.@wifi-iface[%d].%s", id, key); 2638 run_system(dut, buf); 2639 return; 2640 } 2641 2642 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s", 2643 id, key, val); 2644 run_system(dut, buf); 2645 } 2646 2647 2648 static void owrt_ap_set_list_vap(struct sigma_dut *dut, int id, 2649 const char *key, const char *val) 2650 { 2651 char buf[1024]; 2652 2653 if (val == NULL) { 2654 snprintf(buf, sizeof(buf), 2655 "uci del_list wireless.@wifi-iface[%d].%s", id, key); 2656 run_system(dut, buf); 2657 return; 2658 } 2659 2660 snprintf(buf, sizeof(buf), 2661 "uci add_list wireless.@wifi-iface[%d].%s=%s", 2662 id, key, val); 2663 run_system(dut, buf); 2664 } 2665 2666 2667 static void owrt_ap_add_vap(struct sigma_dut *dut, int id, const char *key, 2668 const char *val) 2669 { 2670 char buf[256]; 2671 int res; 2672 2673 if (val == NULL) { 2674 res = snprintf(buf, sizeof(buf), 2675 "uci delete wireless.@wifi-iface[%d].%s", 2676 id, key); 2677 if (res >= 0 && res < sizeof(buf)) 2678 run_system(dut, buf); 2679 return; 2680 } 2681 2682 run_system(dut, "uci add wireless wifi-iface"); 2683 res = snprintf(buf, sizeof(buf), 2684 "uci set wireless.@wifi-iface[%d].%s=%s", 2685 id, key, val); 2686 if (res >= 0 && res < sizeof(buf)) 2687 run_system(dut, buf); 2688 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s", 2689 id, "network", "lan"); 2690 run_system(dut, buf); 2691 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s", 2692 id, "mode", "ap"); 2693 run_system(dut, buf); 2694 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s", 2695 id, "encryption", "none"); 2696 run_system(dut, buf); 2697 } 2698 2699 2700 #define OPENWRT_MAX_NUM_RADIOS (MAX_RADIO + 1) 2701 static int owrt_ap_config_radio(struct sigma_dut *dut) 2702 { 2703 int radio_id[MAX_RADIO] = { 0, 1, 2 }; 2704 int radio_count, radio_no; 2705 char buf[64]; 2706 2707 for (radio_count = 0; radio_count < OPENWRT_MAX_NUM_RADIOS; 2708 radio_count++) { 2709 snprintf(buf, sizeof(buf), "%s%d", "wifi", radio_count); 2710 for (radio_no = 0; radio_no < MAX_RADIO; radio_no++) { 2711 if (!sigma_radio_ifname[radio_no] || 2712 strcmp(sigma_radio_ifname[radio_no], buf) != 0) 2713 continue; 2714 owrt_ap_set_radio(dut, radio_count, "disabled", "0"); 2715 owrt_ap_set_vap(dut, radio_count, "device", buf); 2716 radio_id[radio_no] = radio_count; 2717 } 2718 } 2719 2720 /* Hardware mode (11a/b/g/n/ac) & HT mode selection */ 2721 switch (dut->ap_mode) { 2722 case AP_11g: 2723 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11g"); 2724 break; 2725 case AP_11b: 2726 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11b"); 2727 break; 2728 case AP_11ng: 2729 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng"); 2730 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20"); 2731 break; 2732 case AP_11a: 2733 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11a"); 2734 break; 2735 case AP_11na: 2736 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11na"); 2737 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20"); 2738 break; 2739 case AP_11ac: 2740 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ac"); 2741 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80"); 2742 break; 2743 case AP_11ax: 2744 if (dut->ap_channel >= 36) { 2745 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axa"); 2746 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80"); 2747 } else { 2748 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axg"); 2749 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20"); 2750 } 2751 break; 2752 case AP_inval: 2753 sigma_dut_print(dut, DUT_MSG_ERROR, 2754 "MODE NOT SPECIFIED!"); 2755 return -1; 2756 default: 2757 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng"); 2758 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20"); 2759 break; 2760 } 2761 2762 if (dut->ap_is_dual) { 2763 /* Hardware mode (11a/b/g/n/ac) & HT mode selection */ 2764 switch (dut->ap_mode_1) { 2765 case AP_11g: 2766 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11g"); 2767 break; 2768 case AP_11b: 2769 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11b"); 2770 break; 2771 case AP_11ng: 2772 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng"); 2773 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20"); 2774 break; 2775 case AP_11a: 2776 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11a"); 2777 break; 2778 case AP_11na: 2779 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11na"); 2780 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20"); 2781 break; 2782 case AP_11ac: 2783 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ac"); 2784 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT80"); 2785 break; 2786 case AP_11ax: 2787 if (dut->ap_channel >= 36) { 2788 owrt_ap_set_radio(dut, radio_id[1], 2789 "hwmode", "11axa"); 2790 owrt_ap_set_radio(dut, radio_id[1], 2791 "htmode", "HT80"); 2792 } else { 2793 owrt_ap_set_radio(dut, radio_id[1], 2794 "hwmode", "11axg"); 2795 owrt_ap_set_radio(dut, radio_id[1], 2796 "htmode", "HT20"); 2797 } 2798 break; 2799 case AP_inval: 2800 sigma_dut_print(dut, DUT_MSG_ERROR, 2801 "MODE NOT SPECIFIED!"); 2802 return -1; 2803 default: 2804 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng"); 2805 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20"); 2806 break; 2807 } 2808 2809 } 2810 2811 /* Channel */ 2812 snprintf(buf, sizeof(buf), "%d", dut->ap_channel); 2813 owrt_ap_set_radio(dut, radio_id[0], "channel", buf); 2814 2815 switch (dut->ap_chwidth) { 2816 case AP_20: 2817 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20"); 2818 break; 2819 case AP_40: 2820 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT40"); 2821 break; 2822 case AP_80: 2823 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80"); 2824 break; 2825 case AP_160: 2826 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT160"); 2827 break; 2828 case AP_80_80: 2829 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80_80"); 2830 break; 2831 case AP_AUTO: 2832 default: 2833 break; 2834 } 2835 2836 if (dut->ap_channel == 140 || dut->ap_channel == 144) { 2837 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 2838 owrt_ap_set_radio(dut, radio_id[0], "set_ch_144", "3"); 2839 } 2840 2841 if (dut->ap_is_dual) { 2842 snprintf(buf, sizeof(buf), "%d", dut->ap_channel_1); 2843 owrt_ap_set_radio(dut, radio_id[1], "channel", buf); 2844 } 2845 2846 /* Country Code */ 2847 if (dut->ap_reg_domain == REG_DOMAIN_GLOBAL) { 2848 const char *country; 2849 2850 country = dut->ap_countrycode[0] ? dut->ap_countrycode : "US"; 2851 snprintf(buf, sizeof(buf), "%s4", country); 2852 owrt_ap_set_radio(dut, radio_id[0], "country", buf); 2853 if (dut->ap_is_dual) 2854 owrt_ap_set_radio(dut, radio_id[1], "country", buf); 2855 } else if (dut->ap_countrycode[0]) { 2856 owrt_ap_set_radio(dut, radio_id[0], "country", 2857 dut->ap_countrycode); 2858 } 2859 2860 if (dut->ap_disable_protection == 1) { 2861 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'0 0'"); 2862 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'1 0'"); 2863 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'2 0'"); 2864 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'3 0'"); 2865 } 2866 2867 if (dut->ap_oce == VALUE_ENABLED && 2868 get_driver_type(dut) == DRIVER_OPENWRT) 2869 owrt_ap_set_radio(dut, radio_id[0], "bcnburst", "1"); 2870 2871 if (dut->ap_mbssid == VALUE_ENABLED) 2872 owrt_ap_set_qcawifi(dut, "mbss_ie_enable", "1"); 2873 2874 if (dut->program == PROGRAM_HE) { 2875 owrt_ap_set_radio(dut, radio_id[0], "he_bsscolor", "'1 1'"); 2876 if (dut->ap_is_dual) 2877 owrt_ap_set_radio(dut, radio_id[1], "he_bsscolor", 2878 "'2 1'"); 2879 owrt_ap_set_qcawifi(dut, "ap_bss_color_collision_detection", 2880 "1"); 2881 } 2882 2883 return 1; 2884 } 2885 2886 2887 static int owrt_ap_config_vap_hs2(struct sigma_dut *dut, int vap_id) 2888 { 2889 char buf[256]; 2890 2891 snprintf(buf, sizeof(buf), "%d", dut->ap_hs2); 2892 owrt_ap_set_vap(dut, vap_id, "hs20", buf); 2893 owrt_ap_set_vap(dut, vap_id, "qbssload", "1"); 2894 owrt_ap_set_vap(dut, vap_id, "hs20_deauth_req_timeout","3"); 2895 2896 owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name", 2897 "'eng:Wi-Fi Alliance'"); 2898 2899 owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name", 2900 "'chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f'"); 2901 2902 if (dut->ap_wan_metrics == 1) 2903 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2904 "'01:2500:384:0:0:10'"); 2905 else if (dut->ap_wan_metrics == 1) 2906 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2907 "'01:1500:384:20:20:10'"); 2908 else if (dut->ap_wan_metrics == 2) 2909 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2910 "'01:1500:384:20:20:10'"); 2911 else if (dut->ap_wan_metrics == 3) 2912 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2913 "'01:2000:1000:20:20:10'"); 2914 else if (dut->ap_wan_metrics == 4) 2915 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2916 "'01:8000:1000:20:20:10'"); 2917 else if (dut->ap_wan_metrics == 5) 2918 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2919 "'01:9000:5000:20:20:10'"); 2920 2921 if (dut->ap_conn_capab == 1) { 2922 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", "'1:0:0'"); 2923 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2924 "'6:20:1'"); 2925 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2926 "'6:22:0'"); 2927 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2928 "'6:80:1'"); 2929 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2930 "'6:443:1'"); 2931 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2932 "'6:1723:0'"); 2933 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2934 "'6:5060:0'"); 2935 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2936 "'17:500:1'"); 2937 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2938 "'17:5060:0'"); 2939 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2940 "'17:4500:1'"); 2941 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2942 "'50:0:1'"); 2943 } else if (dut->ap_conn_capab == 2) { 2944 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2945 "'6:80:1'"); 2946 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2947 "'6:443:1'"); 2948 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2949 "'17:5060:1'"); 2950 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2951 "'6:5060:1'"); 2952 } else if (dut->ap_conn_capab == 3) { 2953 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2954 "'6:80:1'"); 2955 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2956 "'6:443:1'"); 2957 } 2958 2959 if (dut->ap_oper_class == 1) 2960 snprintf(buf, sizeof(buf), "%s", "51"); 2961 else if (dut->ap_oper_class == 2) 2962 snprintf(buf, sizeof(buf), "%s", "73"); 2963 else if (dut->ap_oper_class == 3) 2964 snprintf(buf, sizeof(buf), "%s", "5173"); 2965 2966 if (dut->ap_oper_class) 2967 owrt_ap_set_vap(dut, vap_id, "hs20_operating_class", buf); 2968 2969 if (dut->ap_osu_provider_list) { 2970 char *osu_friendly_name = NULL; 2971 char *osu_icon = NULL; 2972 char *osu_ssid = NULL; 2973 char *osu_nai = NULL; 2974 char *osu_service_desc = NULL; 2975 char *hs20_icon_filename = NULL; 2976 char hs20_icon[150]; 2977 int osu_method; 2978 2979 hs20_icon_filename = "icon_red_zxx.png"; 2980 if (dut->ap_osu_icon_tag == 2) 2981 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 2982 snprintf(hs20_icon, sizeof(hs20_icon), 2983 "'128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s'", 2984 hs20_icon_filename); 2985 osu_icon = "icon_red_zxx.png"; 2986 osu_ssid = "OSU"; 2987 osu_friendly_name = "'kor:SP 빨강 테스트 전용'"; 2988 osu_service_desc = "'kor:테스트 목적으로 무료 서비스'"; 2989 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : 2990 dut->ap_osu_method[0]; 2991 2992 if (strlen(dut->ap_osu_server_uri[0])) 2993 owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri", 2994 dut->ap_osu_server_uri[0]); 2995 else 2996 owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri", 2997 "'https://osu-server.r2-testbed.wi-fi.org/'"); 2998 switch (dut->ap_osu_provider_list) { 2999 case 1: 3000 case 101: 3001 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3002 "'eng:SP Red Test Only'"); 3003 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3004 "'eng:Free service for test purpose'"); 3005 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", 3006 hs20_icon); 3007 3008 hs20_icon_filename = "icon_red_eng.png"; 3009 if (dut->ap_osu_icon_tag == 2) 3010 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3011 3012 snprintf(hs20_icon, sizeof(hs20_icon), 3013 "'160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s'", 3014 hs20_icon_filename); 3015 owrt_ap_set_list_vap(dut, vap_id, "osu_icon", 3016 "icon_red_eng.png"); 3017 break; 3018 case 2: 3019 case 102: 3020 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3021 "'eng:Wireless Broadband Alliance'"); 3022 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3023 "'eng:Free service for test purpose'"); 3024 hs20_icon_filename = "icon_orange_zxx.png"; 3025 if (dut->ap_osu_icon_tag == 2) 3026 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3027 3028 snprintf(hs20_icon, sizeof(hs20_icon), 3029 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'", 3030 hs20_icon_filename); 3031 osu_icon = "icon_orange_zxx.png"; 3032 osu_friendly_name = "'kor:와이어리스 브로드밴드 얼라이언스'"; 3033 break; 3034 case 3: 3035 case 103: 3036 osu_friendly_name = "'spa:SP Red Test Only'"; 3037 osu_service_desc = "'spa:Free service for test purpose'"; 3038 break; 3039 case 4: 3040 case 104: 3041 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3042 "'eng:SP Orange Test Only'"); 3043 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3044 "'eng:Free service for test purpose'"); 3045 hs20_icon_filename = "icon_orange_eng.png"; 3046 if (dut->ap_osu_icon_tag == 2) 3047 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3048 3049 snprintf(hs20_icon, sizeof(hs20_icon), 3050 "'160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s'", 3051 hs20_icon_filename); 3052 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", 3053 hs20_icon); 3054 osu_friendly_name = "'kor:SP 오렌지 테스트 전용'"; 3055 3056 hs20_icon_filename = "icon_orange_zxx.png"; 3057 if (dut->ap_osu_icon_tag == 2) 3058 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3059 3060 snprintf(hs20_icon, sizeof(hs20_icon), 3061 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'", 3062 hs20_icon_filename); 3063 osu_icon = "icon_orange_zxx.png"; 3064 break; 3065 case 5: 3066 case 105: 3067 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3068 "'eng:SP Orange Test Only'"); 3069 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3070 "'eng:Free service for test purpose'"); 3071 osu_friendly_name = "'kor:SP 오렌지 테스트 전용'"; 3072 3073 hs20_icon_filename = "icon_orange_zxx.png"; 3074 if (dut->ap_osu_icon_tag == 2) 3075 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3076 3077 snprintf(hs20_icon, sizeof(hs20_icon), 3078 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'", 3079 hs20_icon_filename); 3080 osu_icon = "icon_orange_zxx.png"; 3081 break; 3082 case 6: 3083 case 106: 3084 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3085 "'eng:SP Green Test Only'"); 3086 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3087 "'kor:SP 초록 테스트 전용'"); 3088 3089 hs20_icon_filename = "icon_green_zxx.png"; 3090 if (dut->ap_osu_icon_tag == 2) 3091 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3092 3093 snprintf(hs20_icon, sizeof(hs20_icon), 3094 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'", 3095 hs20_icon_filename); 3096 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", 3097 hs20_icon); 3098 3099 owrt_ap_set_list_vap(dut, vap_id, "osu_icon", 3100 "'icon_green_zxx.png'"); 3101 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 : 3102 dut->ap_osu_method[0]; 3103 3104 snprintf(buf, sizeof(buf), "%d", osu_method); 3105 owrt_ap_set_vap(dut, vap_id, "osu_method_list", buf); 3106 3107 if (strlen(dut->ap_osu_server_uri[1])) 3108 owrt_ap_set_list_vap(dut, vap_id, 3109 "osu_server_uri", 3110 dut->ap_osu_server_uri[1]); 3111 else 3112 owrt_ap_set_list_vap(dut, vap_id, 3113 "osu_server_uri", 3114 "'https://osu-server.r2-testbed.wi-fi.org/'"); 3115 3116 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3117 "'eng:SP Orange Test Only'"); 3118 3119 hs20_icon_filename = "icon_orange_zxx.png"; 3120 if (dut->ap_osu_icon_tag == 2) 3121 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3122 3123 snprintf(hs20_icon, sizeof(hs20_icon), 3124 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'", 3125 hs20_icon_filename); 3126 3127 osu_icon = "icon_orange_zxx.png"; 3128 osu_friendly_name = "'kor:SP 오렌지 테스트 전용'"; 3129 osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 : 3130 dut->ap_osu_method[1]; 3131 osu_service_desc = NULL; 3132 break; 3133 case 7: 3134 case 107: 3135 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3136 "'eng:SP Green Test Only'"); 3137 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3138 "'eng:Free service for test purpose'"); 3139 3140 hs20_icon_filename = "icon_green_eng.png"; 3141 if (dut->ap_osu_icon_tag == 2) 3142 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3143 3144 snprintf(hs20_icon, sizeof(hs20_icon), 3145 "'160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s'", 3146 hs20_icon_filename); 3147 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", 3148 hs20_icon); 3149 3150 owrt_ap_set_list_vap(dut, vap_id, "osu_icon", 3151 "'icon_green_eng.png'"); 3152 osu_friendly_name = "'kor:SP 초록 테스트 전용'"; 3153 3154 hs20_icon_filename = "icon_green_zxx.png"; 3155 if (dut->ap_osu_icon_tag == 2) 3156 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3157 3158 snprintf(hs20_icon, sizeof(hs20_icon), 3159 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'", 3160 hs20_icon_filename); 3161 osu_icon = "icon_green_zxx.png"; 3162 break; 3163 case 8: 3164 case 108: 3165 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3166 "'eng:SP Red Test Only'"); 3167 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3168 "'eng:Free service for test purpose'"); 3169 osu_ssid = "OSU-Encrypted"; 3170 osu_nai = "'anonymous@hotspot.net'"; 3171 break; 3172 case 9: 3173 case 109: 3174 osu_ssid = "OSU-OSEN"; 3175 osu_nai = "'test-anonymous@wi-fi.org'"; 3176 osu_friendly_name = "'eng:SP Orange Test Only'"; 3177 hs20_icon_filename = "icon_orange_zxx.png"; 3178 if (dut->ap_osu_icon_tag == 2) 3179 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3180 3181 snprintf(hs20_icon, sizeof(hs20_icon), 3182 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'", 3183 hs20_icon_filename); 3184 osu_icon = "icon_orange_zxx.png"; 3185 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : 3186 dut->ap_osu_method[0]; 3187 osu_service_desc = NULL; 3188 break; 3189 default: 3190 break; 3191 } 3192 3193 if (strlen(dut->ap_osu_ssid)) { 3194 if (dut->ap_tag_ssid[0][0] && 3195 strcmp(dut->ap_tag_ssid[0], 3196 dut->ap_osu_ssid) != 0 && 3197 strcmp(dut->ap_tag_ssid[0], osu_ssid) != 0) { 3198 sigma_dut_print(dut, DUT_MSG_ERROR, 3199 "OSU_SSID and WLAN_TAG2 SSID differ"); 3200 return -2; 3201 } 3202 3203 snprintf(buf, sizeof(buf), "'\"%s\"'", 3204 dut->ap_osu_ssid); 3205 } else { 3206 snprintf(buf, sizeof(buf), "'\"%s\"'", osu_ssid); 3207 } 3208 3209 owrt_ap_set_vap(dut, vap_id, "osu_ssid", buf); 3210 3211 3212 if (osu_friendly_name) 3213 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3214 osu_friendly_name); 3215 if (osu_service_desc) 3216 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3217 osu_service_desc); 3218 if (osu_nai) 3219 owrt_ap_set_vap(dut, vap_id, "osu_nai", osu_nai); 3220 3221 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", hs20_icon); 3222 3223 if (osu_icon) 3224 owrt_ap_set_list_vap(dut, vap_id, "osu_icon", 3225 osu_icon); 3226 3227 if (dut->ap_osu_provider_list > 100) { 3228 owrt_ap_set_list_vap(dut, vap_id, "osu_method_list", 3229 "0"); 3230 } else { 3231 snprintf(buf, sizeof(buf), "%d", osu_method); 3232 owrt_ap_set_list_vap(dut, vap_id, "osu_method_list", 3233 buf); 3234 } 3235 } 3236 3237 return 0; 3238 } 3239 3240 3241 static int set_anqp_elem_value(struct sigma_dut *dut, const char *ifname, 3242 char *anqp_string, size_t str_size) 3243 { 3244 unsigned char bssid[ETH_ALEN]; 3245 unsigned char dummy_mac[] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50 }; 3246 int preference = 0xff; 3247 3248 if (get_hwaddr(ifname, bssid) < 0) 3249 return -1; 3250 snprintf(anqp_string, str_size, 3251 "272:3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x", 3252 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5], 3253 preference, 3254 dummy_mac[0], dummy_mac[1], dummy_mac[2], 3255 dummy_mac[3], dummy_mac[4], dummy_mac[5], 3256 preference - 1); 3257 return 0; 3258 } 3259 3260 3261 static const char * get_hostapd_ifname(struct sigma_dut *dut) 3262 { 3263 enum driver_type drv; 3264 3265 /* Use the configured hostapd ifname */ 3266 if (dut->hostapd_ifname && if_nametoindex(dut->hostapd_ifname) > 0) 3267 return dut->hostapd_ifname; 3268 3269 /* Use configured main ifname */ 3270 if (dut->main_ifname) { 3271 if (dut->use_5g && dut->main_ifname_5g && 3272 if_nametoindex(dut->main_ifname_5g) > 0) 3273 return dut->main_ifname_5g; 3274 if (!dut->use_5g && dut->main_ifname_2g && 3275 if_nametoindex(dut->main_ifname_2g) > 0) 3276 return dut->main_ifname_2g; 3277 if (if_nametoindex(dut->main_ifname) > 0) 3278 return dut->main_ifname; 3279 } 3280 3281 /* Return based on driver type (indirectly started hostapd) */ 3282 drv = get_driver_type(dut); 3283 if (drv == DRIVER_ATHEROS) { 3284 if (dut->use_5g && if_nametoindex("ath1") > 0) 3285 return "ath1"; 3286 return "ath0"; 3287 } 3288 3289 if (drv == DRIVER_OPENWRT) { 3290 if (sigma_radio_ifname[0] && 3291 strcmp(sigma_radio_ifname[0], "wifi2") == 0) 3292 return "ath2"; 3293 if (sigma_radio_ifname[0] && 3294 strcmp(sigma_radio_ifname[0], "wifi1") == 0) 3295 return "ath1"; 3296 return "ath0"; 3297 } 3298 3299 /* wlan1-is-likely-5-GHz design */ 3300 if (dut->use_5g && if_nametoindex("wlan1") > 0) 3301 return "wlan1"; 3302 3303 /* If nothing else matches, hope for the best and guess this is wlan0 */ 3304 return "wlan0"; 3305 } 3306 3307 3308 static void get_if_name(struct sigma_dut *dut, char *ifname_str, 3309 size_t str_size, int wlan_tag) 3310 { 3311 const char *ifname; 3312 enum driver_type drv; 3313 3314 ifname = get_hostapd_ifname(dut); 3315 drv = get_driver_type(dut); 3316 3317 if (drv == DRIVER_OPENWRT && wlan_tag > 1) { 3318 /* Handle tagged-ifname only on OPENWRT for now */ 3319 snprintf(ifname_str, str_size, "%s%d", ifname, wlan_tag - 1); 3320 } else if ((drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN) && 3321 wlan_tag == 2) { 3322 snprintf(ifname_str, str_size, "%s_1", ifname); 3323 } else { 3324 snprintf(ifname_str, str_size, "%s", ifname); 3325 } 3326 } 3327 3328 3329 static int sae_pw_id_used(struct sigma_dut *dut) 3330 { 3331 return dut->ap_sae_passwords && 3332 strchr(dut->ap_sae_passwords, ':'); 3333 } 3334 3335 3336 static int owrt_ap_config_vap(struct sigma_dut *dut) 3337 { 3338 char buf[256], *temp; 3339 int vap_id = 0, vap_count, i, j, res; 3340 const char *ifname; 3341 char ifname2[50]; 3342 3343 if (sigma_radio_ifname[0] && 3344 strcmp(sigma_radio_ifname[0], "wifi2") == 0) 3345 ifname = "ath2"; 3346 else if (sigma_radio_ifname[0] && 3347 strcmp(sigma_radio_ifname[0], "wifi1") == 0) 3348 ifname = "ath1"; 3349 else 3350 ifname = "ath0"; 3351 3352 for (vap_count = 0; vap_count < OPENWRT_MAX_NUM_RADIOS; vap_count++) { 3353 snprintf(buf, sizeof(buf), "wifi%d", vap_count); 3354 3355 for (vap_id = 0; vap_id < MAX_RADIO; vap_id++) { 3356 if (sigma_radio_ifname[vap_id] && 3357 strcmp(sigma_radio_ifname[vap_id], buf) == 0) 3358 break; 3359 } 3360 if (vap_id == MAX_RADIO) 3361 continue; 3362 3363 /* Single VAP configuration */ 3364 if (!dut->ap_is_dual) 3365 vap_id = vap_count; 3366 3367 for (j = 0; j < MAX_WLAN_TAGS - 1; j++) { 3368 /* 3369 * We keep a separate array of ap_tag_ssid and 3370 * ap_tag_key_mgmt for tags starting from WLAN_TAG=2. 3371 * So j=0 => WLAN_TAG = 2 3372 */ 3373 int wlan_tag = j + 2; 3374 3375 if (wlan_tag == 2 && dut->program == PROGRAM_WPA3 && 3376 (dut->ap_interface_5g || dut->ap_interface_2g)) { 3377 res = snprintf( 3378 dut->ap_tag_ssid[wlan_tag - 2], 3379 sizeof(dut->ap_tag_ssid[wlan_tag - 2]), 3380 "%s-owe", dut->ap_ssid); 3381 if (res < 0 || 3382 res >= sizeof(dut->ap_tag_ssid[wlan_tag - 3383 2])) 3384 dut->ap_tag_ssid[wlan_tag - 2][0] = 3385 '\0'; 3386 } 3387 3388 if (dut->ap_tag_ssid[j][0] == '\0') 3389 continue; 3390 3391 snprintf(buf, sizeof(buf), "%s%d", "wifi", vap_count); 3392 owrt_ap_add_vap(dut, vap_count + (wlan_tag - 1), 3393 "device", buf); 3394 /* SSID */ 3395 snprintf(buf, sizeof(buf), "\"%s\"", 3396 dut->ap_tag_ssid[j]); 3397 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3398 "ssid", buf); 3399 3400 if (dut->ap_key_mgmt == AP_WPA2_OWE && 3401 dut->ap_tag_ssid[0][0] && 3402 dut->ap_tag_key_mgmt[0] == AP2_OPEN) { 3403 /* OWE transition mode */ 3404 snprintf(buf, sizeof(buf), "%s", ifname); 3405 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3406 "owe_transition_ifname", buf); 3407 } 3408 3409 if (dut->ap_key_mgmt == AP_OPEN && 3410 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) { 3411 /* OWE transition mode */ 3412 snprintf(buf, sizeof(buf), "%s", ifname); 3413 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3414 "owe_transition_ifname", buf); 3415 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3416 "hidden", "1"); 3417 } 3418 3419 if (ap_ft_enabled(dut)) { 3420 unsigned char self_mac[ETH_ALEN]; 3421 char mac_str[20]; 3422 3423 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3424 "mobility_domain", 3425 dut->ap_mobility_domain); 3426 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3427 "ft_over_ds", 3428 dut->ap_ft_ds == VALUE_ENABLED ? 3429 "1" : "0"); 3430 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3431 "ieee80211r", "1"); 3432 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3433 "nasid", "nas1.example.com"); 3434 if (get_hwaddr(sigma_radio_ifname[0], 3435 self_mac) < 0) 3436 return -1; 3437 snprintf(mac_str, sizeof(mac_str), 3438 "%02x:%02x:%02x:%02x:%02x:%02x", 3439 self_mac[0], self_mac[1], self_mac[2], 3440 self_mac[3], self_mac[4], self_mac[5]); 3441 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3442 "ap_macaddr", mac_str); 3443 snprintf(mac_str, sizeof(mac_str), 3444 "%02x%02x%02x%02x%02x%02x", 3445 self_mac[0], self_mac[1], self_mac[2], 3446 self_mac[3], self_mac[4], self_mac[5]); 3447 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3448 "r1_key_holder", mac_str); 3449 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3450 "ft_psk_generate_local", "1"); 3451 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3452 "kh_key_hex", 3453 "000102030405060708090a0b0c0d0e0f"); 3454 snprintf(mac_str, sizeof(mac_str), 3455 "%02x:%02x:%02x:%02x:%02x:%02x", 3456 dut->ft_bss_mac_list[0][0], 3457 dut->ft_bss_mac_list[0][1], 3458 dut->ft_bss_mac_list[0][2], 3459 dut->ft_bss_mac_list[0][3], 3460 dut->ft_bss_mac_list[0][4], 3461 dut->ft_bss_mac_list[0][5]); 3462 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3463 "ap2_macaddr", mac_str); 3464 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3465 "ap2_r1_key_holder", mac_str); 3466 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3467 "nasid2", "nas2.example.com"); 3468 } 3469 3470 if (dut->ap_tag_key_mgmt[j] == AP2_OSEN && 3471 wlan_tag == 2) { 3472 /* Only supported for WLAN_TAG=2 */ 3473 owrt_ap_set_vap(dut, vap_count + 1, "osen", 3474 "1"); 3475 snprintf(buf, sizeof(buf), "wpa2"); 3476 owrt_ap_set_vap(dut, vap_count + 1, 3477 "encryption", buf); 3478 snprintf(buf, sizeof(buf), "%s", 3479 dut->ap2_radius_ipaddr); 3480 owrt_ap_set_vap(dut, vap_count + 1, 3481 "auth_server", buf); 3482 snprintf(buf, sizeof(buf), "%d", 3483 dut->ap2_radius_port); 3484 owrt_ap_set_vap(dut, vap_count + 1, 3485 "auth_port", buf); 3486 snprintf(buf, sizeof(buf), "%s", 3487 dut->ap2_radius_password); 3488 owrt_ap_set_vap(dut, vap_count + 1, 3489 "auth_secret", buf); 3490 } else if (dut->ap_tag_key_mgmt[j] == AP2_WPA2_PSK) { 3491 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3492 "encryption", "psk2+ccmp"); 3493 snprintf(buf, sizeof(buf), "\"%s\"", 3494 dut->ap_passphrase); 3495 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3496 "key", buf); 3497 snprintf(buf, sizeof(buf), "%d", dut->ap_pmf); 3498 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3499 "ieee80211w", buf); 3500 } else if (dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) { 3501 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3502 "owe", "1"); 3503 snprintf(buf, sizeof(buf), "ccmp"); 3504 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3505 "encryption", buf); 3506 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3507 "ieee80211w", "2"); 3508 if (dut->ap_sae_groups) { 3509 snprintf(buf, sizeof(buf), "\'%s\'", 3510 dut->ap_sae_groups); 3511 owrt_ap_set_list_vap(dut, vap_count + 3512 (wlan_tag - 1), 3513 "owe_groups", buf); 3514 if (dut->owe_ptk_workaround) 3515 owrt_ap_set_list_vap( 3516 dut, vap_count + 3517 (wlan_tag - 1), 3518 "owe_ptk_workaround", 3519 "1"); 3520 } 3521 } 3522 } 3523 3524 /* Now set anqp_elem and ft_oa for wlan_tag = 1 */ 3525 if (dut->program == PROGRAM_MBO && 3526 get_driver_type(dut) == DRIVER_OPENWRT) { 3527 unsigned char self_mac[ETH_ALEN]; 3528 char mac_str[20]; 3529 char anqp_string[200]; 3530 3531 if (set_anqp_elem_value(dut, sigma_radio_ifname[0], 3532 anqp_string, 3533 sizeof(anqp_string)) < 0) 3534 return -1; 3535 owrt_ap_set_list_vap(dut, vap_count, "anqp_elem", 3536 anqp_string); 3537 3538 if (ap_ft_enabled(dut)) { 3539 owrt_ap_set_vap(dut, vap_count, 3540 "mobility_domain", 3541 dut->ap_mobility_domain); 3542 owrt_ap_set_vap(dut, vap_count, 3543 "ft_over_ds", 3544 dut->ap_ft_ds == VALUE_ENABLED ? 3545 "1" : "0"); 3546 owrt_ap_set_vap(dut, vap_count, 3547 "ieee80211r", "1"); 3548 owrt_ap_set_vap(dut, vap_count, 3549 "nasid", "nas1.example.com"); 3550 get_hwaddr(sigma_radio_ifname[0], self_mac); 3551 snprintf(mac_str, sizeof(mac_str), 3552 "%02x:%02x:%02x:%02x:%02x:%02x", 3553 self_mac[0], self_mac[1], self_mac[2], 3554 self_mac[3], self_mac[4], self_mac[5]); 3555 owrt_ap_set_vap(dut, vap_count, 3556 "ap_macaddr", mac_str); 3557 snprintf(mac_str, sizeof(mac_str), 3558 "%02x%02x%02x%02x%02x%02x", 3559 self_mac[0], self_mac[1], self_mac[2], 3560 self_mac[3], self_mac[4], self_mac[5]); 3561 owrt_ap_set_vap(dut, vap_count, 3562 "r1_key_holder", mac_str); 3563 owrt_ap_set_vap(dut, vap_count, 3564 "ft_psk_generate_local", "1"); 3565 owrt_ap_set_vap(dut, vap_count, 3566 "kh_key_hex", 3567 "000102030405060708090a0b0c0d0e0f"); 3568 snprintf(mac_str, sizeof(mac_str), 3569 "%02x:%02x:%02x:%02x:%02x:%02x", 3570 dut->ft_bss_mac_list[0][0], 3571 dut->ft_bss_mac_list[0][1], 3572 dut->ft_bss_mac_list[0][2], 3573 dut->ft_bss_mac_list[0][3], 3574 dut->ft_bss_mac_list[0][4], 3575 dut->ft_bss_mac_list[0][5]); 3576 owrt_ap_set_vap(dut, vap_count, 3577 "ap2_macaddr", mac_str); 3578 owrt_ap_set_vap(dut, vap_count, 3579 "ap2_r1_key_holder", mac_str); 3580 owrt_ap_set_vap(dut, vap_count, 3581 "nasid2", "nas2.example.com"); 3582 } 3583 } 3584 3585 if (dut->ap_oce == VALUE_ENABLED && 3586 get_driver_type(dut) == DRIVER_OPENWRT) { 3587 owrt_ap_set_vap(dut, vap_id, "oce", "1"); 3588 owrt_ap_set_vap(dut, vap_id, "qbssload", "1"); 3589 owrt_ap_set_vap(dut, vap_id, "bpr_enable", "1"); 3590 3591 if (dut->ap_80plus80 == 1) 3592 owrt_ap_set_vap(dut, vap_id, "cfreq2", "5775"); 3593 3594 if (dut->ap_akm == 1) { 3595 owrt_ap_set_vap(dut, vap_id, "wpa_group_rekey", 3596 "3600"); 3597 owrt_ap_set_vap(dut, vap_id, "key", "12345678"); 3598 owrt_ap_set_vap(dut, vap_id, "ieee80211ai", 3599 "1"); 3600 owrt_ap_set_vap(dut, vap_id, "fils_cache_id", 3601 "1234"); 3602 owrt_ap_set_vap(dut, vap_id, 3603 "erp_send_reauth_start", "1"); 3604 } 3605 3606 if (dut->ap_filshlp == VALUE_ENABLED) { 3607 struct ifreq ifr; 3608 char *ifname; 3609 int s; 3610 struct sockaddr_in *ipaddr; 3611 3612 s = socket(AF_INET, SOCK_DGRAM, 0); 3613 if (s < 0) { 3614 sigma_dut_print(dut, DUT_MSG_ERROR, 3615 "Failed to open socket"); 3616 return -1; 3617 } 3618 ifr.ifr_addr.sa_family = AF_INET; 3619 3620 memset(&ifr, 0, sizeof(ifr)); 3621 ifname = "br-lan"; 3622 strlcpy(ifr.ifr_name, ifname, 3623 sizeof(ifr.ifr_name)); 3624 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { 3625 perror("ioctl"); 3626 close(s); 3627 return -1; 3628 } 3629 3630 ipaddr = (struct sockaddr_in*)&ifr.ifr_addr; 3631 snprintf(buf, sizeof(buf), "%s", 3632 inet_ntoa(ipaddr->sin_addr)); 3633 owrt_ap_set_vap(dut, vap_id, "own_ip_addr", 3634 buf); 3635 snprintf(buf, sizeof(buf), "%s", 3636 dut->ap_dhcpserv_ipaddr); 3637 owrt_ap_set_vap(dut, vap_id, "dhcp_server", 3638 buf); 3639 owrt_ap_set_vap(dut, vap_id, 3640 "dhcp_rapid_commit_proxy", "1"); 3641 owrt_ap_set_vap(dut, vap_id, 3642 "fils_hlp_wait_time", "300"); 3643 } 3644 3645 if (dut->ap_filsdscv == VALUE_ENABLED) { 3646 owrt_ap_set_vap(dut, vap_id, "ieee80211ai", 3647 "1"); 3648 owrt_ap_set_vap(dut, vap_id, "fils_fd_period", 3649 "20"); 3650 } 3651 } 3652 3653 if (dut->ap_filsdscv == VALUE_DISABLED) { 3654 owrt_ap_set_vap(dut, vap_id, "ieee80211ai", "0"); 3655 owrt_ap_set_vap(dut, vap_id, "fils_fd_period", "0"); 3656 } 3657 3658 if (dut->ap_oce == VALUE_DISABLED && 3659 get_driver_type(dut) == DRIVER_OPENWRT) { 3660 owrt_ap_set_vap(dut, vap_id, "oce", "0"); 3661 owrt_ap_set_vap(dut, vap_id, "qbssload", "0"); 3662 owrt_ap_set_vap(dut, vap_id, "bpr_enable", "0"); 3663 3664 if (dut->ap_filsdscv == VALUE_DISABLED) { 3665 owrt_ap_set_vap(dut, vap_id, "ieee80211ai", 3666 "0"); 3667 owrt_ap_set_vap(dut, vap_id, "fils_fd_period", 3668 "0"); 3669 } 3670 3671 if (dut->device_type == AP_testbed) 3672 owrt_ap_set_vap(dut, vap_id, "mbo", "1"); 3673 } 3674 3675 /* NAIRealm */ 3676 if (dut->ap_nairealm_int == 1) { 3677 snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_nairealm); 3678 owrt_ap_set_vap(dut, vap_id, "fils_realm", buf); 3679 owrt_ap_set_vap(dut, vap_id, "erp_domain", buf); 3680 } 3681 3682 /* SSID */ 3683 snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_ssid); 3684 owrt_ap_set_vap(dut, vap_count, "ssid", buf); 3685 3686 /* Encryption */ 3687 switch (dut->ap_key_mgmt) { 3688 case AP_OPEN: 3689 if (dut->ap_cipher == AP_WEP) { 3690 owrt_ap_set_vap(dut, vap_count, "encryption", 3691 "wep-mixed"); 3692 owrt_ap_set_vap(dut, vap_count, "key", 3693 dut->ap_wepkey); 3694 } else { 3695 owrt_ap_set_vap(dut, vap_count, "encryption", 3696 "none"); 3697 } 3698 if (dut->ap_key_mgmt == AP_OPEN && 3699 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) { 3700 /* OWE transition mode */ 3701 snprintf(ifname2, sizeof(ifname2), "%s1", 3702 ifname); 3703 owrt_ap_set_vap(dut, vap_count, 3704 "owe_transition_ifname", 3705 ifname2); 3706 } 3707 break; 3708 case AP_WPA2_PSK: 3709 case AP_WPA2_PSK_MIXED: 3710 case AP_WPA_PSK: 3711 case AP_WPA2_SAE: 3712 case AP_WPA2_PSK_SAE: 3713 if (dut->ap_key_mgmt == AP_WPA2_PSK || 3714 dut->ap_key_mgmt == AP_WPA2_PSK_SAE) { 3715 snprintf(buf, sizeof(buf), "psk2"); 3716 } else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) { 3717 snprintf(buf, sizeof(buf), "psk-mixed"); 3718 } else if (dut->ap_key_mgmt == AP_WPA2_SAE) { 3719 snprintf(buf, sizeof(buf), "ccmp"); 3720 } else { 3721 snprintf(buf, sizeof(buf), "psk"); 3722 } 3723 3724 if (dut->ap_key_mgmt != AP_WPA2_SAE) { 3725 if (dut->ap_cipher == AP_CCMP_TKIP) 3726 strlcat(buf, "+ccmp+tkip", sizeof(buf)); 3727 else if (dut->ap_cipher == AP_TKIP) 3728 strlcat(buf, "+tkip", sizeof(buf)); 3729 else if (dut->ap_cipher == AP_GCMP_128) 3730 strlcat(buf, "+gcmp", sizeof(buf)); 3731 else 3732 strlcat(buf, "+ccmp", sizeof(buf)); 3733 } 3734 3735 owrt_ap_set_vap(dut, vap_count, "encryption", buf); 3736 3737 if (!dut->ap_passphrase[0] && dut->ap_psk[0]) { 3738 snprintf(buf, sizeof(buf), "\"%s\"", 3739 dut->ap_psk); 3740 owrt_ap_set_vap(dut, vap_count, "key", buf); 3741 } else { 3742 snprintf(buf, sizeof(buf), "\"%s\"", 3743 dut->ap_passphrase); 3744 owrt_ap_set_vap(dut, vap_count, "key", buf); 3745 } 3746 3747 if (dut->ap_key_mgmt == AP_WPA2_SAE || 3748 dut->ap_key_mgmt == AP_WPA2_PSK_SAE) 3749 owrt_ap_set_vap(dut, vap_count, "sae", "1"); 3750 else 3751 owrt_ap_set_vap(dut, vap_count, "sae", "0"); 3752 3753 if (dut->ap_key_mgmt == AP_WPA2_SAE) { 3754 snprintf(buf, sizeof(buf), "%s", 3755 dut->ap_passphrase); 3756 owrt_ap_set_vap(dut, vap_count, "sae_password", 3757 buf); 3758 } else { 3759 snprintf(buf, sizeof(buf), "%s", 3760 dut->ap_passphrase); 3761 owrt_ap_set_vap(dut, vap_count, 3762 "wpa_passphrase", buf); 3763 } 3764 break; 3765 case AP_WPA2_EAP: 3766 case AP_WPA2_EAP_MIXED: 3767 case AP_WPA_EAP: 3768 if (dut->ap_key_mgmt == AP_WPA2_EAP) { 3769 snprintf(buf, sizeof(buf), "wpa2"); 3770 } else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) { 3771 snprintf(buf, sizeof(buf), "wpa-mixed"); 3772 } else { 3773 snprintf(buf, sizeof(buf), "wpa"); 3774 } 3775 3776 if (dut->ap_cipher == AP_CCMP_TKIP) 3777 strlcat(buf, "+ccmp+tkip", sizeof(buf)); 3778 else if (dut->ap_cipher == AP_TKIP) 3779 strlcat(buf, "+tkip", sizeof(buf)); 3780 else 3781 strlcat(buf, "+ccmp", sizeof(buf)); 3782 3783 owrt_ap_set_vap(dut, vap_count, "encryption", buf); 3784 snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr); 3785 owrt_ap_set_vap(dut, vap_count, "auth_server", buf); 3786 snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port); 3787 owrt_ap_set_vap(dut, vap_count, "auth_port", buf); 3788 snprintf(buf, sizeof(buf), "%s", 3789 dut->ap_radius_password); 3790 owrt_ap_set_vap(dut, vap_count, "auth_secret", buf); 3791 break; 3792 case AP_WPA2_EAP_OSEN: 3793 case AP_OSEN: 3794 case AP_WPA2_FT_EAP: 3795 case AP_WPA2_FT_PSK: 3796 case AP_WPA2_EAP_SHA256: 3797 case AP_WPA2_PSK_SHA256: 3798 case AP_WPA2_ENT_FT_EAP: 3799 /* TODO */ 3800 break; 3801 case AP_SUITEB: 3802 owrt_ap_set_vap(dut, vap_count, "suite_b", "192"); 3803 snprintf(buf, sizeof(buf), "gcmp"); 3804 owrt_ap_set_vap(dut, vap_count, "encryption", buf); 3805 snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr); 3806 owrt_ap_set_vap(dut, vap_count, "auth_server", buf); 3807 snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port); 3808 owrt_ap_set_vap(dut, vap_count, "auth_port", buf); 3809 snprintf(buf, sizeof(buf), "%s", 3810 dut->ap_radius_password); 3811 owrt_ap_set_vap(dut, vap_count, "auth_secret", buf); 3812 snprintf(buf, sizeof(buf), "%d", 3813 dut->ap_group_mgmt_cipher); 3814 owrt_ap_set_vap(dut, vap_count, "group_mgmt_cipher", 3815 buf); 3816 break; 3817 case AP_WPA2_OWE: 3818 owrt_ap_set_vap(dut, vap_count, "owe", "1"); 3819 snprintf(buf, sizeof(buf), "ccmp"); 3820 owrt_ap_set_vap(dut, vap_count, "encryption", buf); 3821 if (dut->ap_sae_groups) { 3822 snprintf(buf, sizeof(buf), "\'%s\'", 3823 dut->ap_sae_groups); 3824 owrt_ap_set_list_vap(dut, vap_count, 3825 "owe_groups", buf); 3826 if (dut->owe_ptk_workaround) 3827 owrt_ap_set_list_vap( 3828 dut, vap_count, 3829 "owe_ptk_workaround", "1"); 3830 } 3831 3832 if (dut->ap_key_mgmt == AP_WPA2_OWE && 3833 dut->ap_tag_ssid[0][0] && 3834 dut->ap_tag_key_mgmt[0] == AP2_OPEN) { 3835 /* OWE transition mode */ 3836 snprintf(ifname2, sizeof(ifname2), "%s1", 3837 ifname); 3838 owrt_ap_set_vap(dut, vap_count, 3839 "owe_transition_ifname", 3840 ifname2); 3841 owrt_ap_set_vap(dut, vap_count, "hidden", "1"); 3842 } 3843 break; 3844 } 3845 3846 if (!dut->ap_is_dual) 3847 break; 3848 } 3849 3850 if (dut->ap_is_dual) 3851 return 1; 3852 3853 /* PMF */ 3854 snprintf(buf, sizeof(buf), "%d", dut->ap_pmf); 3855 owrt_ap_set_vap(dut, vap_id, "ieee80211w", buf); 3856 3857 /* Add SHA256 */ 3858 snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha256); 3859 owrt_ap_set_vap(dut, vap_id, "add_sha256", buf); 3860 3861 /* Add SHA384 for akmsuitetype 15 */ 3862 if (dut->ap_akm == 1) { 3863 snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha384); 3864 owrt_ap_set_vap(dut, vap_id, "add_sha384", buf); 3865 } 3866 3867 /* Enable RSN preauthentication, if asked to */ 3868 snprintf(buf, sizeof(buf), "%d", dut->ap_rsn_preauth); 3869 owrt_ap_set_vap(dut, vap_id, "rsn_preauth", buf); 3870 3871 /* Hotspot 2.0 */ 3872 if (dut->ap_hs2) { 3873 int ret; 3874 3875 ret = owrt_ap_config_vap_hs2(dut, vap_id); 3876 if (ret) 3877 return ret; 3878 } 3879 3880 /* Interworking */ 3881 if (dut->ap_interworking) { 3882 snprintf(buf, sizeof(buf), "%d", dut->ap_access_net_type); 3883 owrt_ap_set_vap(dut, vap_id, "access_network_type", buf); 3884 snprintf(buf, sizeof(buf), "%d", dut->ap_internet); 3885 owrt_ap_set_vap(dut, vap_id, "internet", buf); 3886 snprintf(buf, sizeof(buf), "%d", dut->ap_venue_group); 3887 owrt_ap_set_vap(dut, vap_id, "venue_group", buf); 3888 snprintf(buf, sizeof(buf), "%d", dut->ap_venue_type); 3889 owrt_ap_set_vap(dut, vap_id, "venue_type", buf); 3890 snprintf(buf, sizeof(buf), "%s", dut->ap_hessid); 3891 owrt_ap_set_vap(dut, vap_id, "hessid", buf); 3892 3893 if (dut->ap_gas_cb_delay > 0) { 3894 snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay); 3895 owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf); 3896 } 3897 3898 if (dut->ap_roaming_cons[0]) { 3899 char *rcons, *temp_ptr; 3900 3901 rcons = strdup(dut->ap_roaming_cons); 3902 if (rcons == NULL) 3903 return -1; 3904 3905 temp_ptr = strchr(rcons, ';'); 3906 3907 if (temp_ptr) 3908 *temp_ptr++ = '\0'; 3909 3910 owrt_ap_set_list_vap(dut, vap_id, "roaming_consortium", 3911 rcons); 3912 3913 if (temp_ptr) 3914 owrt_ap_set_list_vap(dut, vap_id, 3915 "roaming_consortium", 3916 temp_ptr); 3917 3918 free(rcons); 3919 } 3920 } 3921 3922 if (dut->ap_venue_name) { 3923 owrt_ap_set_list_vap(dut, vap_id, "venue_name", 3924 "'P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"'"); 3925 owrt_ap_set_list_vap(dut, vap_id, "venue_name", 3926 "\'"ANQP_VENUE_NAME_1_CHI"\'"); 3927 } 3928 3929 if (dut->ap_net_auth_type == 1) { 3930 owrt_ap_set_list_vap(dut, vap_id, "network_auth_type", 3931 "'00https://tandc-server.wi-fi.org'"); 3932 } else if (dut->ap_net_auth_type == 2) { 3933 owrt_ap_set_list_vap(dut, vap_id, "network_auth_type", "'01'"); 3934 } 3935 3936 if (dut->ap_nai_realm_list == 1) { 3937 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3938 "'0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]'"); 3939 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3940 "'0,wi-fi.org;example.com,13[5:6]'"); 3941 3942 } else if (dut->ap_nai_realm_list == 2) { 3943 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3944 "'0,wi-fi.org,21[2:4][5:7]'"); 3945 } else if (dut->ap_nai_realm_list == 3) { 3946 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3947 "'0,cisco.com;wi-fi.org,21[2:4][5:7]'"); 3948 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3949 "'0,wi-fi.org;example.com,13[5:6]'"); 3950 } else if (dut->ap_nai_realm_list == 4) { 3951 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3952 "'0,mail.example.com,21[2:4][5:7],13[5:6]'"); 3953 } else if (dut->ap_nai_realm_list == 5) { 3954 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3955 "'0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]'"); 3956 } else if (dut->ap_nai_realm_list == 6) { 3957 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3958 "'0,wi-fi.org;mail.example.com,21[2:4][5:7]'"); 3959 } else if (dut->ap_nai_realm_list == 7) { 3960 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3961 "'0,wi-fi.org,13[5:6]'"); 3962 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3963 "'0,wi-fi.org,21[2:4][5:7]'"); 3964 } 3965 3966 if (dut->ap_domain_name_list[0]) 3967 owrt_ap_set_list_vap(dut, vap_id, "domain_name", 3968 dut->ap_domain_name_list); 3969 3970 if (dut->ap_ip_addr_type_avail) 3971 owrt_ap_set_vap(dut, vap_id, "ipaddr_type_availability", 3972 "'0c'"); 3973 3974 temp = buf; 3975 3976 *temp++ = '\''; 3977 3978 for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) { 3979 if (i) 3980 *temp++ = ';'; 3981 3982 snprintf(temp, 3983 sizeof(dut->ap_plmn_mcc[i]) + 3984 sizeof(dut->ap_plmn_mnc[i]) + 1, 3985 "%s,%s", 3986 dut->ap_plmn_mcc[i], 3987 dut->ap_plmn_mnc[i]); 3988 3989 temp += strlen(dut->ap_plmn_mcc[i]) + 3990 strlen(dut->ap_plmn_mnc[i]) + 1; 3991 } 3992 3993 *temp++ = '\''; 3994 *temp++ = '\0'; 3995 3996 if (i) 3997 owrt_ap_set_vap(dut, vap_id, "anqp_3gpp_cell_net", buf); 3998 3999 if (dut->ap_qos_map_set == 1) 4000 owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_1); 4001 else if (dut->ap_qos_map_set == 2) 4002 owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_2); 4003 4004 /* Proxy-ARP */ 4005 snprintf(buf, sizeof(buf), "%d", dut->ap_proxy_arp); 4006 owrt_ap_set_vap(dut, vap_id, "proxyarp", buf); 4007 4008 /* DGAF */ 4009 snprintf(buf, sizeof(buf), "%d", dut->ap_dgaf_disable); 4010 /* parse to hostapd */ 4011 owrt_ap_set_vap(dut, vap_id, "disable_dgaf", buf); 4012 /* parse to wifi driver */ 4013 owrt_ap_set_vap(dut, vap_id, "dgaf_disable", buf); 4014 4015 /* HCBSSLoad */ 4016 if (dut->ap_bss_load) { 4017 unsigned int bssload = 0; 4018 4019 if (dut->ap_bss_load == 1) { 4020 /* STA count: 1, CU: 50, AAC: 65535 */ 4021 bssload = 0x0132ffff; 4022 } else if (dut->ap_bss_load == 2) { 4023 /* STA count: 1, CU: 200, AAC: 65535 */ 4024 bssload = 0x01c8ffff; 4025 } else if (dut->ap_bss_load == 3) { 4026 /* STA count: 1, CU: 75, AAC: 65535 */ 4027 bssload = 0x014bffff; 4028 } 4029 4030 snprintf(buf, sizeof(buf), "%d", bssload); 4031 owrt_ap_set_vap(dut, vap_id, "hcbssload", buf); 4032 } 4033 4034 /* L2TIF */ 4035 if (dut->ap_l2tif) 4036 owrt_ap_set_vap(dut, vap_id, "l2tif", "1"); 4037 4038 if (dut->ap_disable_protection == 1) 4039 owrt_ap_set_vap(dut, vap_id, "enablertscts", "0"); 4040 4041 if (dut->ap_txBF) { 4042 owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "1"); 4043 owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "1"); 4044 if (dut->program == PROGRAM_HE) { 4045 owrt_ap_set_vap(dut, vap_id, "he_subfer", "1"); 4046 owrt_ap_set_vap(dut, vap_id, "cwmenable", "0"); 4047 } 4048 } else { 4049 owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0"); 4050 owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0"); 4051 if (dut->program == PROGRAM_HE) 4052 owrt_ap_set_vap(dut, vap_id, "he_subfer", "0"); 4053 } 4054 4055 if (dut->ap_mu_txBF) { 4056 owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "1"); 4057 if (dut->program == PROGRAM_HE) { 4058 owrt_ap_set_vap(dut, vap_id, "he_mubfer", "1"); 4059 owrt_ap_set_vap(dut, vap_id, "he_mubfee", "1"); 4060 } 4061 } else { 4062 owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "0"); 4063 if (dut->program == PROGRAM_HE) { 4064 owrt_ap_set_vap(dut, vap_id, "he_mubfer", "0"); 4065 owrt_ap_set_vap(dut, vap_id, "he_mubfee", "0"); 4066 } 4067 } 4068 4069 if (dut->ap_tx_stbc) { 4070 /* STBC and beamforming are mutually exclusive features */ 4071 owrt_ap_set_vap(dut, vap_id, "implicitbf", "0"); 4072 } 4073 4074 /* enable dfsmode */ 4075 snprintf(buf, sizeof(buf), "%d", dut->ap_dfs_mode); 4076 owrt_ap_set_vap(dut, vap_id, "doth", buf); 4077 4078 if (dut->program == PROGRAM_LOC && dut->ap_interworking) { 4079 char anqpval[1024]; 4080 4081 owrt_ap_set_vap(dut, vap_id, "interworking", "1"); 4082 4083 if (dut->ap_lci == 1 && strlen(dut->ap_tag_ssid[0]) == 0) { 4084 snprintf(anqpval, sizeof(anqpval), 4085 "'265:0010%s%s060101'", 4086 dut->ap_val_lci, dut->ap_infoz); 4087 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval); 4088 } 4089 4090 if (dut->ap_lcr == 1) { 4091 snprintf(anqpval, sizeof(anqpval), 4092 "'266:0000b2555302ae%s'", 4093 dut->ap_val_lcr); 4094 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval); 4095 } 4096 4097 if (dut->ap_fqdn_held == 1 && dut->ap_fqdn_supl == 1) 4098 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", 4099 "'267:00110168656c642e6578616d706c652e636f6d0011027375706c2e6578616d706c652e636f6d'"); 4100 } 4101 4102 if (dut->program == PROGRAM_MBO) { 4103 owrt_ap_set_vap(dut, vap_id, "interworking", "1"); 4104 owrt_ap_set_vap(dut, vap_id, "mbo", "1"); 4105 owrt_ap_set_vap(dut, vap_id, "rrm", "1"); 4106 owrt_ap_set_vap(dut, vap_id, "mbo_cell_conn_pref", "1"); 4107 4108 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", 4109 "'272:34108cfdf0020df1f7000000733000030101'"); 4110 snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay); 4111 owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf); 4112 } 4113 4114 if (ap_ft_enabled(dut)) { 4115 unsigned char self_mac[ETH_ALEN]; 4116 char mac_str[20]; 4117 4118 owrt_ap_set_vap(dut, vap_id, "ft_over_ds", 4119 dut->ap_ft_ds == VALUE_ENABLED ? "1" : "0"); 4120 owrt_ap_set_vap(dut, vap_id, "ieee80211r", "1"); 4121 if (get_hwaddr(sigma_radio_ifname[0], self_mac) < 0) 4122 return -1; 4123 snprintf(mac_str, sizeof(mac_str), 4124 "%02x:%02x:%02x:%02x:%02x:%02x", 4125 self_mac[0], self_mac[1], self_mac[2], 4126 self_mac[3], self_mac[4], self_mac[5]); 4127 owrt_ap_set_vap(dut, vap_id, "ap_macaddr", mac_str); 4128 snprintf(mac_str, sizeof(mac_str), 4129 "%02x:%02x:%02x:%02x:%02x:%02x", 4130 self_mac[0], self_mac[1], self_mac[2], 4131 self_mac[3], self_mac[4], self_mac[5]); 4132 owrt_ap_set_vap(dut, vap_id, "r1_key_holder", mac_str); 4133 owrt_ap_set_vap(dut, vap_id, "ft_psk_generate_local", "1"); 4134 owrt_ap_set_vap(dut, vap_id, "kh_key_hex", 4135 "000102030405060708090a0b0c0d0e0f"); 4136 snprintf(mac_str, sizeof(mac_str), 4137 "%02x:%02x:%02x:%02x:%02x:%02x", 4138 dut->ft_bss_mac_list[0][0], 4139 dut->ft_bss_mac_list[0][1], 4140 dut->ft_bss_mac_list[0][2], 4141 dut->ft_bss_mac_list[0][3], 4142 dut->ft_bss_mac_list[0][4], 4143 dut->ft_bss_mac_list[0][5]); 4144 owrt_ap_set_vap(dut, vap_id, "ap2_macaddr", mac_str); 4145 owrt_ap_set_vap(dut, vap_id, "mobility_domain", 4146 dut->ap_mobility_domain); 4147 owrt_ap_set_vap(dut, vap_id, "ap2_r1_key_holder", mac_str); 4148 } 4149 4150 if ((ap_ft_enabled(dut) && dut->ap_name == 0) || 4151 (ap_ft_enabled(dut) && dut->ap_name == 2)) { 4152 owrt_ap_set_vap(dut, vap_id, "nasid2", "nas2.example.com"); 4153 owrt_ap_set_vap(dut, vap_id, "nasid", "nas1.example.com"); 4154 } 4155 4156 if (ap_ft_enabled(dut) && dut->ap_name == 1) { 4157 owrt_ap_set_vap(dut, vap_id, "nasid2", "nas1.example.com"); 4158 owrt_ap_set_vap(dut, vap_id, "nasid", "nas2.example.com"); 4159 } 4160 4161 if (dut->ap_broadcast_ssid == VALUE_DISABLED) 4162 owrt_ap_set_vap(dut, vap_id, "hidden", "1"); 4163 4164 /* Enable/disable PMKSA caching, if asked to */ 4165 if (dut->ap_pmksa == 1) { 4166 snprintf(buf, sizeof(buf), "%d", dut->ap_pmksa_caching); 4167 owrt_ap_set_vap(dut, vap_id, "disable_pmksa_caching", buf); 4168 } 4169 4170 if (dut->ap_beacon_prot) 4171 owrt_ap_set_vap(dut, vap_id, "beacon_prot", "1"); 4172 4173 if (dut->ap_transition_disable) { 4174 snprintf(buf, sizeof(buf), "0x%02x", 4175 dut->ap_transition_disable); 4176 owrt_ap_set_vap(dut, vap_id, "transition_disable", buf); 4177 } 4178 4179 if (dut->rsne_override) { 4180 snprintf(buf, sizeof(buf), "%s", dut->rsne_override); 4181 owrt_ap_set_vap(dut, vap_count, "own_ie_override", buf); 4182 } 4183 4184 if (dut->rsnxe_override_eapol) 4185 owrt_ap_set_vap(dut, vap_count, "rsnxe_override_eapol", 4186 dut->rsnxe_override_eapol); 4187 4188 if (dut->sae_commit_override) { 4189 snprintf(buf, sizeof(buf), "%s", dut->sae_commit_override); 4190 owrt_ap_set_vap(dut, vap_count, "sae_commit_override", buf); 4191 } 4192 4193 if (dut->ap_sae_groups) { 4194 snprintf(buf, sizeof(buf), "\'%s\'", dut->ap_sae_groups); 4195 owrt_ap_set_list_vap(dut, vap_count, "sae_groups", buf); 4196 } 4197 4198 if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) { 4199 const char *sae_pwe = NULL; 4200 4201 if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut)) 4202 sae_pwe = "3"; 4203 else if (dut->sae_pwe == SAE_PWE_LOOP) 4204 sae_pwe = "0"; 4205 else if (dut->sae_pwe == SAE_PWE_H2E) 4206 sae_pwe = "1"; 4207 else if (dut->sae_h2e_default) 4208 sae_pwe = "2"; 4209 if (sae_pwe) 4210 owrt_ap_set_vap(dut, vap_count, "sae_pwe", sae_pwe); 4211 } 4212 4213 if (dut->sae_anti_clogging_threshold >= 0) { 4214 snprintf(buf, sizeof(buf), "%d", 4215 dut->sae_anti_clogging_threshold); 4216 owrt_ap_set_vap(dut, vap_count, "sae_anti_clogging_threshold", 4217 buf); 4218 } 4219 4220 if (dut->sae_reflection) 4221 owrt_ap_set_vap(dut, vap_count, "sae_reflection_attack", "1"); 4222 if (dut->sae_confirm_immediate) 4223 owrt_ap_set_vap(dut, vap_count, "sae_confirm_immediate", "2"); 4224 4225 if (dut->ap_he_dlofdma == VALUE_ENABLED && dut->ap_he_ppdu == PPDU_MU) { 4226 dut->ap_txBF = 0; 4227 dut->ap_mu_txBF = 0; 4228 owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0"); 4229 owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0"); 4230 owrt_ap_set_vap(dut, vap_id, "he_subfer", "0"); 4231 } 4232 4233 if (dut->program == PROGRAM_HE && 4234 (dut->ap_txBF || dut->ap_he_ulofdma == VALUE_ENABLED || 4235 dut->ap_he_mimo == MIMO_DL)) { 4236 switch (dut->ap_chwidth) { 4237 case AP_20: 4238 owrt_ap_set_vap(dut, vap_id, "chwidth", "0"); 4239 break; 4240 case AP_40: 4241 owrt_ap_set_vap(dut, vap_id, "chwidth", "1"); 4242 break; 4243 case AP_80: 4244 owrt_ap_set_vap(dut, vap_id, "chwidth", "2"); 4245 break; 4246 case AP_160: 4247 owrt_ap_set_vap(dut, vap_id, "chwidth", "3"); 4248 break; 4249 case AP_80_80: 4250 owrt_ap_set_vap(dut, vap_id, "chwidth", "3"); 4251 break; 4252 case AP_AUTO: 4253 default: 4254 break; 4255 } 4256 } 4257 4258 return 1; 4259 } 4260 4261 4262 static int owrt_ap_config_vap_anqp(struct sigma_dut *dut) 4263 { 4264 char anqpval[1024]; 4265 unsigned char addr[6]; 4266 unsigned char addr2[6]; 4267 struct ifreq ifr; 4268 char *ifname; 4269 int s; 4270 int vap_id = 0; 4271 4272 s = socket(AF_INET, SOCK_DGRAM, 0); 4273 if (s < 0) { 4274 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open socket"); 4275 return -1; 4276 } 4277 4278 memset(&ifr, 0, sizeof(ifr)); 4279 ifname = "ath0"; 4280 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 4281 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { 4282 perror("ioctl"); 4283 close(s); 4284 return -1; 4285 } 4286 memcpy(addr, ifr.ifr_hwaddr.sa_data, 6); 4287 4288 memset(&ifr, 0, sizeof(ifr)); 4289 ifname = "ath01"; 4290 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 4291 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { 4292 perror("ioctl"); 4293 close(s); 4294 return -1; 4295 } 4296 close(s); 4297 memcpy(addr2, ifr.ifr_hwaddr.sa_data, 6); 4298 4299 snprintf(anqpval, sizeof(anqpval), 4300 "'265:0010%s%s060101070d00%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'", 4301 dut->ap_val_lci, dut->ap_infoz, 4302 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], 4303 addr2[0], addr2[1], addr2[2], addr2[3], addr2[4], addr2[5]); 4304 4305 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval); 4306 return 0; 4307 } 4308 4309 4310 static int owrt_ap_post_config_commit(struct sigma_dut *dut, 4311 struct sigma_conn *conn, 4312 struct sigma_cmd *cmd) 4313 { 4314 int ap_security = 0; 4315 int i; 4316 4317 for (i = 0; i < MAX_WLAN_TAGS - 1; i++) { 4318 if (dut->ap_tag_key_mgmt[i] != AP2_OPEN) 4319 ap_security = 1; 4320 } 4321 if (dut->ap_key_mgmt != AP_OPEN) 4322 ap_security = 1; 4323 if (ap_security) { 4324 /* allow some time for hostapd to start before returning 4325 * success */ 4326 usleep(500000); 4327 4328 if (run_hostapd_cli(dut, "ping") != 0) { 4329 send_resp(dut, conn, SIGMA_ERROR, 4330 "errorCode,Failed to talk to hostapd"); 4331 return 0; 4332 } 4333 } 4334 4335 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 4336 ath_ap_set_params(dut); 4337 4338 /* Send response */ 4339 return 1; 4340 } 4341 4342 4343 static int cmd_owrt_ap_config_commit(struct sigma_dut *dut, 4344 struct sigma_conn *conn, 4345 struct sigma_cmd *cmd) 4346 { 4347 if (dut->program == PROGRAM_DPP && 4348 get_driver_type(dut) == DRIVER_OPENWRT) { 4349 wpa_command(dut->hostapd_ifname, "DPP_BOOTSTRAP_REMOVE *"); 4350 wpa_command(dut->hostapd_ifname, "DPP_PKEX_REMOVE *"); 4351 } 4352 4353 /* Stop the AP */ 4354 run_system(dut, "wifi down"); 4355 4356 /* Reset the wireless configuration */ 4357 run_system(dut, "rm -rf /etc/config/wireless"); 4358 switch (get_openwrt_driver_type()) { 4359 case OPENWRT_DRIVER_ATHEROS: 4360 run_system(dut, "wifi detect qcawifi > /etc/config/wireless"); 4361 break; 4362 default: 4363 run_system(dut, "wifi detect > /etc/config/wireless"); 4364 break; 4365 } 4366 4367 /* Configure Radio & VAP, commit the config */ 4368 if (owrt_ap_config_radio(dut) < 0) 4369 return ERROR_SEND_STATUS; 4370 if (owrt_ap_config_vap(dut) < 0) 4371 return ERROR_SEND_STATUS; 4372 run_system(dut, "uci commit"); 4373 4374 /* Start AP */ 4375 run_system(dut, "wifi up"); 4376 if (dut->program != PROGRAM_MBO && 4377 dut->ap_lci == 1 && dut->ap_interworking && 4378 strlen(dut->ap_tag_ssid[0]) > 0) { 4379 /* 4380 * MBO has a different ANQP element value which is set in 4381 * owrt_ap_config_vap(). 4382 */ 4383 owrt_ap_config_vap_anqp(dut); 4384 run_system(dut, "uci commit"); 4385 run_system(dut, "wifi"); 4386 } 4387 4388 return owrt_ap_post_config_commit(dut, conn, cmd); 4389 } 4390 4391 4392 static void cmd_owrt_ap_hs2_reset(struct sigma_dut *dut) 4393 { 4394 unsigned char bssid[6]; 4395 char buf[100]; 4396 char *ifname, *radio_name; 4397 int vap_id = 0; 4398 4399 if (sigma_radio_ifname[0] && 4400 strcmp(sigma_radio_ifname[0], "wifi2") == 0) { 4401 ifname = "ath2"; 4402 radio_name = "wifi2"; 4403 vap_id = 2; 4404 } else if (sigma_radio_ifname[0] && 4405 strcmp(sigma_radio_ifname[0], "wifi1") == 0) { 4406 ifname = "ath1"; 4407 radio_name = "wifi1"; 4408 vap_id = 1; 4409 } else { 4410 ifname = "ath0"; 4411 radio_name = "wifi0"; 4412 vap_id = 0; 4413 } 4414 4415 if (!get_hwaddr(ifname, bssid)) { 4416 snprintf(buf, sizeof(buf), "%s", bssid); 4417 owrt_ap_set_vap(dut, vap_id, "hessid", buf); 4418 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), 4419 "%02x:%02x:%02x:%02x:%02x:%02x", 4420 bssid[0], bssid[1], bssid[2], bssid[3], 4421 bssid[4], bssid[5]); 4422 } else { 4423 if (!get_hwaddr(radio_name, bssid)) { 4424 snprintf(buf, sizeof(buf), "%s", dut->ap_hessid); 4425 owrt_ap_set_vap(dut, vap_id, "hessid", buf); 4426 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), 4427 "%02x:%02x:%02x:%02x:%02x:%02x", 4428 bssid[0], bssid[1], bssid[2], bssid[3], 4429 bssid[4], bssid[5]); 4430 } else { 4431 /* Select & enable/disable radios */ 4432 if (sigma_radio_ifname[0] && 4433 strcmp(sigma_radio_ifname[0], "wifi2") == 0) { 4434 /* We want to use wifi2 */ 4435 owrt_ap_set_radio(dut, 0, "disabled", "1"); 4436 owrt_ap_set_radio(dut, 1, "disabled", "1"); 4437 owrt_ap_set_radio(dut, 2, "disabled", "0"); 4438 owrt_ap_set_vap(dut, vap_id, "device", "wifi2"); 4439 } else if (sigma_radio_ifname[0] && 4440 strcmp(sigma_radio_ifname[0], "wifi1") == 0) { 4441 /* We want to use wifi1 */ 4442 owrt_ap_set_radio(dut, 0, "disabled", "1"); 4443 owrt_ap_set_radio(dut, 1, "disabled", "0"); 4444 owrt_ap_set_vap(dut, vap_id, "device", "wifi1"); 4445 } else { 4446 /* We want to use wifi0 */ 4447 owrt_ap_set_radio(dut, 0, "disabled", "0"); 4448 owrt_ap_set_radio(dut, 1, "disabled", "1"); 4449 owrt_ap_set_vap(dut, vap_id, "device", "wifi0"); 4450 } 4451 4452 run_system(dut, "uci commit"); 4453 run_system(dut, "wifi up"); 4454 4455 if (!get_hwaddr(radio_name, bssid)) { 4456 snprintf(buf, sizeof(buf), "%s", 4457 dut->ap_hessid); 4458 owrt_ap_set_vap(dut, vap_id, "hessid", buf); 4459 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), 4460 "%02x:%02x:%02x:%02x:%02x:%02x", 4461 bssid[0], bssid[1], bssid[2], bssid[3], 4462 bssid[4], bssid[5]); 4463 } 4464 } 4465 } 4466 } 4467 4468 4469 static enum sigma_cmd_result cmd_ap_reboot(struct sigma_dut *dut, 4470 struct sigma_conn *conn, 4471 struct sigma_cmd *cmd) 4472 { 4473 switch (get_driver_type(dut)) { 4474 case DRIVER_ATHEROS: 4475 run_system(dut, "apdown"); 4476 sleep(1); 4477 run_system(dut, "reboot"); 4478 break; 4479 case DRIVER_OPENWRT: 4480 run_system(dut, "wifi down"); 4481 sleep(1); 4482 run_system(dut, "reboot"); 4483 break; 4484 default: 4485 sigma_dut_print(dut, DUT_MSG_INFO, "Ignore ap_reboot command"); 4486 break; 4487 } 4488 4489 return 1; 4490 } 4491 4492 4493 int ascii2hexstr(const char *str, char *hex) 4494 { 4495 int i, length; 4496 4497 length = strlen(str); 4498 4499 for (i = 0; i < length; i++) 4500 snprintf(hex + i * 2, 3, "%X", str[i]); 4501 4502 hex[length * 2] = '\0'; 4503 return 1; 4504 } 4505 4506 4507 static int kill_process(struct sigma_dut *dut, char *proc_name, 4508 unsigned char is_proc_instance_one, int sig) 4509 { 4510 #ifdef __linux__ 4511 struct dirent *dp, *dp_in; 4512 const char *direc = "/proc/"; 4513 char buf[100]; 4514 DIR *dir = opendir(direc); 4515 DIR *dir_in; 4516 FILE *fp; 4517 char *pid, *temp; 4518 char *saveptr; 4519 int ret = -1, res; 4520 4521 if (dir == NULL) 4522 return ret; 4523 4524 while ((dp = readdir(dir)) != NULL) { 4525 if (dp->d_type != DT_DIR) 4526 continue; 4527 4528 res = snprintf(buf, sizeof(buf), "%s%s", direc, dp->d_name); 4529 if (res < 0 || res >= sizeof(buf)) 4530 continue; 4531 dir_in = opendir(buf); 4532 if (dir_in == NULL) 4533 continue; 4534 dp_in = readdir(dir_in); 4535 closedir(dir_in); 4536 if (dp_in == NULL) 4537 continue; 4538 res = snprintf(buf, sizeof(buf), "%s%s/stat", 4539 direc, dp->d_name); 4540 if (res < 0 || res >= sizeof(buf)) 4541 continue; 4542 fp = fopen(buf, "r"); 4543 if (fp == NULL) 4544 continue; 4545 if (fgets(buf, 100, fp) == NULL) 4546 buf[0] = '\0'; 4547 fclose(fp); 4548 pid = strtok_r(buf, " ", &saveptr); 4549 temp = strtok_r(NULL, " ", &saveptr); 4550 if (pid && temp && 4551 strncmp(temp, proc_name, strlen(proc_name)) == 0) { 4552 sigma_dut_print(dut, DUT_MSG_INFO, 4553 "killing %s process with PID %s", 4554 proc_name, pid); 4555 snprintf(buf, sizeof(buf), "kill -%d %d", sig, 4556 atoi(pid)); 4557 run_system(dut, buf); 4558 ret = 0; 4559 if (is_proc_instance_one) 4560 break; 4561 } 4562 } 4563 4564 closedir(dir); 4565 4566 return ret; 4567 #else /* __linux__ */ 4568 return -1; 4569 #endif /* __linux__ */ 4570 } 4571 4572 4573 static int run_ndc(struct sigma_dut *dut, char *buf) 4574 { 4575 sigma_dut_print(dut, DUT_MSG_INFO, "CMD NDC:: %s", buf); 4576 sleep(2); 4577 return run_system(dut, buf); 4578 } 4579 4580 4581 static int sigma_write_cfg(struct sigma_dut *dut, const char *pfile, 4582 const char *field, const char *value) 4583 { 4584 FILE *fcfg, *ftmp; 4585 char buf[MAX_CONF_LINE_LEN + 1]; 4586 int len, found = 0, res; 4587 4588 /* Open the configuration file */ 4589 fcfg = fopen(pfile, "r"); 4590 if (!fcfg) { 4591 sigma_dut_print(dut, DUT_MSG_ERROR, 4592 "Failed to open hostapd conf file"); 4593 return -1; 4594 } 4595 4596 snprintf(buf, sizeof(buf), "%s~", pfile); 4597 /* Open a temporary file */ 4598 ftmp = fopen(buf, "w+"); 4599 if (!ftmp) { 4600 fclose(fcfg); 4601 sigma_dut_print(dut, DUT_MSG_ERROR, 4602 "Failed to open temp buf"); 4603 return -1; 4604 } 4605 4606 /* Read the values from the configuration file */ 4607 len = strlen(field); 4608 while (fgets(buf, MAX_CONF_LINE_LEN, fcfg)) { 4609 char *pline = buf; 4610 4611 /* commented line */ 4612 if (buf[0] == '#') 4613 pline++; 4614 4615 /* Identify the configuration parameter to be updated */ 4616 if (!found && strncmp(pline, field, len) == 0 && 4617 pline[len] == '=') { 4618 snprintf(buf, sizeof(buf), "%s=%s\n", field, value); 4619 found = 1; 4620 sigma_dut_print(dut, DUT_MSG_INFO, 4621 "Updated hostapd conf file"); 4622 } 4623 4624 fprintf(ftmp, "%s", buf); 4625 } 4626 4627 if (!found) { 4628 /* Configuration line not found */ 4629 /* Add the new line at the end of file */ 4630 fprintf(ftmp, "%s=%s\n", field, value); 4631 sigma_dut_print(dut, DUT_MSG_INFO, 4632 "Adding a new line in hostapd conf file"); 4633 } 4634 4635 fclose(fcfg); 4636 fclose(ftmp); 4637 4638 snprintf(buf, sizeof(buf), "%s~", pfile); 4639 4640 /* Restore the updated configuration file */ 4641 res = rename(buf, pfile); 4642 4643 /* Remove the temporary file. Ignore the return value */ 4644 unlink(buf); 4645 4646 /* chmod is needed because open() may not set permissions properly 4647 * depending on the current umask */ 4648 if (chmod(pfile, 0660) < 0) { 4649 unlink(pfile); 4650 sigma_dut_print(dut, DUT_MSG_ERROR, 4651 "Error changing permissions"); 4652 return -1; 4653 } 4654 4655 if (res < 0) { 4656 sigma_dut_print(dut, DUT_MSG_ERROR, 4657 "Error restoring conf file"); 4658 return -1; 4659 } 4660 4661 return 0; 4662 } 4663 4664 4665 static int cmd_wcn_ap_config_commit(struct sigma_dut *dut, 4666 struct sigma_conn *conn, 4667 struct sigma_cmd *cmd) 4668 { 4669 char buf[100]; 4670 struct stat s; 4671 int num_tries = 0, ret; 4672 4673 if (kill_process(dut, "(netd)", 1, SIGKILL) == 0 || 4674 system("killall netd") == 0) { 4675 /* Avoid Error: Error connecting (Connection refused) 4676 * Wait some time to allow netd to reinitialize. 4677 */ 4678 usleep(1500000); 4679 } 4680 4681 while (num_tries < 10) { 4682 ret = run_ndc(dut, "ndc softap stopap"); 4683 num_tries++; 4684 if (WIFEXITED(ret)) 4685 ret = WEXITSTATUS(ret); 4686 /* On success, NDC exits with 0 */ 4687 if (ret == 0) 4688 break; 4689 sigma_dut_print(dut, DUT_MSG_INFO, 4690 "Try No. %d: ndc softap stopap failed, exit code %d", 4691 num_tries, ret); 4692 } 4693 4694 if (ret != 0) 4695 sigma_dut_print(dut, DUT_MSG_ERROR, 4696 "ndc softap stopap command failed for 10 times - giving up"); 4697 4698 #ifdef ANDROID 4699 /* Unload/Load driver to cleanup the state of the driver */ 4700 system("rmmod -f wlan"); 4701 usleep(500000); 4702 system("insmod /system/lib/modules/wlan.ko"); 4703 #else /* ANDROID */ 4704 run_ndc(dut, "ndc softap qccmd set enable_softap=0"); 4705 run_ndc(dut, "ndc softap qccmd set enable_softap=1"); 4706 #endif /* ANDROID */ 4707 4708 switch (dut->ap_mode) { 4709 case AP_11g: 4710 run_ndc(dut, "ndc softap qccmd set hw_mode=g-only"); 4711 break; 4712 case AP_11b: 4713 run_ndc(dut, "ndc softap qccmd set hw_mode=b-only"); 4714 break; 4715 case AP_11ng: 4716 run_ndc(dut, "ndc softap qccmd set hw_mode=n"); 4717 break; 4718 case AP_11a: 4719 run_ndc(dut, "ndc softap qccmd set hw_mode=a-only"); 4720 break; 4721 case AP_11na: 4722 run_ndc(dut, "ndc softap qccmd set hw_mode=n"); 4723 break; 4724 case AP_11ac: 4725 run_ndc(dut, "ndc softap qccmd set hw_mode=ac"); 4726 break; 4727 default: 4728 break; 4729 } 4730 4731 snprintf(buf, sizeof(buf), "ndc softap qccmd set channel=%d", 4732 dut->ap_channel); 4733 run_ndc(dut, buf); 4734 4735 /* 4736 * ndc doesn't support double quotes as SSID string, so re-write 4737 * hostapd configuration file to update SSID. 4738 */ 4739 if (dut->ap_ssid[0] != '\0') 4740 sigma_write_cfg(dut, ANDROID_CONFIG_FILE, "ssid", dut->ap_ssid); 4741 4742 switch (dut->ap_key_mgmt) { 4743 case AP_OPEN: 4744 if (dut->ap_cipher == AP_WEP) { 4745 run_ndc(dut, "ndc softap qccmd set security_mode=1"); 4746 snprintf(buf, sizeof(buf), 4747 "ndc softap qccmd set wep_key0=%s", 4748 dut->ap_wepkey); 4749 run_ndc(dut, buf); 4750 } else { 4751 run_ndc(dut, "ndc softap qccmd set security_mode=0"); 4752 } 4753 break; 4754 case AP_WPA2_PSK: 4755 case AP_WPA2_PSK_MIXED: 4756 case AP_WPA_PSK: 4757 if (dut->ap_key_mgmt == AP_WPA2_PSK) 4758 run_ndc(dut, "ndc softap qccmd set security_mode=3"); 4759 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) 4760 run_ndc(dut, "ndc softap qccmd set security_mode=4"); 4761 else 4762 run_ndc(dut, "ndc softap qccmd set security_mode=2"); 4763 4764 /* 4765 * ndc doesn't support some special characters as passphrase, 4766 * so re-write hostapd configuration file to update Passphrase. 4767 */ 4768 if (dut->ap_passphrase[0] != '\0') 4769 sigma_write_cfg(dut, ANDROID_CONFIG_FILE, 4770 "wpa_passphrase", dut->ap_passphrase); 4771 4772 if (dut->ap_cipher == AP_CCMP_TKIP) 4773 run_ndc(dut, "ndc softap qccmd set wpa_pairwise=" 4774 "TKIP CCMP"); 4775 else if (dut->ap_cipher == AP_TKIP) 4776 run_ndc(dut, "ndc softap qccmd set wpa_pairwise=" 4777 "TKIP"); 4778 else 4779 run_ndc(dut, "ndc softap qccmd set wpa_pairwise=" 4780 "CCMP &"); 4781 break; 4782 case AP_WPA2_SAE: 4783 case AP_WPA2_PSK_SAE: 4784 case AP_WPA2_EAP: 4785 case AP_WPA2_EAP_MIXED: 4786 case AP_WPA_EAP: 4787 case AP_SUITEB: 4788 case AP_WPA2_OWE: 4789 case AP_WPA2_EAP_OSEN: 4790 case AP_OSEN: 4791 case AP_WPA2_FT_EAP: 4792 case AP_WPA2_FT_PSK: 4793 case AP_WPA2_EAP_SHA256: 4794 case AP_WPA2_PSK_SHA256: 4795 case AP_WPA2_ENT_FT_EAP: 4796 /* Not supported */ 4797 break; 4798 } 4799 4800 switch (dut->ap_pmf) { 4801 case AP_PMF_DISABLED: 4802 run_ndc(dut, "ndc softap qccmd set ieee80211w=0"); 4803 break; 4804 case AP_PMF_OPTIONAL: 4805 run_ndc(dut, "ndc softap qccmd set ieee80211w=1"); 4806 if (dut->ap_add_sha256) 4807 run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256"); 4808 else 4809 run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK"); 4810 break; 4811 case AP_PMF_REQUIRED: 4812 run_ndc(dut, "ndc softap qccmd set ieee80211w=2"); 4813 run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK-SHA256"); 4814 break; 4815 } 4816 4817 if (dut->ap_countrycode[0]) { 4818 snprintf(buf, sizeof(buf), 4819 "ndc softap qccmd set country_code=%s", 4820 dut->ap_countrycode); 4821 run_ndc(dut, buf); 4822 } 4823 4824 if (dut->ap_regulatory_mode == AP_80211D_MODE_ENABLED) 4825 run_ndc(dut, "ndc softap qccmd set ieee80211d=1"); 4826 4827 if (dut->ap_dfs_mode == AP_DFS_MODE_ENABLED) 4828 run_ndc(dut, "ndc softap qccmd set ieee80211h=1"); 4829 4830 run_ndc(dut, "ndc softap startap"); 4831 4832 snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl, 4833 get_main_ifname(dut)); 4834 num_tries = 0; 4835 while (num_tries < 10 && (ret = stat(buf, &s) != 0)) { 4836 run_ndc(dut, "ndc softap stopap"); 4837 run_ndc(dut, "ndc softap startap"); 4838 num_tries++; 4839 } 4840 4841 if (num_tries == 10) { 4842 sigma_dut_print(dut, DUT_MSG_INFO, "Tried 10 times with ctrl " 4843 "iface %s :: reboot the APDUT", buf); 4844 return ret; 4845 } 4846 4847 sigma_dut_print(dut, DUT_MSG_INFO, "setting ip addr %s mask %s", 4848 ap_inet_addr, ap_inet_mask); 4849 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up", 4850 get_main_ifname(dut), ap_inet_addr, ap_inet_mask); 4851 if (system(buf) != 0) { 4852 sigma_dut_print(dut, DUT_MSG_ERROR, 4853 "Failed to intialize the interface"); 4854 return -1; 4855 } 4856 4857 return 1; 4858 } 4859 4860 4861 static int append_hostapd_conf_hs2(struct sigma_dut *dut, FILE *f) 4862 { 4863 fprintf(f, "hs20=1\nhs20_deauth_req_timeout=3\n" 4864 "disable_dgaf=%d\n", dut->ap_dgaf_disable); 4865 4866 if (dut->ap_oper_name) { 4867 fprintf(f, "hs20_oper_friendly_name=eng:Wi-Fi Alliance\n"); 4868 fprintf(f, "hs20_oper_friendly_name=chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f\n"); 4869 } 4870 4871 if (dut->ap_wan_metrics == 1) 4872 fprintf(f, "hs20_wan_metrics=01:2500:384:0:0:10\n"); 4873 else if (dut->ap_wan_metrics == 2) 4874 fprintf(f, "hs20_wan_metrics=01:1500:384:20:20:10\n"); 4875 else if (dut->ap_wan_metrics == 3) 4876 fprintf(f, "hs20_wan_metrics=01:2000:1000:20:20:10\n"); 4877 else if (dut->ap_wan_metrics == 4) 4878 fprintf(f, "hs20_wan_metrics=01:8000:1000:20:20:10\n"); 4879 else if (dut->ap_wan_metrics == 5) 4880 fprintf(f, "hs20_wan_metrics=01:9000:5000:20:20:10\n"); 4881 4882 if (dut->ap_conn_capab == 1) { 4883 fprintf(f, "hs20_conn_capab=1:0:0\n"); 4884 fprintf(f, "hs20_conn_capab=6:20:1\n"); 4885 fprintf(f, "hs20_conn_capab=6:22:0\n"); 4886 fprintf(f, "hs20_conn_capab=6:80:1\n"); 4887 fprintf(f, "hs20_conn_capab=6:443:1\n"); 4888 fprintf(f, "hs20_conn_capab=6:1723:0\n"); 4889 fprintf(f, "hs20_conn_capab=6:5060:0\n"); 4890 fprintf(f, "hs20_conn_capab=17:500:1\n"); 4891 fprintf(f, "hs20_conn_capab=17:5060:0\n"); 4892 fprintf(f, "hs20_conn_capab=17:4500:1\n"); 4893 fprintf(f, "hs20_conn_capab=50:0:1\n"); 4894 } else if (dut->ap_conn_capab == 2) { 4895 fprintf(f, "hs20_conn_capab=6:80:1\n"); 4896 fprintf(f, "hs20_conn_capab=6:443:1\n"); 4897 fprintf(f, "hs20_conn_capab=17:5060:1\n"); 4898 fprintf(f, "hs20_conn_capab=6:5060:1\n"); 4899 } else if (dut->ap_conn_capab == 3) { 4900 fprintf(f, "hs20_conn_capab=6:80:1\n"); 4901 fprintf(f, "hs20_conn_capab=6:443:1\n"); 4902 } else if (dut->ap_conn_capab == 4) { 4903 fprintf(f, "hs20_conn_capab=6:80:1\n"); 4904 fprintf(f, "hs20_conn_capab=6:443:1\n"); 4905 fprintf(f, "hs20_conn_capab=6:5060:1\n"); 4906 fprintf(f, "hs20_conn_capab=17:5060:1\n"); 4907 } 4908 4909 if (dut->ap_oper_class == 1) 4910 fprintf(f, "hs20_operating_class=51\n"); 4911 else if (dut->ap_oper_class == 2) 4912 fprintf(f, "hs20_operating_class=73\n"); 4913 else if (dut->ap_oper_class == 3) 4914 fprintf(f, "hs20_operating_class=5173\n"); 4915 4916 if (dut->ap_osu_provider_list) { 4917 char *osu_friendly_name = NULL; 4918 char *osu_icon = NULL; 4919 char *osu_ssid = NULL; 4920 char *osu_nai = NULL; 4921 char *osu_nai2 = NULL; 4922 char *osu_service_desc = NULL; 4923 char *hs20_icon_filename = NULL; 4924 char hs20_icon[150]; 4925 int osu_method; 4926 4927 hs20_icon_filename = "icon_red_zxx.png"; 4928 if (dut->ap_osu_icon_tag == 2) 4929 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 4930 snprintf(hs20_icon, sizeof(hs20_icon), 4931 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s", 4932 hs20_icon_filename); 4933 osu_icon = "icon_red_zxx.png"; 4934 osu_ssid = "OSU"; 4935 osu_friendly_name = "kor:SP 빨강 테스트 전용"; 4936 osu_service_desc = "kor:테스트 목적으로 무료 서비스"; 4937 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0]; 4938 4939 if (strlen(dut->ap_osu_server_uri[0])) 4940 fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[0]); 4941 else 4942 fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n"); 4943 4944 switch (dut->ap_osu_provider_list) { 4945 case 1: 4946 case 101: 4947 fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n"); 4948 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 4949 hs20_icon_filename = "icon_red_eng.png"; 4950 if (dut->ap_osu_icon_tag == 2) 4951 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 4952 fprintf(f, "hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s\n", 4953 hs20_icon_filename); 4954 fprintf(f, "osu_icon=icon_red_eng.png\n"); 4955 break; 4956 case 2: 4957 case 102: 4958 fprintf(f, "osu_friendly_name=eng:Wireless Broadband Alliance\n"); 4959 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 4960 hs20_icon_filename = "icon_orange_zxx.png"; 4961 if (dut->ap_osu_icon_tag == 2) 4962 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 4963 snprintf(hs20_icon, sizeof(hs20_icon), 4964 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s", 4965 hs20_icon_filename); 4966 osu_icon = "icon_orange_zxx.png"; 4967 osu_friendly_name = "kor:와이어리스 브로드밴드 얼라이언스"; 4968 break; 4969 case 3: 4970 case 103: 4971 osu_friendly_name = "spa:SP Red Test Only"; 4972 osu_service_desc = "spa:Free service for test purpose"; 4973 break; 4974 case 4: 4975 case 104: 4976 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n"); 4977 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 4978 hs20_icon_filename = "icon_orange_eng.png"; 4979 if (dut->ap_osu_icon_tag == 2) 4980 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 4981 fprintf(f, "hs20_icon=160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s\n", 4982 hs20_icon_filename); 4983 fprintf(f, "osu_icon=icon_orange_eng.png\n"); 4984 osu_friendly_name = "kor:SP 오렌지 테스트 전용"; 4985 4986 hs20_icon_filename = "icon_orange_zxx.png"; 4987 if (dut->ap_osu_icon_tag == 2) 4988 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 4989 snprintf(hs20_icon, sizeof(hs20_icon), 4990 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s", 4991 hs20_icon_filename); 4992 osu_icon = "icon_orange_zxx.png"; 4993 break; 4994 case 5: 4995 case 105: 4996 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n"); 4997 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 4998 osu_friendly_name = "kor:SP 오렌지 테스트 전용"; 4999 hs20_icon_filename = "icon_orange_zxx.png"; 5000 if (dut->ap_osu_icon_tag == 2) 5001 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5002 snprintf(hs20_icon, sizeof(hs20_icon), 5003 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s", 5004 hs20_icon_filename); 5005 osu_icon = "icon_orange_zxx.png"; 5006 break; 5007 case 6: 5008 case 106: 5009 fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n"); 5010 fprintf(f, "osu_friendly_name=kor:SP 초록 테스트 전용\n"); 5011 hs20_icon_filename = "icon_green_zxx.png"; 5012 if (dut->ap_osu_icon_tag == 2) 5013 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5014 fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s\n", 5015 hs20_icon_filename); 5016 fprintf(f, "osu_icon=icon_green_zxx.png\n"); 5017 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 : dut->ap_osu_method[0]; 5018 fprintf(f, "osu_method_list=%d\n", osu_method); 5019 5020 if (strlen(dut->ap_osu_server_uri[1])) 5021 fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]); 5022 else 5023 fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n"); 5024 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n"); 5025 hs20_icon_filename = "icon_orange_zxx.png"; 5026 if (dut->ap_osu_icon_tag == 2) 5027 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5028 snprintf(hs20_icon, sizeof(hs20_icon), 5029 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s", 5030 hs20_icon_filename); 5031 osu_icon = "icon_orange_zxx.png"; 5032 osu_friendly_name = "kor:SP 오렌지 테스트 전용"; 5033 osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 : dut->ap_osu_method[1]; 5034 osu_service_desc = NULL; 5035 break; 5036 case 7: 5037 case 107: 5038 fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n"); 5039 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 5040 hs20_icon_filename = "icon_green_eng.png"; 5041 if (dut->ap_osu_icon_tag == 2) 5042 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5043 fprintf(f, "hs20_icon=160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s\n", 5044 hs20_icon_filename); 5045 fprintf(f, "osu_icon=icon_green_eng.png\n"); 5046 osu_friendly_name = "kor:SP 초록 테스트 전용"; 5047 5048 hs20_icon_filename = "icon_green_zxx.png"; 5049 if (dut->ap_osu_icon_tag == 2) 5050 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5051 snprintf(hs20_icon, sizeof(hs20_icon), 5052 "128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s", 5053 hs20_icon_filename); 5054 osu_icon = "icon_green_zxx.png"; 5055 break; 5056 case 8: 5057 case 108: 5058 fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n"); 5059 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 5060 osu_ssid = "OSU-Encrypted"; 5061 osu_nai = "anonymous@hotspot.net"; 5062 break; 5063 case 9: 5064 case 109: 5065 osu_ssid = "OSU-OSEN"; 5066 osu_nai = "test-anonymous@wi-fi.org"; 5067 osu_friendly_name = "eng:SP Orange Test Only"; 5068 hs20_icon_filename = "icon_orange_zxx.png"; 5069 if (dut->ap_osu_icon_tag == 2) 5070 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5071 snprintf(hs20_icon, sizeof(hs20_icon), 5072 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s", 5073 hs20_icon_filename); 5074 osu_icon = "icon_orange_zxx.png"; 5075 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0]; 5076 osu_service_desc = NULL; 5077 break; 5078 case 10: 5079 case 110: 5080 /* OSU Provider #1 */ 5081 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n"); 5082 fprintf(f, "osu_friendly_name=kor:SP 오렌지 테스트 전용\n"); 5083 fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/icon_orange_zxx.png\n"); 5084 fprintf(f, "osu_icon=icon_orange_zxx.png\n"); 5085 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 5086 1 : dut->ap_osu_method[0]; 5087 fprintf(f, "osu_method_list=%d\n", osu_method); 5088 fprintf(f, "osu_nai=test-anonymous@wi-fi.org\n"); 5089 switch (dut->ap_osu_provider_nai_list) { 5090 case 3: 5091 fprintf(f, 5092 "osu_nai2=test-anonymous@wi-fi.org\n"); 5093 break; 5094 case 4: 5095 fprintf(f, "osu_nai2=random@hotspot.net\n"); 5096 break; 5097 } 5098 5099 /* OSU Provider #2 */ 5100 /* SP Red from defaults */ 5101 if (strlen(dut->ap_osu_server_uri[1])) 5102 fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]); 5103 else 5104 fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n"); 5105 fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n"); 5106 snprintf(hs20_icon, sizeof(hs20_icon), 5107 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/icon_red_zxx.png"); 5108 osu_method = (dut->ap_osu_method[1] == 0xFF) ? 5109 1 : dut->ap_osu_method[1]; 5110 osu_service_desc = NULL; 5111 osu_nai = "anonymous@hotspot.net"; 5112 break; 5113 default: 5114 break; 5115 } 5116 5117 switch (dut->ap_osu_provider_nai_list) { 5118 case 1: 5119 osu_nai2 = "anonymous@hotspot.net"; 5120 break; 5121 case 2: 5122 osu_nai2 = "test-anonymous@wi-fi.org"; 5123 break; 5124 case 3: 5125 /* OSU Provider NAI #1 written above */ 5126 /* OSU Provider NAI #2 */ 5127 osu_nai2 = "anonymous@hotspot.net"; 5128 break; 5129 case 4: 5130 /* OSU Provider NAI #1 written above */ 5131 /* OSU Provider NAI #2 */ 5132 osu_nai2 = "anonymous@hotspot.net"; 5133 break; 5134 } 5135 5136 if (strlen(dut->ap_osu_ssid)) { 5137 if (dut->ap_tag_ssid[0][0] && 5138 strcmp(dut->ap_tag_ssid[0], dut->ap_osu_ssid) && 5139 strcmp(dut->ap_tag_ssid[0], osu_ssid)) { 5140 sigma_dut_print(dut, DUT_MSG_ERROR, 5141 "OSU_SSID and " 5142 "WLAN_TAG2 SSID differ"); 5143 return -2; 5144 } 5145 fprintf(f, "osu_ssid=\"%s\"\n", dut->ap_osu_ssid); 5146 } else 5147 fprintf(f, "osu_ssid=\"%s\"\n", osu_ssid); 5148 5149 5150 if (osu_friendly_name) 5151 fprintf(f, "osu_friendly_name=%s\n", osu_friendly_name); 5152 5153 if (osu_service_desc) 5154 fprintf(f, "osu_service_desc=%s\n", osu_service_desc); 5155 5156 if (osu_nai) 5157 fprintf(f, "osu_nai=%s\n", osu_nai); 5158 if (osu_nai2) 5159 fprintf(f, "osu_nai2=%s\n", osu_nai2); 5160 5161 fprintf(f, "hs20_icon=%s\n", hs20_icon); 5162 5163 if (osu_icon) 5164 fprintf(f, "osu_icon=%s\n", osu_icon); 5165 5166 if (dut->ap_osu_provider_list > 100) 5167 fprintf(f, "osu_method_list=0\n"); 5168 else 5169 fprintf(f, "osu_method_list=%d\n", osu_method); 5170 } 5171 5172 switch (dut->ap_venue_url) { 5173 case 1: 5174 fprintf(f, 5175 "venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5176 "venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/directory/index.html\n"); 5177 break; 5178 case 2: 5179 fprintf(f, 5180 "venue_url=1:https://the-great-mall.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5181 "venue_url=2:https://abercrombie.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5182 "venue_url=3:https://adidas.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5183 "venue_url=4:https://aeropostale.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5184 "venue_url=5:https://agaci.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5185 "venue_url=6:https://aldo-shoes.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5186 "venue_url=7:https://american-eagle-outfitters.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5187 "venue_url=8:https://anderson-bakery.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5188 "venue_url=9:https://banana-republic-factory-store.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5189 "venue_url=10:https://bed-bath-and-beyond.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5190 ); 5191 break; 5192 } 5193 5194 switch (dut->ap_advice_of_charge) { 5195 case 1: 5196 fprintf(f, "anqp_elem=278:" ADV_OF_CHARGE_1 "\n"); 5197 break; 5198 } 5199 5200 switch (dut->ap_oper_icon_metadata) { 5201 case 1: 5202 fprintf(f, 5203 "hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/icon_red_eng.png\n" 5204 "operator_icon=icon_red_eng.png\n"); 5205 break; 5206 } 5207 5208 switch (dut->ap_tnc_file_name) { 5209 case 1: 5210 fprintf(f, "hs20_t_c_filename=tandc-id1-content.txt\n"); 5211 break; 5212 } 5213 5214 if (dut->ap_tnc_time_stamp) 5215 fprintf(f, "hs20_t_c_timestamp=%u\n", dut->ap_tnc_time_stamp); 5216 5217 return 0; 5218 } 5219 5220 5221 static void write_ap_roaming_cons(FILE *f, const char *list) 5222 { 5223 char *buf, *pos, *end; 5224 5225 if (list == NULL || list[0] == '\0') 5226 return; 5227 5228 buf = strdup(list); 5229 if (buf == NULL) 5230 return; 5231 5232 pos = buf; 5233 while (pos && *pos) { 5234 end = strchr(pos, ';'); 5235 if (end) 5236 *end++ = '\0'; 5237 fprintf(f, "roaming_consortium=%s\n", pos); 5238 pos = end; 5239 } 5240 5241 free(buf); 5242 } 5243 5244 5245 static int append_hostapd_conf_interworking(struct sigma_dut *dut, FILE *f) 5246 { 5247 int i; 5248 char buf[100], *temp; 5249 5250 if (dut->ap_gas_cb_delay > 0) 5251 fprintf(f, "gas_comeback_delay=%d\n", 5252 dut->ap_gas_cb_delay); 5253 5254 fprintf(f, "interworking=1\n" 5255 "access_network_type=%d\n" 5256 "internet=%d\n" 5257 "asra=0\n" 5258 "esr=0\n" 5259 "uesa=0\n" 5260 "venue_group=%d\n" 5261 "venue_type=%d\n", 5262 dut->ap_access_net_type, 5263 dut->ap_internet, 5264 dut->ap_venue_group, 5265 dut->ap_venue_type); 5266 if (dut->ap_hessid[0]) 5267 fprintf(f, "hessid=%s\n", dut->ap_hessid); 5268 5269 write_ap_roaming_cons(f, dut->ap_roaming_cons); 5270 5271 if (dut->ap_venue_name) { 5272 fprintf(f, "venue_name=P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"\n"); 5273 fprintf(f, "venue_name=%s\n", ANQP_VENUE_NAME_1_CHI); 5274 } 5275 5276 if (dut->ap_net_auth_type == 1) 5277 fprintf(f, "network_auth_type=00https://tandc-server.wi-fi.org\n"); 5278 else if (dut->ap_net_auth_type == 2) 5279 fprintf(f, "network_auth_type=01\n"); 5280 5281 if (dut->ap_nai_realm_list == 1) { 5282 fprintf(f, "nai_realm=0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]\n"); 5283 fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n"); 5284 } else if (dut->ap_nai_realm_list == 2) { 5285 fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n"); 5286 } else if (dut->ap_nai_realm_list == 3) { 5287 fprintf(f, "nai_realm=0,cisco.com;wi-fi.org,21[2:4][5:7]\n"); 5288 fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n"); 5289 } else if (dut->ap_nai_realm_list == 4) { 5290 fprintf(f, "nai_realm=0,mail.example.com,21[2:4][5:7],13[5:6]\n"); 5291 } else if (dut->ap_nai_realm_list == 5) { 5292 fprintf(f, "nai_realm=0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]\n"); 5293 } else if (dut->ap_nai_realm_list == 6) { 5294 fprintf(f, "nai_realm=0,wi-fi.org;mail.example.com,21[2:4][5:7]\n"); 5295 } else if (dut->ap_nai_realm_list == 7) { 5296 fprintf(f, "nai_realm=0,wi-fi.org,13[5:6]\n"); 5297 fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n"); 5298 } 5299 5300 if (dut->ap_domain_name_list[0]) { 5301 fprintf(f, "domain_name=%s\n", 5302 dut->ap_domain_name_list); 5303 } 5304 5305 if (dut->ap_ip_addr_type_avail == 1) { 5306 fprintf(f, "ipaddr_type_availability=0c\n"); 5307 } 5308 5309 temp = buf; 5310 for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; 5311 i++) { 5312 if (i) 5313 *temp++ = ';'; 5314 5315 snprintf(temp, 5316 sizeof(dut->ap_plmn_mcc[i]) + 5317 sizeof(dut->ap_plmn_mnc[i]) + 1, 5318 "%s,%s", 5319 dut->ap_plmn_mcc[i], 5320 dut->ap_plmn_mnc[i]); 5321 5322 temp += strlen(dut->ap_plmn_mcc[i]) + 5323 strlen(dut->ap_plmn_mnc[i]) + 1; 5324 } 5325 if (i) 5326 fprintf(f, "anqp_3gpp_cell_net=%s\n", buf); 5327 5328 if (dut->ap_qos_map_set == 1) 5329 fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_1); 5330 else if (dut->ap_qos_map_set == 2) 5331 fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_2); 5332 5333 return 0; 5334 } 5335 5336 5337 static int ath_ap_append_hostapd_conf(struct sigma_dut *dut) 5338 { 5339 FILE *f; 5340 5341 if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 || 5342 system("killall hostapd") == 0) { 5343 int i; 5344 5345 /* Wait some time to allow hostapd to complete cleanup before 5346 * starting a new process */ 5347 for (i = 0; i < 10; i++) { 5348 usleep(500000); 5349 if (system("pidof hostapd") != 0) 5350 break; 5351 } 5352 } 5353 5354 f = fopen("/tmp/secath0", "a"); 5355 if (f == NULL) 5356 return -2; 5357 5358 if (dut->ap_hs2 && append_hostapd_conf_hs2(dut, f)) { 5359 fclose(f); 5360 return -2; 5361 } 5362 5363 if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) { 5364 fclose(f); 5365 return -2; 5366 } 5367 5368 fflush(f); 5369 fclose(f); 5370 return ath_ap_start_hostapd(dut); 5371 } 5372 5373 5374 static int ath_ap_start_hostapd(struct sigma_dut *dut) 5375 { 5376 if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) 5377 run_system(dut, "hostapd -B /tmp/secath0 /tmp/secath1 -e /etc/wpa2/entropy"); 5378 else 5379 run_system(dut, "hostapd -B /tmp/secath0 -e /etc/wpa2/entropy"); 5380 5381 return 0; 5382 } 5383 5384 5385 #define LE16(a) ((((a) & 0xff) << 8) | (((a) >> 8) & 0xff)) 5386 5387 static int cmd_ath_ap_anqpserver_start(struct sigma_dut *dut) 5388 { 5389 FILE *f; 5390 int nai_realm = 0, domain_name = 0, oper_name = 0, venue_name = 0, 5391 wan_metrics = 0, conn_cap = 0, ipaddr_avail = 0, cell_net = 0; 5392 char buf[100]; 5393 int i; 5394 5395 f = fopen("/root/anqpserver.conf", "w"); 5396 if (f == NULL) 5397 return -1; 5398 5399 if (dut->ap_nai_realm_list == 1) { 5400 nai_realm = 1; 5401 fprintf(f, "dyn_nai_home_realm=encoding=00realm=mail.example.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=cisco.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=wi-fi.org;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=example.com;eap_method=0Dauth_id=05auth_val=06encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n"); 5402 } else if (dut->ap_nai_realm_list == 2) { 5403 nai_realm = 1; 5404 fprintf(f, "dyn_nai_home_realm=encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n"); 5405 } else if (dut->ap_nai_realm_list == 3) { 5406 nai_realm = 1; 5407 fprintf(f, "dyn_nai_home_realm=encoding=00realm=cisco.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=wi-fi.org;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=example.com;eap_method=0Dauth_id=05auth_val=06encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n"); 5408 } else if (dut->ap_nai_realm_list == 4) { 5409 nai_realm = 1; 5410 fprintf(f, "dyn_nai_home_realm=encoding=00realm=mail.example.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=mail.example.com;eap_method=0Dauth_id=05auth_val=06\n"); 5411 } else 5412 sigma_dut_print(dut, DUT_MSG_INFO, "not setting nai_realm"); 5413 5414 if (dut->ap_domain_name_list[0]) { 5415 char *next, *start, *dnbuf, *dn1, *anqp_dn; 5416 int len, dn_len_max; 5417 dnbuf = strdup(dut->ap_domain_name_list); 5418 if (dnbuf == NULL) { 5419 fclose(f); 5420 return 0; 5421 } 5422 5423 len = strlen(dnbuf); 5424 dn_len_max = 50 + len*2; 5425 anqp_dn = malloc(dn_len_max); 5426 if (anqp_dn == NULL) { 5427 free(dnbuf); 5428 fclose(f); 5429 return -1; 5430 } 5431 start = dnbuf; 5432 dn1 = anqp_dn; 5433 while (start && *start) { 5434 char *hexstr; 5435 5436 next = strchr(start, ','); 5437 if (next) 5438 *next++ = '\0'; 5439 5440 len = strlen(start); 5441 hexstr = malloc(len * 2 + 1); 5442 if (hexstr == NULL) { 5443 free(dnbuf); 5444 free(anqp_dn); 5445 fclose(f); 5446 return -1; 5447 } 5448 ascii2hexstr(start, hexstr); 5449 snprintf(dn1, dn_len_max, "%02x%s", len, hexstr); 5450 free(hexstr); 5451 dn1 += 2 + len * 2; 5452 dn_len_max -= 2 + len * 2; 5453 start = next; 5454 } 5455 free(dnbuf); 5456 if (dut->ap_gas_cb_delay) { 5457 fprintf(f, "dyn_domain_name=0c01%04x%s", 5458 LE16((unsigned int) strlen(anqp_dn)), anqp_dn); 5459 domain_name = 1; 5460 } else 5461 fprintf(f, "domain_name=0c01%04x%s", 5462 LE16((unsigned int) strlen(anqp_dn)), anqp_dn); 5463 free(anqp_dn); 5464 } else 5465 sigma_dut_print(dut, DUT_MSG_INFO, "not setting domain_name"); 5466 5467 sigma_dut_print(dut, DUT_MSG_INFO, "not setting roaming_consortium"); 5468 5469 if (dut->ap_oper_name) { 5470 if (dut->ap_gas_cb_delay) { 5471 fprintf(f, "dyn_oper_friendly_name=" 5472 ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n"); 5473 oper_name = 1; 5474 } else 5475 fprintf(f, "oper_friendly_name=" 5476 ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n"); 5477 } else 5478 sigma_dut_print(dut, DUT_MSG_INFO, "not setting oper_name"); 5479 5480 if (dut->ap_venue_name) { 5481 if (dut->ap_gas_cb_delay) { 5482 fprintf(f, "dyn_venue_name=" ANQP_VENUE_NAME_1 "\n"); 5483 venue_name = 1; 5484 } else 5485 fprintf(f, "venue_name=" ANQP_VENUE_NAME_1 "\n"); 5486 } else 5487 sigma_dut_print(dut, DUT_MSG_ERROR, "not setting venue_name"); 5488 5489 if (dut->ap_wan_metrics) { 5490 if (dut->ap_gas_cb_delay) { 5491 fprintf(f, "dyn_wan_metrics=" ANQP_HS20_WAN_METRICS_1 "\n"); 5492 wan_metrics = 1; 5493 } else 5494 fprintf(f, "wan_metrics=" ANQP_HS20_WAN_METRICS_1 5495 "\n"); 5496 } else 5497 sigma_dut_print(dut, DUT_MSG_ERROR, "not setting wan_metrics"); 5498 5499 if (dut->ap_conn_capab) { 5500 if (dut->ap_gas_cb_delay) { 5501 fprintf(f, "dyn_conn_capability=" 5502 ANQP_HS20_CONNECTION_CAPABILITY_1 "\n"); 5503 conn_cap = 1; 5504 } else 5505 fprintf(f, "conn_capability=" 5506 ANQP_HS20_CONNECTION_CAPABILITY_1 "\n"); 5507 } else 5508 sigma_dut_print(dut, DUT_MSG_ERROR, 5509 "not setting conn_capability"); 5510 5511 if (dut->ap_ip_addr_type_avail) { 5512 if (dut->ap_gas_cb_delay) { 5513 fprintf(f, "dyn_ipaddr_type=" ANQP_IP_ADDR_TYPE_1 5514 "\n"); 5515 ipaddr_avail = 1; 5516 } else 5517 fprintf(f, "ipaddr_type=" ANQP_IP_ADDR_TYPE_1 "\n"); 5518 } else 5519 sigma_dut_print(dut, DUT_MSG_ERROR, 5520 "not setting ipaddr_type_avail"); 5521 5522 for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) { 5523 snprintf(buf + i * 6, sizeof(buf) - i * 6, "%c%c%c%c%c%c", 5524 dut->ap_plmn_mcc[i][1], 5525 dut->ap_plmn_mcc[i][0], 5526 dut->ap_plmn_mnc[i][2] == '\0' ? 5527 'f' : dut->ap_plmn_mnc[i][2], 5528 dut->ap_plmn_mcc[i][2], 5529 dut->ap_plmn_mnc[i][1], 5530 dut->ap_plmn_mnc[i][0]); 5531 } 5532 if (i) { 5533 uint16_t ie_len = (i * 3) + 5; 5534 if (dut->ap_gas_cb_delay) { 5535 fprintf(f, "dyn_cell_net=0801"); 5536 cell_net = 1; 5537 } else 5538 fprintf(f, "cell_net=0801"); 5539 fprintf(f, "%04x", LE16(ie_len)); 5540 fprintf(f, "00"); /* version */ 5541 fprintf(f, "%02x", (i * 3) + 3); /* user data hdr length */ 5542 fprintf(f, "00"); /* plmn list */ 5543 fprintf(f, "%02x", (i * 3) + 1); /* length of plmn list */ 5544 fprintf(f, "%02x", i); /* number of plmns */ 5545 fprintf(f, "%s\n", buf); /* plmns */ 5546 } else 5547 sigma_dut_print(dut, DUT_MSG_ERROR, 5548 "not setting 3gpp_cellular_network"); 5549 5550 if (nai_realm || domain_name || oper_name || venue_name || 5551 wan_metrics || conn_cap || ipaddr_avail || cell_net) { 5552 fprintf(f, "anqp_attach="); 5553 if (venue_name) 5554 fprintf(f, "00000104%4.4x", dut->ap_gas_cb_delay); 5555 if (nai_realm) 5556 fprintf(f, "00000107%4.4x", dut->ap_gas_cb_delay); 5557 if (cell_net) 5558 fprintf(f, "00000108%4.4x", dut->ap_gas_cb_delay); 5559 if (domain_name) 5560 fprintf(f, "0000010c%4.4x", dut->ap_gas_cb_delay); 5561 if (oper_name) 5562 fprintf(f, "00010003%4.4x", dut->ap_gas_cb_delay); 5563 if (wan_metrics) 5564 fprintf(f, "00010004%4.4x", dut->ap_gas_cb_delay); 5565 if (conn_cap) 5566 fprintf(f, "00010005%4.4x", dut->ap_gas_cb_delay); 5567 fprintf(f, "00010006%4.4x", dut->ap_gas_cb_delay); 5568 fprintf(f, "\n"); 5569 } 5570 5571 fclose(f); 5572 5573 run_system(dut, "anqpserver -i ath0 &"); 5574 if (!dut->ap_anqpserver_on) 5575 run_system(dut, "killall anqpserver"); 5576 5577 return 1; 5578 } 5579 5580 5581 static void cmd_ath_ap_radio_config(struct sigma_dut *dut) 5582 { 5583 char buf[100]; 5584 5585 run_system(dut, "cfg -a AP_STARTMODE=standard"); 5586 5587 if (sigma_radio_ifname[0] && 5588 strcmp(sigma_radio_ifname[0], "wifi1") == 0) { 5589 run_system(dut, "cfg -a AP_RADIO_ID=1"); 5590 switch (dut->ap_mode) { 5591 case AP_11g: 5592 run_system(dut, "cfg -a AP_CHMODE_2=11G"); 5593 break; 5594 case AP_11b: 5595 run_system(dut, "cfg -a AP_CHMODE_2=11B"); 5596 break; 5597 case AP_11ng: 5598 run_system(dut, "cfg -a AP_CHMODE_2=11NGHT20"); 5599 break; 5600 case AP_11a: 5601 run_system(dut, "cfg -a AP_CHMODE_2=11A"); 5602 break; 5603 case AP_11na: 5604 run_system(dut, "cfg -a AP_CHMODE_2=11NAHT20"); 5605 break; 5606 case AP_11ac: 5607 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80"); 5608 break; 5609 default: 5610 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80"); 5611 break; 5612 } 5613 5614 switch (dut->ap_rx_streams) { 5615 case 1: 5616 run_system(dut, "cfg -a RX_CHAINMASK_2=1"); 5617 break; 5618 case 2: 5619 run_system(dut, "cfg -a RX_CHAINMASK_2=3"); 5620 break; 5621 case 3: 5622 run_system(dut, "cfg -a RX_CHAINMASK_2=7"); 5623 break; 5624 } 5625 5626 switch (dut->ap_tx_streams) { 5627 case 1: 5628 run_system(dut, "cfg -a TX_CHAINMASK_2=1"); 5629 break; 5630 case 2: 5631 run_system(dut, "cfg -a TX_CHAINMASK_2=3"); 5632 break; 5633 case 3: 5634 run_system(dut, "cfg -a TX_CHAINMASK_2=7"); 5635 break; 5636 } 5637 5638 switch (dut->ap_chwidth) { 5639 case AP_20: 5640 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT20"); 5641 break; 5642 case AP_40: 5643 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT40"); 5644 break; 5645 case AP_80: 5646 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80"); 5647 break; 5648 case AP_160: 5649 case AP_AUTO: 5650 default: 5651 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80"); 5652 break; 5653 } 5654 5655 if (dut->ap_tx_stbc) { 5656 run_system(dut, "cfg -a TX_STBC_2=1"); 5657 } 5658 5659 snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH_2=%d", 5660 dut->ap_channel); 5661 5662 if (dut->ap_is_dual) { 5663 switch (dut->ap_mode_1) { 5664 case AP_11g: 5665 run_system(dut, "cfg -a AP_CHMODE=11G"); 5666 break; 5667 case AP_11b: 5668 run_system(dut, "cfg -a AP_CHMODE=11B"); 5669 break; 5670 case AP_11ng: 5671 run_system(dut, "cfg -a AP_CHMODE=11NGHT20"); 5672 break; 5673 case AP_11a: 5674 run_system(dut, "cfg -a AP_CHMODE=11A"); 5675 break; 5676 case AP_11na: 5677 run_system(dut, "cfg -a AP_CHMODE=11NAHT20"); 5678 break; 5679 case AP_11ac: 5680 run_system(dut, "cfg -a AP_CHMODE=11ACVHT80"); 5681 break; 5682 default: 5683 run_system(dut, "cfg -a AP_CHMODE=11NGHT20"); 5684 break; 5685 } 5686 snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d", 5687 dut->ap_channel_1); 5688 } 5689 run_system(dut, buf); 5690 } else { 5691 run_system(dut, "cfg -a AP_RADIO_ID=0"); 5692 switch (dut->ap_mode) { 5693 case AP_11g: 5694 run_system(dut, "cfg -a AP_CHMODE=11G"); 5695 break; 5696 case AP_11b: 5697 run_system(dut, "cfg -a AP_CHMODE=11B"); 5698 break; 5699 case AP_11ng: 5700 run_system(dut, "cfg -a AP_CHMODE=11NGHT20"); 5701 break; 5702 case AP_11a: 5703 run_system(dut, "cfg -a AP_CHMODE=11A"); 5704 break; 5705 case AP_11na: 5706 run_system(dut, "cfg -a AP_CHMODE=11NAHT20"); 5707 break; 5708 case AP_11ac: 5709 run_system(dut, "cfg -a AP_CHMODE=11ACVHT80"); 5710 break; 5711 default: 5712 run_system(dut, "cfg -a AP_CHMODE=11NGHT20"); 5713 break; 5714 } 5715 snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d", 5716 dut->ap_channel); 5717 run_system(dut, buf); 5718 } 5719 5720 if (dut->ap_sgi80 == 1) { 5721 run_system(dut, "cfg -a SHORTGI=1"); 5722 run_system(dut, "cfg -a SHORTGI_2=1"); 5723 } else if (dut->ap_sgi80 == 0) { 5724 run_system(dut, "cfg -a SHORTGI=0"); 5725 run_system(dut, "cfg -a SHORTGI_2=0"); 5726 } 5727 5728 if (dut->ap_ldpc == VALUE_ENABLED) 5729 run_system(dut, "cfg -a LDPC=1"); 5730 else if (dut->ap_ldpc == VALUE_DISABLED) 5731 run_system(dut, "cfg -a LDPC=0"); 5732 } 5733 5734 5735 void ath_disable_txbf(struct sigma_dut *dut, const char *intf) 5736 { 5737 run_iwpriv(dut, intf, "vhtsubfee 0"); 5738 run_iwpriv(dut, intf, "vhtsubfer 0"); 5739 run_iwpriv(dut, intf, "vhtmubfee 0"); 5740 run_iwpriv(dut, intf, "vhtmubfer 0"); 5741 } 5742 5743 5744 static void ath_set_assoc_disallow(struct sigma_dut *dut, const char *ifname, 5745 const char *val) 5746 { 5747 if (strcasecmp(val, "enable") == 0) { 5748 run_iwpriv(dut, ifname, "mbo_asoc_dis 1"); 5749 } else if (strcasecmp(val, "disable") == 0) { 5750 run_iwpriv(dut, ifname, "mbo_asoc_dis 0"); 5751 } else { 5752 sigma_dut_print(dut, DUT_MSG_ERROR, 5753 "Unsupported assoc_disallow"); 5754 } 5755 } 5756 5757 5758 static void apply_mbo_pref_ap_list(struct sigma_dut *dut) 5759 { 5760 int i; 5761 int least_pref = 1 << 8; 5762 char ifname[20]; 5763 uint8_t self_mac[ETH_ALEN]; 5764 char buf[200]; 5765 int ap_ne_class, ap_ne_pref, ap_ne_op_ch; 5766 5767 get_if_name(dut, ifname, sizeof(ifname), 1); 5768 get_hwaddr(ifname, self_mac); 5769 5770 /* Clear off */ 5771 snprintf(buf, sizeof(buf), 5772 "wifitool %s setbssidpref 00:00:00:00:00:00 0 0 0", 5773 ifname); 5774 run_system(dut, buf); 5775 5776 /* Find the least preference number */ 5777 for (i = 0; i < dut->mbo_pref_ap_cnt; i++) { 5778 unsigned char *mac_addr = dut->mbo_pref_aps[i].mac_addr; 5779 5780 ap_ne_class = 1; 5781 ap_ne_pref = 255; 5782 ap_ne_op_ch = 1; 5783 if (dut->mbo_pref_aps[i].ap_ne_pref != -1) 5784 ap_ne_pref = dut->mbo_pref_aps[i].ap_ne_pref; 5785 if (dut->mbo_pref_aps[i].ap_ne_class != -1) 5786 ap_ne_class = dut->mbo_pref_aps[i].ap_ne_class; 5787 if (dut->mbo_pref_aps[i].ap_ne_op_ch != -1) 5788 ap_ne_op_ch = dut->mbo_pref_aps[i].ap_ne_op_ch; 5789 5790 if (ap_ne_pref < least_pref) 5791 least_pref = ap_ne_pref; 5792 snprintf(buf, sizeof(buf), 5793 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d", 5794 ifname, mac_addr[0], mac_addr[1], mac_addr[2], 5795 mac_addr[3], mac_addr[4], mac_addr[5], 5796 ap_ne_pref, ap_ne_class, ap_ne_op_ch); 5797 run_system(dut, buf); 5798 } 5799 5800 /* Now add the self AP Address */ 5801 if (dut->mbo_self_ap_tuple.ap_ne_class == -1) { 5802 if (dut->ap_channel <= 11) 5803 ap_ne_class = 81; 5804 else 5805 ap_ne_class = 115; 5806 } else { 5807 ap_ne_class = dut->mbo_self_ap_tuple.ap_ne_class; 5808 } 5809 5810 if (dut->mbo_self_ap_tuple.ap_ne_op_ch == -1) 5811 ap_ne_op_ch = dut->ap_channel; 5812 else 5813 ap_ne_op_ch = dut->mbo_self_ap_tuple.ap_ne_op_ch; 5814 5815 if (dut->mbo_self_ap_tuple.ap_ne_pref == -1) 5816 ap_ne_pref = least_pref - 1; 5817 else 5818 ap_ne_pref = dut->mbo_self_ap_tuple.ap_ne_pref; 5819 5820 snprintf(buf, sizeof(buf), 5821 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d", 5822 ifname, self_mac[0], self_mac[1], self_mac[2], 5823 self_mac[3], self_mac[4], self_mac[5], 5824 ap_ne_pref, 5825 ap_ne_class, 5826 ap_ne_op_ch); 5827 run_system(dut, buf); 5828 } 5829 5830 5831 static void mubrp_commands(struct sigma_dut *dut, const char *ifname) 5832 { 5833 run_iwpriv(dut, ifname, "he_subfer 1"); 5834 run_iwpriv(dut, ifname, "he_mubfer 1"); 5835 /* To enable MU_AX with MU_BRP trigger */ 5836 run_iwpriv(dut, ifname, "he_sounding_mode 13"); 5837 /* Sets g_force_1x1_peer to 1 which should be reset to zero for non MU 5838 * test cases */ 5839 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 118 1", 5840 ifname); 5841 /* Disable DL OFDMA */ 5842 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 11 0", 5843 ifname); 5844 } 5845 5846 5847 static void ath_ap_set_params(struct sigma_dut *dut) 5848 { 5849 const char *basedev = "wifi0"; 5850 const char *basedev_radio = "wifi1"; 5851 const char *ifname = get_main_ifname(dut); 5852 char *ifname_dual = NULL; 5853 int i; 5854 char buf[300]; 5855 unsigned int he_mcsnssmap = dut->he_mcsnssmap; 5856 5857 if (sigma_radio_ifname[0]) 5858 basedev = sigma_radio_ifname[0]; 5859 5860 if (dut->ap_is_dual == 1) { 5861 basedev = sigma_radio_ifname[0]; 5862 basedev_radio = sigma_radio_ifname[1]; 5863 if (sigma_radio_ifname[0] && 5864 strcmp(sigma_radio_ifname[0], "wifi0") == 0) { 5865 ifname = "ath0"; 5866 ifname_dual = "ath1"; 5867 } else { 5868 ifname = "ath1"; 5869 ifname_dual = "ath0"; 5870 } 5871 } 5872 5873 if (dut->ap_countrycode[0]) { 5874 run_iwpriv(dut, basedev, "setCountry %s", dut->ap_countrycode); 5875 sigma_dut_print(dut, DUT_MSG_INFO, "Set countrycode"); 5876 } 5877 5878 for (i = 0; i < NUM_AP_AC; i++) { 5879 if (dut->ap_qos[i].ac) { 5880 run_iwpriv(dut, ifname, "cwmin %d 0 %d", i, 5881 dut->ap_qos[i].cwmin); 5882 run_iwpriv(dut, ifname, "cwmax %d 0 %d", i, 5883 dut->ap_qos[i].cwmax); 5884 run_iwpriv(dut, ifname, "aifs %d 0 %d", i, 5885 dut->ap_qos[i].aifs); 5886 run_iwpriv(dut, ifname, "txoplimit %d 0 %d", i, 5887 dut->ap_qos[i].txop); 5888 run_iwpriv(dut, ifname, "acm %d 0 %d", i, 5889 dut->ap_qos[i].acm); 5890 } 5891 } 5892 5893 for (i = 0; i < NUM_AP_AC; i++) { 5894 if (dut->ap_sta_qos[i].ac) { 5895 run_iwpriv(dut, ifname, "cwmin %d 1 %d", i, 5896 dut->ap_sta_qos[i].cwmin); 5897 run_iwpriv(dut, ifname, "cwmax %d 1 %d", i, 5898 dut->ap_sta_qos[i].cwmax); 5899 run_iwpriv(dut, ifname, "aifs %d 1 %d", i, 5900 dut->ap_sta_qos[i].aifs); 5901 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", i, 5902 dut->ap_sta_qos[i].txop); 5903 run_iwpriv(dut, ifname, "acm %d 1 %d", i, 5904 dut->ap_sta_qos[i].acm); 5905 } 5906 } 5907 5908 if (dut->ap_disable_protection == 1) { 5909 run_iwpriv(dut, ifname, "enablertscts 0"); 5910 sigma_dut_print(dut, DUT_MSG_INFO, "Disabled rtscts"); 5911 } 5912 5913 if (dut->ap_ldpc == VALUE_ENABLED) 5914 run_iwpriv(dut, ifname, "ldpc 3"); 5915 else if (dut->ap_ldpc == VALUE_DISABLED) 5916 run_iwpriv(dut, ifname, "ldpc 0"); 5917 5918 if (dut->ap_ampdu == VALUE_ENABLED) { 5919 run_iwpriv(dut, ifname, "ampdu 1"); 5920 } else if (dut->ap_ampdu == VALUE_DISABLED) { 5921 run_iwpriv(dut, ifname, "ampdu 0"); 5922 if (dut->program == PROGRAM_HE) { 5923 run_iwpriv(dut, ifname, "setaddbaoper 1"); 5924 run_system_wrapper(dut, "wifitool %s refusealladdbas 1", 5925 ifname); 5926 if (dut->ap_amsdu == VALUE_ENABLED) { 5927 /* disable the limit for A-MSDU */ 5928 run_system_wrapper(dut, 5929 "wifitool %s setUnitTestCmd 0x48 2 46 1", 5930 ifname); 5931 } 5932 } 5933 } 5934 5935 if (dut->ap_ampdu_exp) { 5936 if (dut->program == PROGRAM_VHT) { 5937 run_iwpriv(dut, ifname, "vhtmaxampdu %d", 5938 dut->ap_ampdu_exp); 5939 } else { 5940 /* 11N */ 5941 run_iwpriv(dut, ifname, "maxampdu %d", 5942 dut->ap_ampdu_exp); 5943 } 5944 } 5945 5946 if (dut->ap_noack == VALUE_ENABLED) { 5947 run_iwpriv(dut, ifname, "noackpolicy 0 0 1"); 5948 run_iwpriv(dut, ifname, "noackpolicy 1 0 1"); 5949 run_iwpriv(dut, ifname, "noackpolicy 2 0 1"); 5950 run_iwpriv(dut, ifname, "noackpolicy 3 0 1"); 5951 } else if (dut->ap_noack == VALUE_DISABLED) { 5952 run_iwpriv(dut, ifname, "noackpolicy 0 0 0"); 5953 run_iwpriv(dut, ifname, "noackpolicy 1 0 0"); 5954 run_iwpriv(dut, ifname, "noackpolicy 2 0 0"); 5955 run_iwpriv(dut, ifname, "noackpolicy 3 0 0"); 5956 } 5957 5958 if (dut->device_type == AP_testbed && dut->ap_vhtmcs_map) 5959 run_iwpriv(dut, ifname, "vht_mcsmap 0x%04x", 5960 dut->ap_vhtmcs_map); 5961 5962 if (dut->ap_amsdu == VALUE_ENABLED) 5963 run_iwpriv(dut, ifname, "amsdu 2"); 5964 else if (dut->ap_amsdu == VALUE_DISABLED) 5965 run_iwpriv(dut, ifname, "amsdu 1"); 5966 5967 if (dut->ap_rx_amsdu == VALUE_ENABLED) 5968 run_iwpriv(dut, basedev_radio, "rx_amsdu 1"); 5969 else if (dut->ap_rx_amsdu == VALUE_DISABLED) 5970 run_iwpriv(dut, basedev_radio, "rx_amsdu 0"); 5971 5972 /* Command sequence to generate single VHT AMSDU and MPDU */ 5973 if (dut->ap_addba_reject != VALUE_NOT_SET && 5974 dut->ap_ampdu == VALUE_DISABLED && 5975 dut->ap_amsdu == VALUE_ENABLED) { 5976 run_iwpriv(dut, ifname, "setaddbaoper 1"); 5977 5978 snprintf(buf, sizeof(buf), 5979 "wifitool %s senddelba 1 0 1 4", ifname); 5980 if (system(buf) != 0) { 5981 sigma_dut_print(dut, DUT_MSG_ERROR, 5982 "wifitool senddelba failed"); 5983 } 5984 5985 snprintf(buf, sizeof(buf), "wifitool %s sendsingleamsdu 1 0", 5986 ifname); 5987 if (system(buf) != 0) { 5988 sigma_dut_print(dut, DUT_MSG_ERROR, 5989 "wifitool sendsingleamsdu failed"); 5990 } 5991 5992 run_iwpriv(dut, ifname, "amsdu 10"); 5993 } 5994 5995 if (dut->ap_mode == AP_11ac) { 5996 int chwidth, nss; 5997 5998 switch (dut->ap_chwidth) { 5999 case AP_20: 6000 chwidth = 0; 6001 break; 6002 case AP_40: 6003 chwidth = 1; 6004 break; 6005 case AP_80: 6006 chwidth = 2; 6007 break; 6008 case AP_160: 6009 chwidth = 3; 6010 break; 6011 case AP_80_80: 6012 chwidth = 3; 6013 break; 6014 default: 6015 chwidth = 0; 6016 break; 6017 } 6018 6019 switch (dut->ap_tx_streams) { 6020 case 1: 6021 nss = 1; 6022 break; 6023 case 2: 6024 nss = 2; 6025 break; 6026 case 3: 6027 nss = 3; 6028 break; 6029 case 4: 6030 nss = 4; 6031 break; 6032 default: 6033 nss = 3; 6034 break; 6035 } 6036 6037 if (dut->ap_fixed_rate) { 6038 if (nss == 4) 6039 ath_disable_txbf(dut, ifname); 6040 6041 /* Set the nss */ 6042 run_iwpriv(dut, ifname, "nss %d", nss); 6043 6044 /* Set the channel width */ 6045 run_iwpriv(dut, ifname, "chwidth %d", chwidth); 6046 6047 /* Set the VHT MCS */ 6048 run_iwpriv(dut, ifname, "vhtmcs %d", dut->ap_mcs); 6049 } 6050 } 6051 6052 if (dut->ap_dyn_bw_sig == VALUE_ENABLED) 6053 run_iwpriv(dut, ifname, "cwmenable 1"); 6054 else if (dut->ap_dyn_bw_sig == VALUE_DISABLED) 6055 run_iwpriv(dut, ifname, "cwmenable 0"); 6056 6057 if (dut->ap_sig_rts == VALUE_ENABLED) { 6058 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname); 6059 if (system(buf) != 0) { 6060 sigma_dut_print(dut, DUT_MSG_ERROR, 6061 "iwconfig rts 64 failed"); 6062 } 6063 } else if (dut->ap_sig_rts == VALUE_DISABLED) { 6064 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname); 6065 if (system(buf) != 0) { 6066 sigma_dut_print(dut, DUT_MSG_ERROR, 6067 "iwconfig rts 2347 failed"); 6068 } 6069 } 6070 6071 if (dut->ap_hs2) { 6072 run_iwpriv(dut, ifname, "qbssload 1"); 6073 sigma_dut_print(dut, DUT_MSG_INFO, "Enabled qbssload"); 6074 } 6075 6076 if (dut->ap_bss_load && dut->ap_bss_load != -1) { 6077 unsigned int bssload = 0; 6078 6079 if (dut->ap_bss_load == 1) { 6080 /* STA count: 1, CU: 50, AAC: 65535 */ 6081 bssload = 0x0132ffff; 6082 } else if (dut->ap_bss_load == 2) { 6083 /* STA count: 1, CU: 200, AAC: 65535 */ 6084 bssload = 0x01c8ffff; 6085 } else if (dut->ap_bss_load == 3) { 6086 /* STA count: 1, CU: 75, AAC: 65535 */ 6087 bssload = 0x014bffff; 6088 } 6089 6090 run_iwpriv(dut, ifname, "hcbssload %u", bssload); 6091 } else if (dut->ap_bss_load == 0) { 6092 run_iwpriv(dut, ifname, "qbssload 0"); 6093 sigma_dut_print(dut, DUT_MSG_INFO, "Disabled qbssload"); 6094 } 6095 6096 if (dut->ap_dgaf_disable) { 6097 run_iwpriv(dut, ifname, "dgaf_disable 1"); 6098 sigma_dut_print(dut, DUT_MSG_INFO, "Enabled dgaf_disable"); 6099 } 6100 6101 if (dut->ap_l2tif) { 6102 run_iwpriv(dut, ifname, "l2tif 1"); 6103 snprintf(buf, sizeof(buf), 6104 "echo 1 > /sys/class/net/br0/brif/ath0/hotspot_l2tif"); 6105 if (system(buf) != 0) 6106 sigma_dut_print(dut, DUT_MSG_ERROR, 6107 "l2tif br failed"); 6108 6109 snprintf(buf, sizeof(buf), 6110 "echo 1 > /sys/class/net/br0/brif/eth0/hotspot_wan"); 6111 if (system(buf) != 0) 6112 sigma_dut_print(dut, DUT_MSG_ERROR, 6113 "l2tif brif failed"); 6114 sigma_dut_print(dut, DUT_MSG_INFO, "Enabled l2tif"); 6115 } 6116 6117 if (dut->ap_ndpa_frame == 0) { 6118 snprintf(buf, sizeof(buf), 6119 "wifitool %s beeliner_fw_test 117 192", ifname); 6120 if (system(buf) != 0) { 6121 sigma_dut_print(dut, DUT_MSG_ERROR, 6122 "wifitool beeliner_fw_test 117 192 failed"); 6123 } 6124 snprintf(buf, sizeof(buf), 6125 "wifitool %s beeliner_fw_test 118 192", ifname); 6126 if (system(buf) != 0) { 6127 sigma_dut_print(dut, DUT_MSG_ERROR, 6128 "wifitool beeliner_fw_test 117 192 failed"); 6129 } 6130 } else if (dut->ap_ndpa_frame == 1) { 6131 /* Driver default - no changes needed */ 6132 } else if (dut->ap_ndpa_frame == 2) { 6133 snprintf(buf, sizeof(buf), 6134 "wifitool %s beeliner_fw_test 115 1", ifname); 6135 if (system(buf) != 0) { 6136 sigma_dut_print(dut, DUT_MSG_ERROR, 6137 "wifitool beeliner_fw_test 117 192 failed"); 6138 } 6139 snprintf(buf, sizeof(buf), 6140 "wifitool %s beeliner_fw_test 116 1", ifname); 6141 if (system(buf) != 0) { 6142 sigma_dut_print(dut, DUT_MSG_ERROR, 6143 "wifitool beeliner_fw_test 117 192 failed"); 6144 } 6145 } 6146 6147 if (dut->ap_rtt == 1) 6148 run_iwpriv(dut, ifname, "enable_rtt 1"); 6149 6150 if (dut->ap_lci == 1) 6151 run_iwpriv(dut, ifname, "enable_lci 1"); 6152 6153 if (dut->ap_lcr == 1) 6154 run_iwpriv(dut, ifname, "enable_lcr 1"); 6155 6156 if (dut->ap_rrm == 1) 6157 run_iwpriv(dut, ifname, "enable_rmm 1"); 6158 6159 if (dut->ap_lci == 1 || dut->ap_lcr == 1) { 6160 run_system(dut, "wpc -l /tmp/lci_cfg.txt"); 6161 } 6162 6163 if (dut->ap_neighap >= 1 && dut->ap_lci == 0) { 6164 FILE *f; 6165 6166 f = fopen("/tmp/nbr_report.txt", "w"); 6167 if (!f) { 6168 sigma_dut_print(dut, DUT_MSG_ERROR, 6169 "Failed to open /tmp/nbr_report.txt"); 6170 return; 6171 } 6172 6173 fprintf(f, 6174 "ap_1 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x2a 0x00\n", 6175 dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1], 6176 dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3], 6177 dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5], 6178 dut->ap_val_opchannel[0]); 6179 fclose(f); 6180 6181 f = fopen("/tmp/ftmrr.txt", "w"); 6182 if (!f) { 6183 sigma_dut_print(dut, DUT_MSG_ERROR, 6184 "Failed to open /tmp/ftmrr.txt"); 6185 return; 6186 } 6187 6188 fprintf(f, 6189 "ap_1 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x2a 0x00\n", 6190 dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1], 6191 dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3], 6192 dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5], 6193 dut->ap_val_opchannel[0]); 6194 fclose(f); 6195 } 6196 6197 if (dut->ap_neighap >= 2 && dut->ap_lci == 0) { 6198 FILE *f; 6199 6200 f = fopen("/tmp/nbr_report.txt", "a"); 6201 if (!f) { 6202 sigma_dut_print(dut, DUT_MSG_ERROR, 6203 "Failed to open /tmp/nbr_report.txt"); 6204 return; 6205 } 6206 fprintf(f, 6207 "ap_2 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x6a 0x00\n", 6208 dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1], 6209 dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3], 6210 dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5], 6211 dut->ap_val_opchannel[1]); 6212 fclose(f); 6213 6214 f = fopen("/tmp/ftmrr.txt", "a"); 6215 if (!f) { 6216 sigma_dut_print(dut, DUT_MSG_ERROR, 6217 "Failed to open /tmp/ftmrr.txt"); 6218 return; 6219 } 6220 fprintf(f, 6221 "ap_2 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x6a 0x00\n", 6222 dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1], 6223 dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3], 6224 dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5], 6225 dut->ap_val_opchannel[1]); 6226 fclose(f); 6227 } 6228 6229 if (dut->ap_neighap >= 3 && dut->ap_lci == 0) { 6230 FILE *f; 6231 6232 f = fopen("/tmp/nbr_report.txt", "a"); 6233 if (!f) { 6234 sigma_dut_print(dut, DUT_MSG_ERROR, 6235 "Failed to open /tmp/nbr_report.txt"); 6236 return; 6237 } 6238 6239 fprintf(f, 6240 "ap_3 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x9b 0x00\n", 6241 dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1], 6242 dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3], 6243 dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5], 6244 dut->ap_val_opchannel[2]); 6245 fclose(f); 6246 6247 f = fopen("/tmp/ftmrr.txt", "a"); 6248 if (!f) { 6249 sigma_dut_print(dut, DUT_MSG_ERROR, 6250 "Failed to open /tmp/ftmrr.txt"); 6251 return; 6252 } 6253 6254 fprintf(f, 6255 "ap_3 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x9b 0x00\n", 6256 dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1], 6257 dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3], 6258 dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5], 6259 dut->ap_val_opchannel[2]); 6260 fclose(f); 6261 } 6262 6263 if (dut->ap_neighap) { 6264 run_iwpriv(dut, ifname, "enable_rtt 1"); 6265 run_iwpriv(dut, ifname, "enable_lci 1"); 6266 run_iwpriv(dut, ifname, "enable_lcr 1"); 6267 run_iwpriv(dut, ifname, "enable_rrm 1"); 6268 } 6269 6270 if (dut->ap_scan == 1) { 6271 run_iwpriv(dut, ifname, "scanentryage 600"); 6272 snprintf(buf, sizeof(buf), "iwlist %s scan", ifname); 6273 run_system(dut, buf); 6274 } 6275 6276 if (dut->ap_set_bssidpref) { 6277 snprintf(buf, sizeof(buf), 6278 "wifitool %s setbssidpref 00:00:00:00:00:00 0 00 00", 6279 ifname); 6280 if (system(buf) != 0) { 6281 sigma_dut_print(dut, DUT_MSG_ERROR, 6282 "wifitool clear bssidpref failed"); 6283 } 6284 } 6285 6286 if (dut->wnm_bss_max_feature != VALUE_NOT_SET) { 6287 int feature_enable; 6288 6289 feature_enable = dut->wnm_bss_max_feature == VALUE_ENABLED; 6290 run_iwpriv(dut, ifname, "wnm %d", feature_enable); 6291 run_iwpriv(dut, ifname, "wnm_bss %d", feature_enable); 6292 if (feature_enable) { 6293 const char *extra = ""; 6294 6295 if (dut->wnm_bss_max_protection != VALUE_NOT_SET) { 6296 if (dut->wnm_bss_max_protection == 6297 VALUE_ENABLED) 6298 extra = " 1"; 6299 else 6300 extra = " 0"; 6301 } 6302 snprintf(buf, sizeof(buf), 6303 "wlanconfig %s wnm setbssmax %d%s", 6304 ifname, dut->wnm_bss_max_idle_time, extra); 6305 run_system(dut, buf); 6306 } 6307 } 6308 6309 if (dut->program == PROGRAM_MBO) { 6310 apply_mbo_pref_ap_list(dut); 6311 run_iwpriv(dut, ifname, "mbo_cel_pref %d", 6312 dut->ap_cell_cap_pref); 6313 run_iwpriv(dut, ifname, "mbocap 0x40"); 6314 ath_set_assoc_disallow(dut, ifname, "disable"); 6315 } 6316 6317 if (dut->ap_oce == VALUE_ENABLED) 6318 run_iwpriv(dut, ifname, "set_bpr_enable 1"); 6319 6320 if (dut->ap_oce == VALUE_ENABLED && dut->ap_channel <= 11) { 6321 run_iwpriv(dut, ifname, "prb_rate 5500"); 6322 run_iwpriv(dut, ifname, "set_bcn_rate 5500"); 6323 } 6324 6325 if (dut->ap_oce == VALUE_DISABLED) 6326 run_iwpriv(dut, ifname, "set_bpr_enable 0"); 6327 6328 if (dut->ap_oce == VALUE_DISABLED && dut->ap_channel <= 11) { 6329 run_iwpriv(dut, ifname, "mgmt_rate 1000"); 6330 run_iwpriv(dut, ifname, "set_bcn_rate 1000"); 6331 } 6332 6333 if (dut->ap_bcnint) 6334 run_iwpriv(dut, ifname, "bintval %d", dut->ap_bcnint); 6335 6336 if (dut->ap_filsdscv == VALUE_DISABLED) 6337 run_iwpriv(dut, ifname, "enable_fils 0 0"); 6338 6339 if (dut->ap_filshlp == VALUE_ENABLED) 6340 run_iwpriv(dut, ifname, "oce_hlp 1"); 6341 else if (dut->ap_filshlp == VALUE_DISABLED) 6342 run_iwpriv(dut, ifname, "oce_hlp 0"); 6343 6344 /* When RNR is enabled, also enable apchannelreport, background scan */ 6345 if (dut->ap_rnr == VALUE_ENABLED) { 6346 run_iwpriv(dut, ifname, "rnr 1"); 6347 run_iwpriv(dut, ifname, "rnr_tbtt 1"); 6348 run_iwpriv(dut, ifname, "apchanrpt 1"); 6349 run_iwpriv(dut, basedev, "acs_ctrlflags 0x4"); 6350 run_iwpriv(dut, basedev, "acs_scanintvl 60"); 6351 run_iwpriv(dut, basedev, "acs_bkscanen 1"); 6352 if (dut->ap_is_dual == 1) { 6353 run_iwpriv(dut, ifname_dual, "rnr 1"); 6354 run_iwpriv(dut, ifname_dual, "rnr_tbtt 1"); 6355 run_iwpriv(dut, ifname_dual, "apchanrpt 1"); 6356 run_iwpriv(dut, basedev_radio, "acs_ctrlflags 0x4"); 6357 run_iwpriv(dut, basedev_radio, "acs_scanintvl 60"); 6358 run_iwpriv(dut, basedev_radio, "acs_bkscanen 1"); 6359 } 6360 } 6361 6362 if (dut->ap_blechanutil || dut->ap_ble_admit_cap || dut->ap_blestacnt) { 6363 run_iwpriv(dut, ifname, "qbssload 0"); 6364 snprintf(buf, sizeof(buf), 6365 "wlanconfig %s addie ftype 0 len 7 data 0b05%02x%02x%02x%02x%02x ", 6366 ifname, dut->ap_blestacnt & 0xFF, 6367 dut->ap_blestacnt >> 8, dut->ap_blechanutil, 6368 dut->ap_ble_admit_cap & 0xFF, 6369 dut->ap_ble_admit_cap >> 8); 6370 run_system(dut, buf); 6371 snprintf(buf, sizeof(buf), 6372 "wlanconfig %s addie ftype 2 len 7 data 0b05%02x%02x%02x%02x%02x ", 6373 ifname, dut->ap_blestacnt & 0xFF, 6374 dut->ap_blestacnt >> 8, dut->ap_blechanutil, 6375 dut->ap_ble_admit_cap & 0xFF, 6376 dut->ap_ble_admit_cap >> 8); 6377 run_system(dut, buf); 6378 } 6379 6380 if (dut->ap_esp == VALUE_ENABLED) 6381 run_iwpriv(dut, basedev, "esp_period 5"); 6382 else if (dut->ap_esp == VALUE_DISABLED) 6383 run_iwpriv(dut, basedev, "esp_period 0"); 6384 6385 if (dut->ap_datappdudura) 6386 run_iwpriv(dut, basedev, "esp_ppdu_dur %d", 6387 dut->ap_datappdudura); 6388 6389 if (dut->ap_airtimefract) 6390 run_iwpriv(dut, basedev, "esp_airtime %d", 6391 dut->ap_airtimefract); 6392 6393 if (dut->ap_dhcp_stop) { 6394 snprintf(buf, sizeof(buf), "/etc/init.d/dnsmasq stop"); 6395 run_system(dut, buf); 6396 } 6397 6398 if (dut->ap_bawinsize) 6399 run_iwpriv(dut, basedev, "esp_ba_window %d", dut->ap_bawinsize); 6400 6401 if (dut->program == PROGRAM_DPP) { 6402 if (dut->ap_interface_2g == 1) { 6403 run_iwpriv(dut, ifname, "set_bcn_rate 5500"); 6404 run_iwpriv(dut, ifname, "prb_rate 5500"); 6405 run_iwpriv(dut, ifname, "mgmt_rate 5500"); 6406 } 6407 6408 run_iwpriv(dut, basedev, "set_rxfilter 0xffffffff"); 6409 dut->hostapd_running = 1; 6410 } 6411 6412 if (dut->program == PROGRAM_HE) { 6413 /* disable sending basic triggers */ 6414 run_system_wrapper(dut, 6415 "wifitool %s setUnitTestCmd 0x47 2 42 0", 6416 ifname); 6417 /* disable MU BAR */ 6418 run_system_wrapper(dut, 6419 "wifitool %s setUnitTestCmd 0x47 2 64 1", 6420 ifname); 6421 /* disable PSD Boost */ 6422 run_system_wrapper(dut, 6423 "wifitool %s setUnitTestCmd 0x48 2 142 1", 6424 ifname); 6425 /* Enable mix bw */ 6426 run_system_wrapper(dut, 6427 "wifitool %s setUnitTestCmd 0x47 2 141 1", 6428 ifname); 6429 /* Disable preferred AC */ 6430 run_system_wrapper(dut, 6431 "wifitool %s setUnitTestCmd 0x48 2 186 0", 6432 ifname); 6433 run_iwpriv(dut, basedev, "he_muedca_mode 0"); 6434 run_iwpriv(dut, ifname, "he_ul_ofdma 0"); 6435 run_iwpriv(dut, ifname, "he_dl_ofdma 0"); 6436 if (dut->he_set_sta_1x1 == VALUE_ENABLED) { 6437 /* sets g_force_1x1_peer to 1 */ 6438 run_system_wrapper(dut, 6439 "wifitool %s setUnitTestCmd 0x48 2 118 1", 6440 ifname); 6441 } 6442 if (dut->ap_txBF) { 6443 /* Enable SU_AX sounding */ 6444 run_iwpriv(dut, ifname, "he_sounding_mode 1"); 6445 /* Ignore TBTT for NDP */ 6446 run_system_wrapper(dut, 6447 "wifitool %s setUnitTestCmd 0x48 2 2 1", 6448 ifname); 6449 /* g_cv_query_enable=1, i.e., cv query enable */ 6450 run_system_wrapper(dut, 6451 "wifitool %s setUnitTestCmd 0x47 2 7 1", 6452 ifname); 6453 /* Override TPC calculations and set TxBF flag to True 6454 */ 6455 run_system_wrapper(dut, 6456 "wifitool %s setUnitTestCmd 0x47 2 47 1", 6457 ifname); 6458 } 6459 if (dut->device_type == AP_testbed) { 6460 run_iwpriv(dut, ifname, "tx_stbc 0"); 6461 run_iwpriv(dut, ifname, "he_txmcsmap 0x0"); 6462 run_iwpriv(dut, ifname, "he_rxmcsmap 0x0"); 6463 run_iwpriv(dut, ifname, "he_amsdu_in_ampdu_supp 0"); 6464 run_iwpriv(dut, ifname, "he_bfee_sts_supp 0 0"); 6465 run_iwpriv(dut, ifname, "he_4xltf_800nsgi_rx 0"); 6466 run_iwpriv(dut, ifname, "he_1xltf_800nsgi_rx 0"); 6467 run_iwpriv(dut, ifname, "he_max_nc 0"); 6468 run_iwpriv(dut, ifname, "he_bsr_supp 0"); 6469 run_iwpriv(dut, ifname, "rx_stbc 0"); 6470 if (dut->ap_he_dlofdma == VALUE_DISABLED) 6471 run_iwpriv(dut, ifname, "he_dlofdma 0"); 6472 if (dut->ap_channel <= 11) { 6473 dut->ap_bcc = VALUE_ENABLED; 6474 run_iwpriv(dut, ifname, "vht_11ng 0"); 6475 } 6476 if (!dut->ap_txBF) { 6477 run_iwpriv(dut, ifname, "he_subfer 0"); 6478 run_iwpriv(dut, ifname, "he_subfee 0"); 6479 } 6480 if (!dut->ap_mu_txBF) { 6481 run_iwpriv(dut, ifname, "he_mubfer 0"); 6482 run_iwpriv(dut, ifname, "he_mubfee 0"); 6483 } 6484 if (dut->ap_cipher == AP_WEP || 6485 dut->ap_cipher == AP_TKIP) 6486 run_iwpriv(dut, ifname, "htweptkip 1"); 6487 if (dut->ap_rx_streams || dut->ap_tx_streams) 6488 run_iwpriv(dut, ifname, "nss %d", 6489 dut->ap_rx_streams); 6490 } 6491 } 6492 6493 if (dut->ap_he_ulofdma == VALUE_ENABLED) { 6494 run_iwpriv(dut, ifname, "he_ul_ofdma 1"); 6495 run_iwpriv(dut, ifname, "he_mu_edca 1"); 6496 6497 /* Disable sounding for UL OFDMA */ 6498 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0", 6499 ifname); 6500 6501 if ((dut->ap_rx_streams || dut->ap_tx_streams) && 6502 dut->device_type == AP_testbed) { 6503 unsigned int txchainmask = 0x00; 6504 6505 switch (dut->ap_rx_streams) { 6506 case 1: 6507 txchainmask = 0x01; 6508 break; 6509 case 2: 6510 txchainmask = 0x03; 6511 break; 6512 case 3: 6513 txchainmask = 0x07; 6514 break; 6515 case 4: 6516 txchainmask = 0x0f; 6517 break; 6518 case 5: 6519 txchainmask = 0x1f; 6520 break; 6521 case 6: 6522 txchainmask = 0x3f; 6523 break; 6524 case 7: 6525 txchainmask = 0x7f; 6526 break; 6527 case 8: 6528 txchainmask = 0xff; 6529 break; 6530 } 6531 6532 run_iwpriv(dut, ifname, "he_ul_nss %d", 6533 dut->ap_rx_streams); 6534 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask); 6535 run_iwpriv(dut, basedev, "rxchainmask %d", txchainmask); 6536 } 6537 6538 if (dut->ap_channel == 100 && dut->device_type == AP_testbed) 6539 run_system_wrapper(dut, "iwpriv %s inact 1000", ifname); 6540 6541 if (dut->he_ul_mcs) 6542 run_iwpriv(dut, ifname, "he_ul_mcs %d", dut->he_ul_mcs); 6543 6544 run_iwpriv(dut, ifname, "he_ul_ltf 3"); 6545 run_iwpriv(dut, ifname, "he_ul_shortgi 3"); 6546 run_iwpriv(dut, basedev, "he_ul_trig_int 2"); 6547 6548 /* Disable efficiency check for UL OFDMA. We do not send TBPPDU 6549 * for one user. With this command, we would send UL OFDMA even 6550 * for one user to allow testing to be done without requiring 6551 * more than one station. */ 6552 run_system_wrapper(dut, 6553 "wifitool %s setUnitTestCmd 0x47 2 131 0", 6554 ifname); 6555 /* Set random RU allocation */ 6556 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 9 1", 6557 ifname); 6558 /* To set TBTT PPDU duration (us) */ 6559 run_system_wrapper(dut, 6560 "wifitool %s setUnitTestCmd 0x48 2 63 1908", 6561 ifname); 6562 } 6563 6564 if (dut->ap_he_dlofdma == VALUE_ENABLED) { 6565 run_iwpriv(dut, ifname, "he_dl_ofdma 1", ifname); 6566 6567 /* For fixed MCS */ 6568 novap_reset(dut, ifname, 0); 6569 run_iwpriv(dut, ifname, 6570 "cfg80211tool %s setratemask 3 0x80f80f80 0x0f80f80f 0xf80f80f8"); 6571 } 6572 6573 if (dut->ap_he_ppdu == PPDU_MU && dut->ap_he_dlofdma == VALUE_ENABLED) { 6574 /* Increase the min TX time limit for MU MIMO to disable MU MIMO 6575 * scheduling */ 6576 run_system_wrapper(dut, 6577 "wifitool %s setUnitTestCmd 0x47 2 11 1000000", 6578 ifname); 6579 /* Increase the max TX time limit for DL OFDMA to enable OFDMA 6580 * scheduling */ 6581 run_system_wrapper(dut, 6582 "wifitool %s setUnitTestCmd 0x47 2 17 1000000", 6583 ifname); 6584 /* Disable 'force SU schedule' to enable MU sch */ 6585 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 8 0", 6586 ifname); 6587 /* Enable MU 11ax support in sch algo */ 6588 run_system_wrapper(dut, 6589 "wifitool %s setUnitTestCmd 0x47 2 29 0", 6590 ifname); 6591 /* Enable to sort RU allocation */ 6592 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x4b 2 2 1", 6593 ifname); 6594 } 6595 6596 if (dut->ap_numsounddim) { 6597 unsigned int txchainmask = 0; 6598 6599 switch (dut->ap_numsounddim) { 6600 case 1: 6601 txchainmask = 0x01; 6602 break; 6603 case 2: 6604 txchainmask = 0x03; 6605 break; 6606 case 3: 6607 txchainmask = 0x07; 6608 break; 6609 case 4: 6610 txchainmask = 0x0f; 6611 break; 6612 case 5: 6613 txchainmask = 0x1f; 6614 break; 6615 case 6: 6616 txchainmask = 0x3f; 6617 break; 6618 case 7: 6619 txchainmask = 0x7f; 6620 break; 6621 case 8: 6622 txchainmask = 0xff; 6623 break; 6624 } 6625 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask); 6626 } 6627 6628 if (dut->ap_numsounddim && dut->device_type == AP_testbed) { 6629 /* Sets g_force_1x1_peer to 1 which should be reset to zero 6630 * for non-MU test cases */ 6631 run_system_wrapper(dut, 6632 "wifitool %s setUnitTestCmd 0x48 2 118 1", 6633 ifname); 6634 if (dut->ap_mu_txBF) { 6635 /* Disable DL OFDMA */ 6636 run_system_wrapper(dut, 6637 "wifitool %s setUnitTestCmd 0x47 2 11 0", 6638 ifname); 6639 } 6640 } 6641 6642 if (dut->ap_bcc == VALUE_ENABLED) { 6643 run_iwpriv(dut, ifname, "mode 11AHE20"); 6644 run_iwpriv(dut, ifname, "nss 2"); 6645 run_iwpriv(dut, ifname, "he_txmcsmap 0x0"); 6646 run_iwpriv(dut, ifname, "he_rxmcsmap 0x0"); 6647 } 6648 6649 if (dut->ap_he_frag == VALUE_ENABLED) 6650 run_iwpriv(dut, ifname, "he_frag 1"); 6651 else if (dut->ap_he_frag == VALUE_DISABLED) 6652 run_iwpriv(dut, ifname, "he_frag 0"); 6653 6654 if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) { 6655 if (dut->ap_ba_bufsize == BA_BUFSIZE_64) 6656 run_iwpriv(dut, ifname, "ba_bufsize 0"); 6657 else 6658 run_iwpriv(dut, ifname, "ba_bufsize 1"); 6659 } 6660 6661 if (dut->ap_mu_edca == VALUE_ENABLED) 6662 run_iwpriv(dut, ifname, "he_mu_edca 1"); 6663 6664 if (dut->ap_he_mimo == MIMO_DL) { 6665 mubrp_commands(dut, ifname); 6666 if (dut->device_type != AP_testbed) 6667 run_system_wrapper( 6668 dut, "wifitool %s setUnitTestCmd 0x48 2 100 2", 6669 ifname); 6670 } 6671 6672 if (dut->ap_he_mimo == MIMO_UL) 6673 run_iwpriv(dut, ifname, "he_mubfee 1"); 6674 6675 if (dut->ap_he_rtsthrshld == VALUE_ENABLED) 6676 run_iwpriv(dut, ifname, "he_rtsthrshld 512"); 6677 else if (dut->ap_he_rtsthrshld == VALUE_DISABLED) 6678 run_iwpriv(dut, ifname, "he_rtsthrshld 1024"); 6679 6680 if (dut->ap_mbssid == VALUE_ENABLED && 6681 (dut->ap_rx_streams || dut->ap_tx_streams) && 6682 dut->device_type == AP_testbed) { 6683 const char *ifname_1; 6684 6685 ifname_1= dut->ap_channel >= 36 ? "ath01" : "ath11"; 6686 6687 /* NSS is not set in Secondary VAP for MBSSID case, 6688 * hence it is explicitly set here. For primary VAP 6689 * NSS is set during AP configuration */ 6690 run_iwpriv(dut, ifname_1, "nss %d", dut->ap_rx_streams); 6691 } 6692 6693 if (dut->ap_twtresp == VALUE_ENABLED) 6694 run_iwpriv(dut, ifname, "twt_responder 1"); 6695 else if (dut->ap_twtresp == VALUE_DISABLED) 6696 run_iwpriv(dut, ifname, "twt_responder 0"); 6697 6698 if (dut->program == PROGRAM_HE && dut->ap_fixed_rate) { 6699 int nss = 0, mcs = 0; 6700 uint16_t mcsnssmap = 0; 6701 6702 /* MCS 7 is used - set only nss and he_mcs. 6703 * Do not set mcsnssmap unless MCS is 9 or 11. */ 6704 if (dut->ap_mcs >= 9) { 6705 if (dut->ap_mcs == 9) { 6706 if (dut->ap_tx_streams == 1) { 6707 nss = 1; 6708 mcs = dut->ap_mcs; 6709 } else if (dut->ap_tx_streams == 2) { 6710 nss = 2; 6711 mcs = dut->ap_mcs; 6712 } 6713 } else if (dut->ap_mcs == 11) { 6714 if (dut->ap_tx_streams == 1) { 6715 nss = 1; 6716 mcs = dut->ap_mcs; 6717 } else if (dut->ap_tx_streams == 2) { 6718 nss = 2; 6719 mcs = dut->ap_mcs; 6720 } 6721 } 6722 6723 get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs); 6724 he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap; 6725 } 6726 6727 run_iwpriv(dut, ifname, "nss %d", dut->ap_tx_streams); 6728 run_iwpriv(dut, ifname, "he_mcs %d", dut->ap_mcs); 6729 } 6730 6731 if (he_mcsnssmap) { 6732 run_iwpriv(dut, ifname, "he_rxmcsmap %lu", he_mcsnssmap); 6733 run_iwpriv(dut, ifname, "he_txmcsmap %lu", he_mcsnssmap); 6734 } 6735 6736 if (dut->he_sounding == VALUE_ENABLED) 6737 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0", 6738 ifname); 6739 6740 if (dut->he_mmss) 6741 run_iwpriv(dut, ifname, "ampduden_ovrd %d", dut->he_mmss); 6742 6743 if (dut->he_srctrl_allow == 0) { 6744 /* This is a special testbed AP case to enable SR for protocol 6745 * testing when SRCtrl_SRValue15Allowed is specified. 6746 */ 6747 run_iwpriv(dut, ifname, "he_sr_enable 1"); 6748 } 6749 } 6750 6751 6752 static int cmd_ath_ap_config_commit(struct sigma_dut *dut, 6753 struct sigma_conn *conn, 6754 struct sigma_cmd *cmd) 6755 { 6756 /* const char *name = get_param(cmd, "NAME"); */ 6757 char buf[100]; 6758 struct stat s; 6759 const char *ifname = dut->ap_is_dual ? "ath1" : "ath0"; 6760 int res; 6761 6762 if (stat("/proc/athversion", &s) == 0) { 6763 sigma_dut_print(dut, DUT_MSG_INFO, "Run apdown"); 6764 run_system(dut, "apdown"); 6765 } 6766 6767 cmd_ath_ap_radio_config(dut); 6768 6769 snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID=%s'", dut->ap_ssid); 6770 run_system(dut, buf); 6771 6772 switch (dut->ap_key_mgmt) { 6773 case AP_OPEN: 6774 if (dut->ap_cipher == AP_WEP) { 6775 run_system(dut, "cfg -a AP_SECMODE=WEP"); 6776 run_system(dut, "cfg -a AP_SECFILE=NONE"); 6777 /* shared auth mode not supported */ 6778 run_system(dut, "cfg -a AP_WEP_MODE_0=1"); 6779 run_system(dut, "cfg -a AP_WEP_MODE_1=1"); 6780 snprintf(buf, sizeof(buf), 6781 "cfg -a WEP_RADIO_NUM0_KEY_1=%s", 6782 dut->ap_wepkey); 6783 run_system(dut, buf); 6784 snprintf(buf, sizeof(buf), 6785 "cfg -a WEP_RADIO_NUM1_KEY_1=%s", 6786 dut->ap_wepkey); 6787 run_system(dut, buf); 6788 } else { 6789 run_system(dut, "cfg -a AP_SECMODE=None"); 6790 } 6791 break; 6792 case AP_WPA2_PSK: 6793 case AP_WPA2_PSK_MIXED: 6794 case AP_WPA_PSK: 6795 case AP_WPA2_SAE: 6796 case AP_WPA2_PSK_SAE: 6797 if (dut->ap_key_mgmt == AP_WPA2_PSK || 6798 dut->ap_key_mgmt == AP_WPA2_SAE || 6799 dut->ap_key_mgmt == AP_WPA2_PSK_SAE) 6800 run_system(dut, "cfg -a AP_WPA=2"); 6801 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) 6802 run_system(dut, "cfg -a AP_WPA=3"); 6803 else 6804 run_system(dut, "cfg -a AP_WPA=1"); 6805 /* TODO: SAE configuration */ 6806 run_system(dut, "cfg -a AP_SECMODE=WPA"); 6807 run_system(dut, "cfg -a AP_SECFILE=PSK"); 6808 res = snprintf(buf, sizeof(buf), "cfg -a 'PSK_KEY=%s'", 6809 dut->ap_passphrase); 6810 if (res < 0 || res >= sizeof(buf)) 6811 return ERROR_SEND_STATUS; 6812 run_system(dut, buf); 6813 if (dut->ap_cipher == AP_CCMP_TKIP) 6814 run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\""); 6815 else if (dut->ap_cipher == AP_TKIP) 6816 run_system(dut, "cfg -a AP_CYPHER=TKIP"); 6817 else 6818 run_system(dut, "cfg -a AP_CYPHER=CCMP"); 6819 break; 6820 case AP_WPA2_EAP: 6821 case AP_WPA2_EAP_MIXED: 6822 case AP_WPA_EAP: 6823 if (dut->ap_key_mgmt == AP_WPA2_EAP) 6824 run_system(dut, "cfg -a AP_WPA=2"); 6825 else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) 6826 run_system(dut, "cfg -a AP_WPA=3"); 6827 else 6828 run_system(dut, "cfg -a AP_WPA=1"); 6829 run_system(dut, "cfg -a AP_SECMODE=WPA"); 6830 run_system(dut, "cfg -a AP_SECFILE=EAP"); 6831 if (dut->ap_cipher == AP_CCMP_TKIP) 6832 run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\""); 6833 else if (dut->ap_cipher == AP_TKIP) 6834 run_system(dut, "cfg -a AP_CYPHER=TKIP"); 6835 else 6836 run_system(dut, "cfg -a AP_CYPHER=CCMP"); 6837 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER=%s", 6838 dut->ap_radius_ipaddr); 6839 run_system(dut, buf); 6840 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT=%d", 6841 dut->ap_radius_port); 6842 run_system(dut, buf); 6843 res = snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SECRET=%s", 6844 dut->ap_radius_password); 6845 if (res < 0 || res >= sizeof(buf)) 6846 return ERROR_SEND_STATUS; 6847 run_system(dut, buf); 6848 break; 6849 case AP_WPA2_EAP_OSEN: 6850 /* TODO */ 6851 sigma_dut_print(dut, DUT_MSG_ERROR, "EAP+OSEN not supported"); 6852 break; 6853 case AP_SUITEB: 6854 /* TODO */ 6855 sigma_dut_print(dut, DUT_MSG_ERROR, "SuiteB not supported"); 6856 break; 6857 case AP_WPA2_OWE: 6858 /* TODO */ 6859 sigma_dut_print(dut, DUT_MSG_ERROR, "OWE not supported"); 6860 break; 6861 case AP_WPA2_FT_EAP: 6862 case AP_WPA2_FT_PSK: 6863 case AP_WPA2_EAP_SHA256: 6864 case AP_WPA2_PSK_SHA256: 6865 case AP_WPA2_ENT_FT_EAP: 6866 case AP_OSEN: 6867 /* TODO */ 6868 send_resp(dut, conn, SIGMA_ERROR, 6869 "errorCode,Unsupported KeyMgnt value"); 6870 return 0; 6871 } 6872 6873 if (dut->ap_is_dual) { 6874 /* ath1 settings in case of dual */ 6875 snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID_2=%s'", 6876 dut->ap_ssid); 6877 run_system(dut, buf); 6878 6879 switch (dut->ap_key_mgmt) { 6880 case AP_OPEN: 6881 if (dut->ap_cipher == AP_WEP) { 6882 run_system(dut, "cfg -a AP_SECMODE_2=WEP"); 6883 run_system(dut, "cfg -a AP_SECFILE_2=NONE"); 6884 /* shared auth mode not supported */ 6885 run_system(dut, "cfg -a AP_WEP_MODE_0=1"); 6886 run_system(dut, "cfg -a AP_WEP_MODE_1=1"); 6887 snprintf(buf, sizeof(buf), 6888 "cfg -a WEP_RADIO_NUM0_KEY_1=%s", 6889 dut->ap_wepkey); 6890 run_system(dut, buf); 6891 snprintf(buf, sizeof(buf), 6892 "cfg -a WEP_RADIO_NUM1_KEY_1=%s", 6893 dut->ap_wepkey); 6894 run_system(dut, buf); 6895 } else { 6896 run_system(dut, "cfg -a AP_SECMODE_2=None"); 6897 } 6898 break; 6899 case AP_WPA2_PSK: 6900 case AP_WPA2_PSK_MIXED: 6901 case AP_WPA_PSK: 6902 case AP_WPA2_SAE: 6903 case AP_WPA2_PSK_SAE: 6904 if (dut->ap_key_mgmt == AP_WPA2_PSK || 6905 dut->ap_key_mgmt == AP_WPA2_SAE || 6906 dut->ap_key_mgmt == AP_WPA2_PSK_SAE) 6907 run_system(dut, "cfg -a AP_WPA_2=2"); 6908 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) 6909 run_system(dut, "cfg -a AP_WPA_2=3"); 6910 else 6911 run_system(dut, "cfg -a AP_WPA_2=1"); 6912 // run_system(dut, "cfg -a AP_WPA_2=2"); 6913 /* TODO: SAE configuration */ 6914 run_system(dut, "cfg -a AP_SECMODE_2=WPA"); 6915 run_system(dut, "cfg -a AP_SECFILE_2=PSK"); 6916 res = snprintf(buf, sizeof(buf), 6917 "cfg -a 'PSK_KEY_2=%s'", 6918 dut->ap_passphrase); 6919 if (res < 0 || res >= sizeof(buf)) 6920 return ERROR_SEND_STATUS; 6921 run_system(dut, buf); 6922 if (dut->ap_cipher == AP_CCMP_TKIP) 6923 run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\""); 6924 else if (dut->ap_cipher == AP_TKIP) 6925 run_system(dut, "cfg -a AP_CYPHER_2=TKIP"); 6926 else 6927 run_system(dut, "cfg -a AP_CYPHER_2=CCMP"); 6928 break; 6929 case AP_WPA2_EAP: 6930 case AP_WPA2_EAP_MIXED: 6931 case AP_WPA_EAP: 6932 if (dut->ap_key_mgmt == AP_WPA2_EAP) 6933 run_system(dut, "cfg -a AP_WPA_2=2"); 6934 else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) 6935 run_system(dut, "cfg -a AP_WPA_2=3"); 6936 else 6937 run_system(dut, "cfg -a AP_WPA_2=1"); 6938 run_system(dut, "cfg -a AP_SECMODE_2=WPA"); 6939 run_system(dut, "cfg -a AP_SECFILE_2=EAP"); 6940 if (dut->ap_cipher == AP_CCMP_TKIP) 6941 run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\""); 6942 else if (dut->ap_cipher == AP_TKIP) 6943 run_system(dut, "cfg -a AP_CYPHER_2=TKIP"); 6944 else 6945 run_system(dut, "cfg -a AP_CYPHER_2=CCMP"); 6946 6947 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER_2=%s", 6948 dut->ap_radius_ipaddr); 6949 run_system(dut, buf); 6950 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT_2=%d", 6951 dut->ap_radius_port); 6952 run_system(dut, buf); 6953 res = snprintf(buf, sizeof(buf), 6954 "cfg -a AP_AUTH_SECRET_2=%s", 6955 dut->ap_radius_password); 6956 if (res < 0 || res >= sizeof(buf)) 6957 return ERROR_SEND_STATUS; 6958 run_system(dut, buf); 6959 break; 6960 case AP_WPA2_EAP_OSEN: 6961 /* TODO */ 6962 sigma_dut_print(dut, DUT_MSG_ERROR, 6963 "EAP+OSEN not supported"); 6964 break; 6965 case AP_SUITEB: 6966 /* TODO */ 6967 sigma_dut_print(dut, DUT_MSG_ERROR, 6968 "SuiteB not supported"); 6969 break; 6970 case AP_WPA2_OWE: 6971 /* TODO */ 6972 sigma_dut_print(dut, DUT_MSG_ERROR, 6973 "OWE not supported"); 6974 break; 6975 case AP_WPA2_FT_EAP: 6976 case AP_WPA2_FT_PSK: 6977 case AP_WPA2_EAP_SHA256: 6978 case AP_WPA2_PSK_SHA256: 6979 case AP_WPA2_ENT_FT_EAP: 6980 case AP_OSEN: 6981 /* TODO */ 6982 send_resp(dut, conn, SIGMA_ERROR, 6983 "errorCode,Unsupported KeyMgnt value"); 6984 return 0; 6985 } 6986 6987 /* wifi0 settings in case of dual */ 6988 run_system(dut, "cfg -a AP_RADIO_ID=0"); 6989 run_system(dut, "cfg -a AP_PRIMARY_CH=6"); 6990 run_system(dut, "cfg -a AP_STARTMODE=dual"); 6991 run_system(dut, "cfg -a AP_CHMODE=11NGHT40PLUS"); 6992 run_system(dut, "cfg -a TX_CHAINMASK=7"); 6993 run_system(dut, "cfg -a RX_CHAINMASK=7"); 6994 } 6995 6996 switch (dut->ap_pmf) { 6997 case AP_PMF_DISABLED: 6998 snprintf(buf, sizeof(buf), "cfg -a AP_PMF=0"); 6999 run_system(dut, buf); 7000 break; 7001 case AP_PMF_OPTIONAL: 7002 snprintf(buf, sizeof(buf), "cfg -a AP_PMF=1"); 7003 run_system(dut, buf); 7004 break; 7005 case AP_PMF_REQUIRED: 7006 snprintf(buf, sizeof(buf), "cfg -a AP_PMF=2"); 7007 run_system(dut, buf); 7008 break; 7009 } 7010 if (dut->ap_add_sha256) { 7011 snprintf(buf, sizeof(buf), "cfg -a AP_WPA_SHA256=1"); 7012 run_system(dut, buf); 7013 } else { 7014 snprintf(buf, sizeof(buf), "cfg -r AP_WPA_SHA256"); 7015 run_system(dut, buf); 7016 } 7017 7018 if (dut->ap_hs2) 7019 run_system(dut, "cfg -a AP_HOTSPOT=1"); 7020 else 7021 run_system(dut, "cfg -r AP_HOTSPOT"); 7022 7023 if (dut->ap_interworking) { 7024 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_ANT=%d", 7025 dut->ap_access_net_type); 7026 run_system(dut, buf); 7027 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_INTERNET=%d", 7028 dut->ap_internet); 7029 run_system(dut, buf); 7030 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUEGROUP=%d", 7031 dut->ap_venue_group); 7032 run_system(dut, buf); 7033 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUETYPE=%d", 7034 dut->ap_venue_type); 7035 run_system(dut, buf); 7036 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=%s", 7037 dut->ap_hessid); 7038 run_system(dut, buf); 7039 7040 if (dut->ap_roaming_cons[0]) { 7041 char *second, *rc; 7042 rc = strdup(dut->ap_roaming_cons); 7043 if (rc == NULL) 7044 return 0; 7045 7046 second = strchr(rc, ';'); 7047 if (second) 7048 *second++ = '\0'; 7049 7050 snprintf(buf, sizeof(buf), 7051 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=%s", rc); 7052 run_system(dut, buf); 7053 7054 if (second) { 7055 snprintf(buf, sizeof(buf), 7056 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2" 7057 "=%s", second); 7058 run_system(dut, buf); 7059 } 7060 free(rc); 7061 } else { 7062 run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM"); 7063 run_system(dut, 7064 "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2"); 7065 } 7066 } else { 7067 run_system(dut, "cfg -r AP_HOTSPOT_ANT"); 7068 run_system(dut, "cfg -r AP_HOTSPOT_INTERNET"); 7069 run_system(dut, "cfg -r AP_HOTSPOT_VENUEGROUP"); 7070 run_system(dut, "cfg -r AP_HOTSPOT_VENUETYPE"); 7071 run_system(dut, "cfg -r AP_HOTSPOT_HESSID"); 7072 run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM"); 7073 run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2"); 7074 } 7075 7076 if (dut->ap_proxy_arp) 7077 run_system(dut, "cfg -a IEEE80211V_PROXYARP=1"); 7078 else 7079 run_system(dut, "cfg -a IEEE80211V_PROXYARP=0"); 7080 if (dut->ap_dgaf_disable) 7081 run_system(dut, "cfg -a AP_HOTSPOT_DISABLE_DGAF=1"); 7082 else 7083 run_system(dut, "cfg -r AP_HOTSPOT_DISABLE_DGAF"); 7084 7085 if (strlen(dut->ap_tag_ssid[0])) { 7086 snprintf(buf, sizeof(buf), 7087 "cfg -a AP_SSID_2=%s", dut->ap_tag_ssid[0]); 7088 run_system(dut, buf); 7089 7090 if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) { 7091 run_system(dut, "cfg -a AP_SECMODE_2=WPA"); 7092 run_system(dut, "cfg -a AP_SECFILE_2=OSEN"); 7093 7094 res = snprintf(buf, sizeof(buf), 7095 "cfg -a AP_AUTH_SERVER_2=%s", 7096 dut->ap2_radius_ipaddr); 7097 if (res < 0 || res >= sizeof(buf)) 7098 return ERROR_SEND_STATUS; 7099 run_system(dut, buf); 7100 7101 res = snprintf(buf, sizeof(buf), 7102 "cfg -a AP_AUTH_PORT_2=%d", 7103 dut->ap2_radius_port); 7104 if (res < 0 || res >= sizeof(buf)) 7105 return ERROR_SEND_STATUS; 7106 run_system(dut, buf); 7107 7108 res = snprintf(buf, sizeof(buf), 7109 "cfg -a AP_AUTH_SECRET_2=%s", 7110 dut->ap2_radius_password); 7111 if (res < 0 || res >= sizeof(buf)) 7112 return ERROR_SEND_STATUS; 7113 run_system(dut, buf); 7114 } else { 7115 run_system(dut, "cfg -a AP_SECMODE_2=None"); 7116 run_system(dut, "cfg -r AP_AUTH_SERVER_2"); 7117 run_system(dut, "cfg -r AP_AUTH_PORT_2"); 7118 run_system(dut, "cfg -r AP_AUTH_SECRET_2"); 7119 } 7120 7121 run_system(dut, "cfg -a AP_STARTMODE=multi"); 7122 } 7123 7124 run_system(dut, "cfg -c"); 7125 7126 sigma_dut_print(dut, DUT_MSG_INFO, "Starting AP"); 7127 if (system("apup") != 0) { 7128 /* to be debugged why apup returns error 7129 send_resp(dut, conn, SIGMA_ERROR, 7130 "errorCode,apup failed"); 7131 return 0; 7132 */ 7133 } 7134 sigma_dut_print(dut, DUT_MSG_INFO, "AP started"); 7135 7136 if (dut->ap_key_mgmt != AP_OPEN) { 7137 int res; 7138 /* allow some time for hostapd to start before returning 7139 * success */ 7140 usleep(500000); 7141 if (run_hostapd_cli(dut, "ping") != 0) { 7142 send_resp(dut, conn, SIGMA_ERROR, 7143 "errorCode,Failed to talk to hostapd"); 7144 return 0; 7145 } 7146 7147 if (dut->ap_hs2 && !dut->ap_anqpserver) { 7148 /* the cfg app doesn't like ";" in the variables */ 7149 res = ath_ap_append_hostapd_conf(dut); 7150 if (res < 0) 7151 return res; 7152 7153 /* wait for hostapd to be ready */ 7154 usleep(500000); 7155 if (run_hostapd_cli(dut, "ping") != 0) { 7156 send_resp(dut, conn, SIGMA_ERROR, 7157 "errorCode,Failed to talk to " 7158 "hostapd"); 7159 return 0; 7160 } 7161 } 7162 } 7163 7164 ath_ap_set_params(dut); 7165 7166 if (dut->ap_anqpserver) 7167 return cmd_ath_ap_anqpserver_start(dut); 7168 7169 if (dut->ap2_proxy_arp) 7170 run_iwpriv(dut, ifname, "proxy_arp 1"); 7171 7172 if (dut->ap_allow_vht_wep || dut->ap_allow_vht_tkip) 7173 run_iwpriv(dut, ifname, "htweptkip 1"); 7174 7175 return 1; 7176 } 7177 7178 7179 static int set_ebtables_proxy_arp(struct sigma_dut *dut, const char *chain, 7180 const char *ifname) 7181 { 7182 char buf[200]; 7183 7184 if (!chain || !ifname) 7185 return -2; 7186 7187 snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain); 7188 if (system(buf) != 0) { 7189 sigma_dut_print(dut, DUT_MSG_ERROR, 7190 "Failed to set ebtables rules, RULE-1, %s", 7191 chain); 7192 return -2; 7193 } 7194 7195 snprintf(buf, sizeof(buf), 7196 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP", 7197 chain, ifname); 7198 if (system(buf) != 0) { 7199 sigma_dut_print(dut, DUT_MSG_ERROR, 7200 "Failed to set ebtables rules, RULE-2, %s", 7201 chain); 7202 return -2; 7203 } 7204 7205 snprintf(buf, sizeof(buf), 7206 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-solicitation -o %s -j DROP", 7207 chain, ifname); 7208 if (system(buf) != 0) { 7209 sigma_dut_print(dut, DUT_MSG_ERROR, 7210 "Failed to set ebtables rules, RULE-3, %s", 7211 chain); 7212 return -2; 7213 } 7214 7215 snprintf(buf, sizeof(buf), 7216 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-advertisement -o %s -j DROP", 7217 chain, ifname); 7218 if (system(buf) != 0) { 7219 sigma_dut_print(dut, DUT_MSG_ERROR, 7220 "Failed to set ebtables rules, RULE-4, %s", 7221 chain); 7222 return -2; 7223 } 7224 7225 return 0; 7226 } 7227 7228 7229 static int set_ebtables_disable_dgaf(struct sigma_dut *dut, 7230 const char *chain, 7231 const char *ifname) 7232 { 7233 char buf[200]; 7234 7235 if (!chain || !ifname) 7236 return -2; 7237 7238 snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain); 7239 if (system(buf) != 0) { 7240 sigma_dut_print(dut, DUT_MSG_ERROR, 7241 "Failed to set ebtables rules, RULE-5, %s", 7242 chain); 7243 return -2; 7244 } 7245 7246 snprintf(buf, sizeof(buf), 7247 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP", 7248 chain, ifname); 7249 if (system(buf) != 0) { 7250 sigma_dut_print(dut, DUT_MSG_ERROR, 7251 "Failed to set ebtables rules, RULE-6, %s", 7252 chain); 7253 return -2; 7254 } 7255 7256 snprintf(buf, sizeof(buf), 7257 "ebtables -A %s -p IPv4 -d Multicast -o %s -j DROP", 7258 chain, ifname); 7259 if (system(buf) != 0) { 7260 sigma_dut_print(dut, DUT_MSG_ERROR, 7261 "Failed to set ebtables rules, RULE-7, %s", 7262 chain); 7263 return -2; 7264 } 7265 7266 snprintf(buf, sizeof(buf), 7267 "ebtables -A %s -p IPv6 -d Multicast -o %s -j DROP", 7268 chain, ifname); 7269 if (system(buf) != 0) { 7270 sigma_dut_print(dut, DUT_MSG_ERROR, 7271 "Failed to set ebtables rules, RULE-8, %s", 7272 chain); 7273 return -2; 7274 } 7275 7276 return 0; 7277 } 7278 7279 7280 static void set_ebtables_forward_drop(struct sigma_dut *dut, 7281 const char *ifname, const char *ifname2) 7282 { 7283 char buf[128]; 7284 7285 snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP", 7286 ifname, ifname2); 7287 if (system(buf) != 0) 7288 sigma_dut_print(dut, DUT_MSG_ERROR, 7289 "Failed to set ebtables rule"); 7290 7291 snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP", 7292 ifname2, ifname); 7293 if (system(buf) != 0) 7294 sigma_dut_print(dut, DUT_MSG_ERROR, 7295 "Failed to set ebtables rule"); 7296 } 7297 7298 7299 static int check_channel(int channel) 7300 { 7301 int channel_list[] = { 36, 40, 44, 48, 52, 60, 64, 100, 104, 108, 112, 7302 116, 120, 124, 128, 132, 140, 144, 149, 153, 157, 7303 161, 165 }; 7304 int num_chan = sizeof(channel_list) / sizeof(int); 7305 int i; 7306 7307 for (i = 0; i < num_chan; i++) { 7308 if (channel == channel_list[i]) 7309 return i; 7310 } 7311 7312 return -1; 7313 } 7314 7315 7316 static int get_oper_centr_freq_seq_idx(int chwidth, int channel) 7317 { 7318 int ch_base; 7319 int period; 7320 7321 if (check_channel(channel) < 0) 7322 return -1; 7323 7324 if (channel >= 36 && channel <= 64) 7325 ch_base = 36; 7326 else if (channel >= 100 && channel <= 144) 7327 ch_base = 100; 7328 else 7329 ch_base = 149; 7330 7331 period = channel % ch_base * 5 / chwidth; 7332 return ch_base + period * chwidth / 5 + (chwidth - 20) / 10; 7333 } 7334 7335 7336 static int is_ht40plus_chan(int chan) 7337 { 7338 return chan == 36 || chan == 44 || chan == 52 || chan == 60 || 7339 chan == 100 || chan == 108 || chan == 116 || chan == 124 || 7340 chan == 132 || chan == 149 || chan == 157; 7341 } 7342 7343 7344 static int is_ht40minus_chan(int chan) 7345 { 7346 return chan == 40 || chan == 48 || chan == 56 || chan == 64 || 7347 chan == 104 || chan == 112 || chan == 120 || chan == 128 || 7348 chan == 136 || chan == 144 || chan == 153 || chan == 161; 7349 } 7350 7351 7352 static int get_5g_channel_freq(int chan) 7353 { 7354 return 5000 + chan * 5; 7355 } 7356 7357 7358 static const char * hostapd_cipher_name(enum ap_cipher cipher) 7359 { 7360 switch (cipher) { 7361 case AP_CCMP: 7362 return "CCMP"; 7363 case AP_TKIP: 7364 return "TKIP"; 7365 case AP_CCMP_TKIP: 7366 return "CCMP TKIP"; 7367 case AP_GCMP_256: 7368 return "GCMP-256"; 7369 case AP_GCMP_128: 7370 return "GCMP"; 7371 case AP_CCMP_256: 7372 return "CCMP-256"; 7373 case AP_CCMP_128_GCMP_256: 7374 return "CCMP GCMP-256"; 7375 default: 7376 return "UNKNOWN"; 7377 } 7378 } 7379 7380 7381 static const char * 7382 hostapd_group_mgmt_cipher_name(enum ap_group_mgmt_cipher cipher) 7383 { 7384 switch (cipher) { 7385 case AP_BIP_GMAC_256: 7386 return "BIP-GMAC-256"; 7387 case AP_BIP_CMAC_256: 7388 return "BIP-CMAC-256"; 7389 case AP_BIP_GMAC_128: 7390 return "BIP-GMAC-128"; 7391 case AP_BIP_CMAC_128: 7392 return "AES-128-CMAC"; 7393 default: 7394 return "UNKNOWN"; 7395 } 7396 } 7397 7398 7399 static int ap_set_60g_ese(struct sigma_dut *dut, int count, 7400 struct sigma_ese_alloc *allocs) 7401 { 7402 switch (get_driver_type(dut)) { 7403 #ifdef __linux__ 7404 case DRIVER_WIL6210: 7405 return wil6210_set_ese(dut, count, allocs); 7406 #endif /* __linux__ */ 7407 default: 7408 sigma_dut_print(dut, DUT_MSG_ERROR, 7409 "Unsupported ap_set_60g_ese with the current driver"); 7410 return -1; 7411 } 7412 } 7413 7414 7415 static int ap_set_force_mcs(struct sigma_dut *dut, int force, int mcs) 7416 { 7417 switch (get_driver_type(dut)) { 7418 #ifdef __linux__ 7419 case DRIVER_WIL6210: 7420 return wil6210_set_force_mcs(dut, force, mcs); 7421 #endif /* __linux__ */ 7422 default: 7423 sigma_dut_print(dut, DUT_MSG_ERROR, 7424 "Unsupported ap_set_force_mcs with the current driver"); 7425 return -1; 7426 } 7427 } 7428 7429 7430 enum sigma_cmd_result cmd_ap_config_commit(struct sigma_dut *dut, 7431 struct sigma_conn *conn, 7432 struct sigma_cmd *cmd) 7433 { 7434 /* const char *name = get_param(cmd, "NAME"); */ 7435 FILE *f; 7436 const char *ifname; 7437 char buf[500]; 7438 char path[100]; 7439 char ap_conf_path[100]; 7440 enum driver_type drv; 7441 const char *key_mgmt; 7442 #ifdef ANDROID 7443 struct group *gr; 7444 #endif /* ANDROID */ 7445 7446 drv = get_driver_type(dut); 7447 7448 if (dut->mode == SIGMA_MODE_STATION) { 7449 stop_sta_mode(dut); 7450 sleep(1); 7451 } 7452 7453 if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) { 7454 snprintf(buf, sizeof(buf), "ifconfig %s down", 7455 dut->sniffer_ifname); 7456 if (system(buf) != 0) { 7457 sigma_dut_print(dut, DUT_MSG_INFO, 7458 "Failed to run '%s'", buf); 7459 } 7460 snprintf(buf, sizeof(buf), "iw dev %s set type station", 7461 dut->sniffer_ifname); 7462 if (system(buf) != 0) { 7463 sigma_dut_print(dut, DUT_MSG_INFO, 7464 "Failed to run '%s'", buf); 7465 } 7466 } 7467 7468 dut->mode = SIGMA_MODE_AP; 7469 7470 if (drv == DRIVER_ATHEROS) 7471 return cmd_ath_ap_config_commit(dut, conn, cmd); 7472 if (drv == DRIVER_WCN) 7473 return cmd_wcn_ap_config_commit(dut, conn, cmd); 7474 if (drv == DRIVER_OPENWRT) 7475 return cmd_owrt_ap_config_commit(dut, conn, cmd); 7476 7477 concat_sigma_tmpdir(dut, "/sigma_dut-ap.conf", ap_conf_path, 7478 sizeof(ap_conf_path)); 7479 f = fopen(ap_conf_path, "w"); 7480 if (f == NULL) { 7481 sigma_dut_print(dut, DUT_MSG_ERROR, 7482 "%s: Failed to open sigma_dut-ap.conf", 7483 __func__); 7484 return -2; 7485 } 7486 7487 ifname = get_hostapd_ifname(dut); 7488 7489 switch (dut->ap_mode) { 7490 case AP_11g: 7491 case AP_11b: 7492 case AP_11ng: 7493 fprintf(f, "hw_mode=g\n"); 7494 break; 7495 case AP_11a: 7496 case AP_11na: 7497 case AP_11ac: 7498 fprintf(f, "hw_mode=a\n"); 7499 break; 7500 case AP_11ad: 7501 fprintf(f, "hw_mode=ad\n"); 7502 break; 7503 case AP_11ax: 7504 if (dut->use_5g) 7505 fprintf(f, "hw_mode=a\n"); 7506 else 7507 fprintf(f, "hw_mode=g\n"); 7508 break; 7509 default: 7510 fclose(f); 7511 return -1; 7512 } 7513 7514 if (drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN) 7515 fprintf(f, "driver=nl80211\n"); 7516 7517 if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO || 7518 drv == DRIVER_LINUX_WCN) && 7519 (dut->ap_mode == AP_11ng || dut->ap_mode == AP_11na || 7520 (dut->ap_mode == AP_11ax && !dut->use_5g))) { 7521 int ht40plus = 0, ht40minus = 0, tx_stbc = 0; 7522 7523 fprintf(f, "ieee80211n=1\n"); 7524 if (dut->ap_mode == AP_11ax) 7525 fprintf(f, "ieee80211ax=1\n"); 7526 if (dut->ap_mode == AP_11ng && 7527 (dut->ap_chwidth == AP_40 || 7528 (dut->ap_chwidth == AP_AUTO && 7529 dut->default_11ng_ap_chwidth == AP_40))) { 7530 if (dut->ap_channel >= 1 && dut->ap_channel <= 7) 7531 ht40plus = 1; 7532 else if (dut->ap_channel >= 8 && dut->ap_channel <= 11) 7533 ht40minus = 1; 7534 fprintf(f, "obss_interval=300\n"); 7535 } 7536 7537 /* configure ht_capab based on channel width */ 7538 if (dut->ap_mode == AP_11na && 7539 (dut->ap_chwidth == AP_40 || 7540 (dut->ap_chwidth == AP_AUTO && 7541 dut->default_11na_ap_chwidth == AP_40))) { 7542 if (is_ht40plus_chan(dut->ap_channel)) 7543 ht40plus = 1; 7544 else if (is_ht40minus_chan(dut->ap_channel)) 7545 ht40minus = 1; 7546 } 7547 7548 if (dut->ap_tx_stbc) 7549 tx_stbc = 1; 7550 7551 /* Overwrite the ht_capab with offset value if configured */ 7552 if (dut->ap_chwidth == AP_40 && 7553 dut->ap_chwidth_offset == SEC_CH_40ABOVE) { 7554 ht40plus = 1; 7555 ht40minus = 0; 7556 } else if (dut->ap_chwidth == AP_40 && 7557 dut->ap_chwidth_offset == SEC_CH_40BELOW) { 7558 ht40minus = 1; 7559 ht40plus = 0; 7560 } 7561 7562 fprintf(f, "ht_capab=%s%s%s\n", 7563 ht40plus ? "[HT40+]" : "", 7564 ht40minus ? "[HT40-]" : "", 7565 tx_stbc ? "[TX-STBC]" : ""); 7566 } 7567 7568 if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO || 7569 drv == DRIVER_LINUX_WCN) && 7570 (dut->ap_mode == AP_11ac || 7571 (dut->ap_mode == AP_11ax && dut->use_5g))) { 7572 int ht40plus = 0, ht40minus = 0; 7573 7574 fprintf(f, "ieee80211ac=1\n" 7575 "ieee80211n=1\n"); 7576 if (dut->ap_mode == AP_11ax) 7577 fprintf(f, "ieee80211ax=1\n"); 7578 7579 /* configure ht_capab based on channel width */ 7580 if (dut->ap_chwidth != AP_20) { 7581 if (is_ht40plus_chan(dut->ap_channel)) 7582 ht40plus = 1; 7583 else if (is_ht40minus_chan(dut->ap_channel)) 7584 ht40minus = 1; 7585 7586 fprintf(f, "ht_capab=%s%s\n", 7587 ht40plus ? "[HT40+]" : "", 7588 ht40minus ? "[HT40-]" : ""); 7589 } 7590 } 7591 7592 if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO || 7593 drv == DRIVER_LINUX_WCN) && 7594 (dut->ap_mode == AP_11ac || dut->ap_mode == AP_11na)) { 7595 if (dut->ap_countrycode[0]) { 7596 fprintf(f, "country_code=%s\n", dut->ap_countrycode); 7597 fprintf(f, "ieee80211d=1\n"); 7598 fprintf(f, "ieee80211h=1\n"); 7599 } 7600 } 7601 7602 if (drv == DRIVER_LINUX_WCN && dut->ap_mode == AP_11ax) { 7603 if (dut->ap_txBF) { 7604 fprintf(f, "he_su_beamformer=1\n"); 7605 fprintf(f, "he_su_beamformee=1\n"); 7606 if (dut->ap_mu_txBF) 7607 fprintf(f, "he_mu_beamformer=1\n"); 7608 } else { 7609 fprintf(f, "he_su_beamformer=0\n"); 7610 fprintf(f, "he_su_beamformee=0\n"); 7611 fprintf(f, "he_mu_beamformer=0\n"); 7612 } 7613 } 7614 7615 fprintf(f, "interface=%s\n", ifname); 7616 if (dut->bridge) 7617 fprintf(f, "bridge=%s\n", dut->bridge); 7618 fprintf(f, "channel=%d\n", dut->ap_channel); 7619 7620 if (sigma_hapd_ctrl) 7621 fprintf(f, "ctrl_interface=%s\n", sigma_hapd_ctrl); 7622 else 7623 fprintf(f, "ctrl_interface=/var/run/hostapd\n"); 7624 7625 if (dut->ap_ssid[0]) 7626 fprintf(f, "ssid=%s\n", dut->ap_ssid); 7627 else 7628 fprintf(f, "ssid=QCA AP OOB\n"); 7629 if (dut->ap_bcnint) 7630 fprintf(f, "beacon_int=%d\n", dut->ap_bcnint); 7631 if (dut->ap_start_disabled) 7632 fprintf(f, "start_disabled=1\n"); 7633 7634 if (dut->ap_akm_values) { 7635 struct { 7636 int akm; 7637 const char *str; 7638 } akms[] = { 7639 { AKM_WPA_EAP, "WPA-EAP" }, 7640 { AKM_WPA_PSK, "WPA-PSK" }, 7641 { AKM_FT_EAP, "FT-EAP" }, 7642 { AKM_FT_PSK, "FT-PSK" }, 7643 { AKM_EAP_SHA256, "WPA-EAP-SHA256" }, 7644 { AKM_PSK_SHA256, "WPA-PSK-SHA256" }, 7645 { AKM_SAE, "SAE" }, 7646 { AKM_FT_SAE, "FT-SAE" }, 7647 { AKM_SUITE_B, "WPA-EAP-SUITE-B-192" }, 7648 { AKM_FT_SUITE_B, "FT-EAP-SHA384" }, 7649 { AKM_FILS_SHA256, "FILS-SHA256" }, 7650 { AKM_FILS_SHA384, "FILS-SHA384" }, 7651 { AKM_FT_FILS_SHA256, "FT-FILS-SHA256" }, 7652 { AKM_FT_FILS_SHA384, "FT-FILS-SHA384" }, 7653 }; 7654 int first = 1; 7655 unsigned int i; 7656 7657 fprintf(f, "wpa_key_mgmt="); 7658 for (i = 0; i < ARRAY_SIZE(akms); i++) { 7659 if (dut->ap_akm_values & (1 << akms[i].akm)) { 7660 fprintf(f, "%s%s", first ? "" : " ", 7661 akms[i].str); 7662 first = 0; 7663 } 7664 } 7665 fprintf(f, "\n"); 7666 /* TODO: mixed mode and WPAv1 only */ 7667 fprintf(f, "wpa=2\n"); 7668 fprintf(f, "wpa_pairwise=%s\n", 7669 hostapd_cipher_name(dut->ap_cipher)); 7670 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET) 7671 fprintf(f, "group_cipher=%s\n", 7672 hostapd_cipher_name(dut->ap_group_cipher)); 7673 if ((dut->ap_akm_values & 7674 ((1 << AKM_SAE) | (1 << AKM_FT_SAE))) && 7675 !(dut->ap_akm_values & 7676 ((1 << AKM_WPA_PSK) | (1 << AKM_FT_PSK))) && 7677 dut->ap_passphrase[0]) 7678 fprintf(f, "sae_password=%s\n", dut->ap_passphrase); 7679 else if (!dut->ap_passphrase[0] && dut->ap_psk[0]) 7680 fprintf(f, "wpa_psk=%s", dut->ap_psk); 7681 else if (dut->ap_passphrase[0]) 7682 fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase); 7683 if (dut->ap_akm_values & ((1 << AKM_WPA_EAP) | 7684 (1 << AKM_FT_EAP) | 7685 (1 << AKM_EAP_SHA256) | 7686 (1 << AKM_SUITE_B) | 7687 (1 << AKM_FT_SUITE_B) | 7688 (1 << AKM_FILS_SHA256) | 7689 (1 << AKM_FILS_SHA384) | 7690 (1 << AKM_FT_FILS_SHA256) | 7691 (1 << AKM_FT_FILS_SHA384))) { 7692 fprintf(f, "ieee8021x=1\n"); 7693 fprintf(f, "auth_server_addr=%s\n", 7694 dut->ap_radius_ipaddr); 7695 if (dut->ap_radius_port) 7696 fprintf(f, "auth_server_port=%d\n", 7697 dut->ap_radius_port); 7698 fprintf(f, "auth_server_shared_secret=%s\n", 7699 dut->ap_radius_password); 7700 } 7701 goto skip_key_mgmt; 7702 } 7703 7704 switch (dut->ap_key_mgmt) { 7705 case AP_OPEN: 7706 if (dut->ap_cipher == AP_WEP) 7707 fprintf(f, "wep_key0=%s\n", dut->ap_wepkey); 7708 break; 7709 case AP_WPA2_PSK: 7710 case AP_WPA2_PSK_MIXED: 7711 case AP_WPA_PSK: 7712 case AP_WPA2_SAE: 7713 case AP_WPA2_PSK_SAE: 7714 case AP_WPA2_PSK_SHA256: 7715 case AP_WPA2_FT_PSK: 7716 if (dut->ap_key_mgmt == AP_WPA2_PSK || 7717 dut->ap_key_mgmt == AP_WPA2_SAE || 7718 dut->ap_key_mgmt == AP_WPA2_PSK_SAE || 7719 dut->ap_key_mgmt == AP_WPA2_PSK_SHA256 || 7720 dut->ap_key_mgmt == AP_WPA2_FT_PSK) 7721 fprintf(f, "wpa=2\n"); 7722 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) 7723 fprintf(f, "wpa=3\n"); 7724 else 7725 fprintf(f, "wpa=1\n"); 7726 if (dut->ap_key_mgmt == AP_WPA2_SAE) 7727 key_mgmt = "SAE"; 7728 else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE) 7729 key_mgmt = "WPA-PSK SAE"; 7730 else 7731 key_mgmt = "WPA-PSK"; 7732 switch (dut->ap_pmf) { 7733 case AP_PMF_DISABLED: 7734 fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt, 7735 dut->ap_add_sha256 ? " WPA-PSK-SHA256" : ""); 7736 break; 7737 case AP_PMF_OPTIONAL: 7738 fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt, 7739 dut->ap_add_sha256 ? " WPA-PSK-SHA256" : ""); 7740 break; 7741 case AP_PMF_REQUIRED: 7742 if (dut->ap_key_mgmt == AP_WPA2_SAE) 7743 key_mgmt = "SAE"; 7744 else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE) 7745 key_mgmt = "WPA-PSK-SHA256 SAE"; 7746 else 7747 key_mgmt = "WPA-PSK-SHA256"; 7748 fprintf(f, "wpa_key_mgmt=%s\n", key_mgmt); 7749 break; 7750 } 7751 if (dut->ap_key_mgmt == AP_WPA2_PSK_SHA256) 7752 fprintf(f, "wpa_key_mgmt=WPA-PSK-SHA256\n"); 7753 else if (dut->ap_key_mgmt == AP_WPA2_FT_PSK) 7754 fprintf(f, "wpa_key_mgmt=FT-PSK\n"); 7755 fprintf(f, "wpa_pairwise=%s\n", 7756 hostapd_cipher_name(dut->ap_cipher)); 7757 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET) 7758 fprintf(f, "group_cipher=%s\n", 7759 hostapd_cipher_name(dut->ap_group_cipher)); 7760 if (dut->ap_key_mgmt == AP_WPA2_SAE) 7761 fprintf(f, "sae_password=%s\n", dut->ap_passphrase); 7762 else if (!dut->ap_passphrase[0] && dut->ap_psk[0]) 7763 fprintf(f, "wpa_psk=%s", dut->ap_psk); 7764 else 7765 fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase); 7766 break; 7767 case AP_WPA2_EAP: 7768 case AP_WPA2_EAP_MIXED: 7769 case AP_WPA_EAP: 7770 case AP_WPA2_EAP_OSEN: 7771 case AP_WPA2_EAP_SHA256: 7772 case AP_WPA2_FT_EAP: 7773 case AP_WPA2_ENT_FT_EAP: 7774 fprintf(f, "ieee8021x=1\n"); 7775 if (dut->ap_key_mgmt == AP_WPA2_EAP || 7776 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN || 7777 dut->ap_key_mgmt == AP_WPA2_EAP_SHA256 || 7778 dut->ap_key_mgmt == AP_WPA2_FT_EAP || 7779 dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP) 7780 fprintf(f, "wpa=2\n"); 7781 else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) 7782 fprintf(f, "wpa=3\n"); 7783 else 7784 fprintf(f, "wpa=1\n"); 7785 switch (dut->ap_pmf) { 7786 case AP_PMF_DISABLED: 7787 fprintf(f, "wpa_key_mgmt=WPA-EAP%s\n", 7788 dut->ap_add_sha256 ? " WPA-EAP-SHA256" : ""); 7789 break; 7790 case AP_PMF_OPTIONAL: 7791 fprintf(f, "wpa_key_mgmt=WPA-EAP%s%s\n", 7792 dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "", 7793 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" : 7794 ""); 7795 break; 7796 case AP_PMF_REQUIRED: 7797 fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256%s\n", 7798 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" : 7799 ""); 7800 break; 7801 } 7802 if (dut->ap_key_mgmt == AP_WPA2_EAP_SHA256) 7803 fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256\n"); 7804 else if (dut->ap_key_mgmt == AP_WPA2_FT_EAP) 7805 fprintf(f, "wpa_key_mgmt=FT-EAP\n"); 7806 else if (dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP) 7807 fprintf(f, "wpa_key_mgmt=FT-EAP WPA-EAP\n"); 7808 fprintf(f, "wpa_pairwise=%s\n", 7809 hostapd_cipher_name(dut->ap_cipher)); 7810 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET) 7811 fprintf(f, "group_cipher=%s\n", 7812 hostapd_cipher_name(dut->ap_group_cipher)); 7813 fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr); 7814 if (dut->ap_radius_port) 7815 fprintf(f, "auth_server_port=%d\n", 7816 dut->ap_radius_port); 7817 fprintf(f, "auth_server_shared_secret=%s\n", 7818 dut->ap_radius_password); 7819 if (dut->program == PROGRAM_HS2_R3) { 7820 fprintf(f, "radius_das_port=3799\n"); 7821 fprintf(f, "radius_das_client=0.0.0.0 %s\n", 7822 dut->ap_radius_password); 7823 fprintf(f, "radius_das_require_event_timestamp=1\n"); 7824 } 7825 break; 7826 case AP_SUITEB: 7827 fprintf(f, "ieee8021x=1\n"); 7828 fprintf(f, "wpa=2\n"); 7829 fprintf(f, "wpa_key_mgmt=WPA-EAP-SUITE-B-192\n"); 7830 fprintf(f, "wpa_pairwise=%s\n", 7831 hostapd_cipher_name(dut->ap_cipher)); 7832 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET) 7833 fprintf(f, "group_cipher=%s\n", 7834 hostapd_cipher_name(dut->ap_group_cipher)); 7835 if (dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET) 7836 fprintf(f, "group_mgmt_cipher=%s\n", 7837 hostapd_group_mgmt_cipher_name( 7838 dut->ap_group_mgmt_cipher)); 7839 fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr); 7840 if (dut->ap_radius_port) 7841 fprintf(f, "auth_server_port=%d\n", 7842 dut->ap_radius_port); 7843 fprintf(f, "auth_server_shared_secret=%s\n", 7844 dut->ap_radius_password); 7845 break; 7846 case AP_WPA2_OWE: 7847 fprintf(f, "wpa=2\n"); 7848 fprintf(f, "wpa_key_mgmt=OWE\n"); 7849 fprintf(f, "rsn_pairwise=%s\n", 7850 hostapd_cipher_name(dut->ap_cipher)); 7851 if (dut->ap_sae_groups) { 7852 fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups); 7853 if (dut->owe_ptk_workaround) 7854 fprintf(f, "owe_ptk_workaround=1\n"); 7855 } 7856 break; 7857 case AP_OSEN: 7858 fprintf(f, "osen=1\n"); 7859 fprintf(f, "disable_dgaf=1\n"); 7860 fprintf(f, "wpa_pairwise=%s\n", 7861 hostapd_cipher_name(dut->ap_cipher)); 7862 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET) 7863 fprintf(f, "group_cipher=%s\n", 7864 hostapd_cipher_name(dut->ap_group_cipher)); 7865 fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr); 7866 if (dut->ap_radius_port) 7867 fprintf(f, "auth_server_port=%d\n", 7868 dut->ap_radius_port); 7869 fprintf(f, "auth_server_shared_secret=%s\n", 7870 dut->ap_radius_password); 7871 break; 7872 } 7873 skip_key_mgmt: 7874 7875 if (dut->ap_sae_passwords) { 7876 char *tmp, *pos, *end, *id; 7877 7878 tmp = strdup(dut->ap_sae_passwords); 7879 if (!tmp) { 7880 fclose(f); 7881 return ERROR_SEND_STATUS; 7882 } 7883 7884 pos = tmp; 7885 while (*pos) { 7886 end = strchr(pos, ';'); 7887 if (end) 7888 *end = '\0'; 7889 id = strchr(pos, ':'); 7890 if (id) 7891 *id++ = '\0'; 7892 7893 fprintf(f, "sae_password=%s%s%s\n", 7894 pos, id ? "|id=" : "", id ? id : ""); 7895 if (!end) 7896 break; 7897 pos = end + 1; 7898 } 7899 7900 free(tmp); 7901 } 7902 7903 if (dut->ap_rsn_preauth) 7904 fprintf(f, "rsn_preauth=1\n"); 7905 7906 if (dut->ap_pmksa && dut->ap_pmksa_caching) 7907 fprintf(f, "disable_pmksa_caching=1\n"); 7908 7909 if (dut->ap_beacon_prot) 7910 fprintf(f, "beacon_prot=1\n"); 7911 7912 if (dut->ap_transition_disable) 7913 fprintf(f, "transition_disable=0x%02x\n", 7914 dut->ap_transition_disable); 7915 7916 switch (dut->ap_pmf) { 7917 case AP_PMF_DISABLED: 7918 break; 7919 case AP_PMF_OPTIONAL: 7920 fprintf(f, "ieee80211w=1\n"); 7921 if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE || 7922 (dut->ap_akm_values & (AKM_SAE | AKM_WPA_PSK)) == 7923 (AKM_SAE | AKM_WPA_PSK)) 7924 fprintf(f, "sae_require_mfp=1\n"); 7925 break; 7926 case AP_PMF_REQUIRED: 7927 fprintf(f, "ieee80211w=2\n"); 7928 break; 7929 } 7930 7931 if (dut->ap_pmf != AP_PMF_DISABLED && 7932 dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET) 7933 fprintf(f, "group_mgmt_cipher=%s\n", 7934 hostapd_group_mgmt_cipher_name( 7935 dut->ap_group_mgmt_cipher)); 7936 7937 if (ap_ft_enabled(dut)) { 7938 unsigned char own_addr[ETH_ALEN]; 7939 7940 fprintf(f, "mobility_domain=%s\n", dut->ap_mobility_domain); 7941 fprintf(f, "ft_over_ds=%d\n", dut->ap_ft_ds == VALUE_ENABLED); 7942 if (get_hwaddr(ifname, own_addr) < 0) { 7943 memset(own_addr, 0, ETH_ALEN); 7944 own_addr[0] = 0x02; 7945 } 7946 fprintf(f, 7947 "nas_identifier=%02x%02x%02x%02x%02x%02x.nas.example.com\n", 7948 own_addr[0], own_addr[1], own_addr[2], 7949 own_addr[3], own_addr[4], own_addr[5]); 7950 fprintf(f, "r1_key_holder=%02x%02x%02x%02x%02x%02x\n", 7951 own_addr[0], own_addr[1], own_addr[2], 7952 own_addr[3], own_addr[4], own_addr[5]); 7953 fprintf(f, "ft_psk_generate_local=1\n"); 7954 fprintf(f, "pmk_r1_push=0\n"); 7955 fprintf(f, 7956 "r0kh=ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n"); 7957 fprintf(f, 7958 "r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n"); 7959 } 7960 7961 if (dut->rsne_override) 7962 fprintf(f, "own_ie_override=%s\n", dut->rsne_override); 7963 if (dut->rsnxe_override_eapol) 7964 fprintf(f, "rsnxe_override_eapol=%s\n", 7965 dut->rsnxe_override_eapol); 7966 7967 if (dut->sae_commit_override) 7968 fprintf(f, "sae_commit_override=%s\n", 7969 dut->sae_commit_override); 7970 7971 if (dut->ap_sae_groups) 7972 fprintf(f, "sae_groups=%s\n", dut->ap_sae_groups); 7973 7974 if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) { 7975 const char *sae_pwe = NULL; 7976 7977 if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut)) 7978 sae_pwe = "3"; 7979 else if (dut->sae_pwe == SAE_PWE_LOOP) 7980 sae_pwe = "0"; 7981 else if (dut->sae_pwe == SAE_PWE_H2E) 7982 sae_pwe = "1"; 7983 else if (dut->sae_h2e_default) 7984 sae_pwe = "2"; 7985 if (sae_pwe) 7986 fprintf(f, "sae_pwe=%s\n", sae_pwe); 7987 } 7988 7989 if (dut->sae_anti_clogging_threshold >= 0) 7990 fprintf(f, "sae_anti_clogging_threshold=%d\n", 7991 dut->sae_anti_clogging_threshold); 7992 if (dut->sae_reflection) 7993 fprintf(f, "sae_reflection_attack=1\n"); 7994 if (dut->sae_confirm_immediate) 7995 fprintf(f, "sae_confirm_immediate=2\n"); 7996 7997 if (dut->ap_p2p_mgmt) 7998 fprintf(f, "manage_p2p=1\n"); 7999 8000 if (dut->ap_tdls_prohibit || dut->ap_l2tif) 8001 fprintf(f, "tdls_prohibit=1\n"); 8002 if (dut->ap_tdls_prohibit_chswitch || dut->ap_l2tif) 8003 fprintf(f, "tdls_prohibit_chan_switch=1\n"); 8004 if (dut->ap_p2p_cross_connect >= 0) { 8005 fprintf(f, "manage_p2p=1\n" 8006 "allow_cross_connection=%d\n", 8007 dut->ap_p2p_cross_connect); 8008 } 8009 8010 if (dut->ap_l2tif || dut->ap_proxy_arp || 8011 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN) { 8012 if (!dut->bridge) { 8013 sigma_dut_print(dut, DUT_MSG_ERROR, 8014 "Bridge must be configured. Run with -b <brname>."); 8015 fclose(f); 8016 return -2; 8017 } 8018 fprintf(f, "ap_isolate=1\n"); 8019 } 8020 8021 if (dut->ap_proxy_arp) 8022 fprintf(f, "proxy_arp=1\n"); 8023 8024 if (dut->ap_wme) 8025 fprintf(f, "wmm_enabled=1\n"); 8026 8027 if (dut->ap_wmmps == AP_WMMPS_ON) 8028 fprintf(f, "uapsd_advertisement_enabled=1\n"); 8029 8030 if (dut->ap_hs2) { 8031 if (dut->ap_bss_load) { 8032 char *bss_load; 8033 8034 switch (dut->ap_bss_load) { 8035 case -1: 8036 bss_load = "bss_load_update_period=10"; 8037 break; 8038 case 1: 8039 /* STA count: 1, CU: 50, AAC: 65535 */ 8040 bss_load = "bss_load_test=1:50:65535"; 8041 break; 8042 case 2: 8043 /* STA count: 1, CU: 200, AAC: 65535 */ 8044 bss_load = "bss_load_test=1:200:65535"; 8045 break; 8046 case 3: 8047 /* STA count: 1, CU: 75, AAC: 65535 */ 8048 bss_load = "bss_load_test=1:75:65535"; 8049 break; 8050 default: 8051 bss_load = NULL; 8052 break; 8053 } 8054 8055 if (!bss_load) { 8056 fclose(f); 8057 return -2; 8058 } 8059 fprintf(f, "%s\n", bss_load); 8060 } 8061 8062 if (append_hostapd_conf_hs2(dut, f)) { 8063 fclose(f); 8064 return -2; 8065 } 8066 } 8067 8068 if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) { 8069 fclose(f); 8070 return -2; 8071 } 8072 8073 if (dut->ap_hs2 && strlen(dut->ap_tag_ssid[0])) { 8074 unsigned char bssid[6]; 8075 char ifname2[50]; 8076 8077 if (get_hwaddr(ifname, bssid)) { 8078 fclose(f); 8079 return -2; 8080 } 8081 if (bssid[0] & 0x02) 8082 bssid[5] ^= 0x01; 8083 else 8084 bssid[0] |= 0x02; 8085 8086 snprintf(ifname2, sizeof(ifname2), "%s_1", ifname); 8087 fprintf(f, "bss=%s\n", ifname2); 8088 fprintf(f, "ssid=%s\n", dut->ap_tag_ssid[0]); 8089 if (dut->bridge) 8090 fprintf(f, "bridge=%s\n", dut->bridge); 8091 8092 if (drv == DRIVER_LINUX_WCN) 8093 fprintf(f, "use_driver_iface_addr=1\n"); 8094 else 8095 fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", 8096 bssid[0], bssid[1], bssid[2], bssid[3], 8097 bssid[4], bssid[5]); 8098 8099 if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) { 8100 fprintf(f, "osen=1\n"); 8101 /* Disable DGAF for OSEN BSS */ 8102 fprintf(f, "disable_dgaf=1\n"); 8103 fprintf(f, "ap_isolate=1\n"); 8104 if (strlen(dut->ap2_radius_ipaddr)) 8105 fprintf(f, "auth_server_addr=%s\n", 8106 dut->ap2_radius_ipaddr); 8107 if (dut->ap2_radius_port) 8108 fprintf(f, "auth_server_port=%d\n", 8109 dut->ap2_radius_port); 8110 if (strlen(dut->ap2_radius_password)) 8111 fprintf(f, "auth_server_shared_secret=%s\n", 8112 dut->ap2_radius_password); 8113 8114 set_ebtables_forward_drop(dut, ifname, ifname2); 8115 } else if (dut->ap2_osu) { 8116 fprintf(f, "ap_isolate=1\n"); 8117 set_ebtables_forward_drop(dut, ifname, ifname2); 8118 } 8119 8120 if (dut->ap2_proxy_arp) { 8121 if (!dut->bridge) { 8122 sigma_dut_print(dut, DUT_MSG_ERROR, 8123 "Bridge must be configured. Run with -b <brname>."); 8124 fclose(f); 8125 return -2; 8126 } 8127 fprintf(f, "ap_isolate=1\n"); 8128 fprintf(f, "proxy_arp=1\n"); 8129 8130 if (set_ebtables_proxy_arp(dut, "FORWARD", ifname2) || 8131 set_ebtables_proxy_arp(dut, "OUTPUT", ifname2)) { 8132 fclose(f); 8133 return -2; 8134 } 8135 8136 } 8137 } 8138 8139 if (dut->program == PROGRAM_WPS) { 8140 /* 60G WPS tests requires wps_state of 2 (configured) */ 8141 int wps_state = is_60g_sigma_dut(dut) ? 2 : 1; 8142 8143 fprintf(f, "eap_server=1\n" 8144 "wps_state=%d\n" 8145 "device_name=QCA AP\n" 8146 "manufacturer=QCA\n" 8147 "device_type=6-0050F204-1\n" 8148 "config_methods=label virtual_display %s" 8149 "virtual_push_button keypad%s\n" 8150 "ap_pin=12345670\n" 8151 "friendly_name=QCA Access Point\n" 8152 "upnp_iface=%s\n", 8153 wps_state, 8154 is_60g_sigma_dut(dut) ? "physical_display " : "", 8155 dut->ap_wpsnfc ? " nfc_interface ext_nfc_token" : "", 8156 dut->bridge ? dut->bridge : ifname); 8157 if (dut->wsc_fragment) { 8158 fprintf(f, "device_name=%s\n" 8159 "manufacturer=%s\n" 8160 "model_name=%s\n" 8161 "model_number=%s\n" 8162 "serial_number=%s\n", 8163 WPS_LONG_DEVICE_NAME, 8164 WPS_LONG_MANUFACTURER, 8165 WPS_LONG_MODEL_NAME, 8166 WPS_LONG_MODEL_NUMBER, 8167 WPS_LONG_SERIAL_NUMBER); 8168 } else { 8169 fprintf(f, "device_name=QCA AP\n" 8170 "manufacturer=QCA\n"); 8171 } 8172 if (dut->eap_fragment) 8173 fprintf(f, "fragment_size=128\n"); 8174 } 8175 8176 if (dut->ap_dpp_conf_addr && dut->ap_dpp_conf_pkhash) 8177 fprintf(f, "dpp_controller=ipaddr=%s pkhash=%s\n", 8178 dut->ap_dpp_conf_addr, dut->ap_dpp_conf_pkhash); 8179 8180 if (dut->ap_he_rtsthrshld == VALUE_ENABLED) 8181 fprintf(f, "he_rts_threshold=512\n"); 8182 else if (dut->ap_he_rtsthrshld == VALUE_DISABLED) 8183 fprintf(f, "he_rts_threshold=1024\n"); 8184 8185 if ((dut->program == PROGRAM_VHT) || 8186 (dut->program == PROGRAM_HE && dut->use_5g)) { 8187 int vht_oper_centr_freq_idx; 8188 8189 if (check_channel(dut->ap_channel) < 0) { 8190 send_resp(dut, conn, SIGMA_INVALID, 8191 "errorCode,Invalid channel"); 8192 fclose(f); 8193 return 0; 8194 } 8195 8196 switch (dut->ap_chwidth) { 8197 case AP_20: 8198 dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH; 8199 vht_oper_centr_freq_idx = 8200 get_oper_centr_freq_seq_idx(20, 8201 dut->ap_channel); 8202 break; 8203 case AP_40: 8204 dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH; 8205 vht_oper_centr_freq_idx = 8206 get_oper_centr_freq_seq_idx(40, 8207 dut->ap_channel); 8208 break; 8209 case AP_80: 8210 dut->ap_vht_chwidth = AP_80_VHT_OPER_CHWIDTH; 8211 vht_oper_centr_freq_idx = 8212 get_oper_centr_freq_seq_idx(80, 8213 dut->ap_channel); 8214 break; 8215 case AP_160: 8216 dut->ap_vht_chwidth = AP_160_VHT_OPER_CHWIDTH; 8217 vht_oper_centr_freq_idx = 8218 get_oper_centr_freq_seq_idx(160, 8219 dut->ap_channel); 8220 break; 8221 default: 8222 dut->ap_vht_chwidth = VHT_DEFAULT_OPER_CHWIDTH; 8223 vht_oper_centr_freq_idx = 8224 get_oper_centr_freq_seq_idx(80, 8225 dut->ap_channel); 8226 break; 8227 } 8228 fprintf(f, "vht_oper_centr_freq_seg0_idx=%d\n", 8229 vht_oper_centr_freq_idx); 8230 fprintf(f, "vht_oper_chwidth=%d\n", dut->ap_vht_chwidth); 8231 if (dut->ap_mode == AP_11ax) { 8232 fprintf(f, "he_oper_chwidth=%d\n", dut->ap_vht_chwidth); 8233 fprintf(f, "he_oper_centr_freq_seg0_idx=%d\n", 8234 vht_oper_centr_freq_idx); 8235 } 8236 8237 if (dut->ap_sgi80 || dut->ap_txBF || 8238 dut->ap_ldpc != VALUE_NOT_SET || 8239 dut->ap_tx_stbc || dut->ap_mu_txBF) { 8240 fprintf(f, "vht_capab=%s%s%s%s%s\n", 8241 dut->ap_sgi80 ? "[SHORT-GI-80]" : "", 8242 dut->ap_txBF ? 8243 "[SU-BEAMFORMER][SU-BEAMFORMEE][BF-ANTENNA-2][SOUNDING-DIMENSION-2]" : "", 8244 (dut->ap_ldpc == VALUE_ENABLED) ? 8245 "[RXLDPC]" : "", 8246 dut->ap_tx_stbc ? "[TX-STBC-2BY1]" : "", 8247 dut->ap_mu_txBF ? "[MU-BEAMFORMER]" : ""); 8248 } 8249 } 8250 8251 if (dut->ap_key_mgmt == AP_WPA2_OWE && dut->ap_tag_ssid[0][0] && 8252 dut->ap_tag_key_mgmt[0] == AP2_OPEN) { 8253 /* OWE transition mode */ 8254 unsigned char bssid[6]; 8255 char ifname2[50]; 8256 unsigned long val; 8257 FILE *f2; 8258 8259 snprintf(ifname2, sizeof(ifname2), "%s_1", ifname); 8260 8261 fprintf(f, "owe_transition_ifname=%s\n", ifname2); 8262 val = 0x12345678; /* default to something */ 8263 f2 = fopen("/dev/urandom", "r"); 8264 if (f2) { 8265 if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) { 8266 sigma_dut_print(dut, DUT_MSG_ERROR, 8267 "Could not read /dev/urandom"); 8268 } 8269 fclose(f2); 8270 } 8271 fprintf(f, "ssid=owe-%lx\n", val); 8272 fprintf(f, "ignore_broadcast_ssid=1\n"); 8273 8274 if (get_hwaddr(ifname, bssid)) { 8275 fclose(f); 8276 return -2; 8277 } 8278 if (bssid[0] & 0x02) 8279 bssid[5] ^= 0x01; 8280 else 8281 bssid[0] |= 0x02; 8282 8283 fprintf(f, "bss=%s\n", ifname2); 8284 fprintf(f, "ssid=%s\n", dut->ap_ssid); 8285 if (dut->bridge) 8286 fprintf(f, "bridge=%s\n", dut->bridge); 8287 if (drv == DRIVER_LINUX_WCN) 8288 fprintf(f, "use_driver_iface_addr=1\n"); 8289 else 8290 fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", 8291 bssid[0], bssid[1], bssid[2], bssid[3], 8292 bssid[4], bssid[5]); 8293 fprintf(f, "owe_transition_ifname=%s\n", ifname); 8294 } 8295 8296 if (dut->ap_key_mgmt == AP_OPEN && 8297 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) { 8298 /* OWE transition mode */ 8299 unsigned char bssid[6]; 8300 char ifname2[50]; 8301 unsigned long val; 8302 FILE *f2; 8303 8304 snprintf(ifname2, sizeof(ifname2), "%s_1", ifname); 8305 8306 fprintf(f, "owe_transition_ifname=%s\n", ifname2); 8307 fprintf(f, "ssid=%s\n", dut->ap_ssid); 8308 8309 if (get_hwaddr(ifname, bssid)) { 8310 fclose(f); 8311 return -2; 8312 } 8313 if (bssid[0] & 0x02) 8314 bssid[5] ^= 0x01; 8315 else 8316 bssid[0] |= 0x02; 8317 8318 fprintf(f, "bss=%s\n", ifname2); 8319 val = 0x12345678; /* default to something */ 8320 f2 = fopen("/dev/urandom", "r"); 8321 if (f2) { 8322 if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) { 8323 sigma_dut_print(dut, DUT_MSG_ERROR, 8324 "Could not read /dev/urandom"); 8325 } 8326 fclose(f2); 8327 } 8328 fprintf(f, "ssid=owe-%lx\n", val); 8329 if (dut->bridge) 8330 fprintf(f, "bridge=%s\n", dut->bridge); 8331 if (drv == DRIVER_LINUX_WCN) 8332 fprintf(f, "use_driver_iface_addr=1\n"); 8333 else 8334 fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", 8335 bssid[0], bssid[1], bssid[2], bssid[3], 8336 bssid[4], bssid[5]); 8337 fprintf(f, "owe_transition_ifname=%s\n", ifname); 8338 fprintf(f, "wpa=2\n"); 8339 fprintf(f, "wpa_key_mgmt=OWE\n"); 8340 fprintf(f, "rsn_pairwise=CCMP\n"); 8341 fprintf(f, "ieee80211w=2\n"); 8342 fprintf(f, "ignore_broadcast_ssid=1\n"); 8343 if (dut->ap_sae_groups) { 8344 fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups); 8345 if (dut->owe_ptk_workaround) 8346 fprintf(f, "owe_ptk_workaround=1\n"); 8347 } 8348 } 8349 8350 if (dut->program == PROGRAM_OCE) { 8351 fprintf(f, "oce=%d\n", 8352 dut->dev_role == DEVROLE_STA_CFON ? 2 : 1); 8353 } 8354 fclose(f); 8355 if (dut->use_hostapd_pid_file) 8356 kill_hostapd_process_pid(dut); 8357 #ifdef __QNXNTO__ 8358 if (system("slay hostapd") == 0) 8359 #else /* __QNXNTO__ */ 8360 if (!dut->use_hostapd_pid_file && 8361 (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 || 8362 system("killall hostapd") == 0)) 8363 #endif /* __QNXNTO__ */ 8364 { 8365 int i; 8366 /* Wait some time to allow hostapd to complete cleanup before 8367 * starting a new process */ 8368 for (i = 0; i < 10; i++) { 8369 usleep(500000); 8370 #ifdef __QNXNTO__ 8371 if (system("pidin | grep hostapd") != 0) 8372 break; 8373 #else /* __QNXNTO__ */ 8374 if (system("pidof hostapd") != 0) 8375 break; 8376 #endif /* __QNXNTO__ */ 8377 } 8378 } 8379 dut->hostapd_running = 0; 8380 8381 #ifdef ANDROID 8382 /* Set proper conf file permissions so that hostapd process 8383 * can access it. 8384 */ 8385 if (chmod(ap_conf_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0) 8386 sigma_dut_print(dut, DUT_MSG_ERROR, 8387 "Error changing permissions"); 8388 8389 gr = getgrnam("wifi"); 8390 if (!gr || chown(ap_conf_path, -1, gr->gr_gid) < 0) 8391 sigma_dut_print(dut, DUT_MSG_ERROR, "Error changing groupid"); 8392 #endif /* ANDROID */ 8393 8394 f = fopen(ap_conf_path, "r"); 8395 if (f) { 8396 size_t len; 8397 8398 len = fread(buf, 1, sizeof(buf), f); 8399 fclose(f); 8400 if (len >= sizeof(buf)) 8401 len = sizeof(buf) - 1; 8402 buf[len] = '\0'; 8403 sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd debug log:\n%s", 8404 buf); 8405 } 8406 8407 if (drv == DRIVER_QNXNTO) { 8408 snprintf(buf, sizeof(buf), 8409 "hostapd -B %s%s%s %s%s %s/sigma_dut-ap.conf", 8410 dut->hostapd_debug_log ? "-dddKt " : "", 8411 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ? 8412 "-f " : "", 8413 dut->hostapd_debug_log ? dut->hostapd_debug_log : "", 8414 dut->hostapd_entropy_log ? " -e" : "", 8415 dut->hostapd_entropy_log ? dut->hostapd_entropy_log : 8416 "", 8417 dut->sigma_tmpdir); 8418 } else { 8419 /* 8420 * It looks like a monitor interface can cause some issues for 8421 * beaconing, so remove it (if injection was used) before 8422 * starting hostapd. 8423 */ 8424 if (if_nametoindex("sigmadut") > 0 && 8425 system("iw dev sigmadut del") != 0) 8426 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove " 8427 "monitor interface"); 8428 8429 snprintf(path, sizeof(path), "%shostapd", 8430 file_exists("hostapd") ? "./" : ""); 8431 snprintf(buf, sizeof(buf), 8432 "%s -B%s%s%s%s%s%s %s/sigma_dut-ap.conf", 8433 dut->hostapd_bin ? dut->hostapd_bin : path, 8434 dut->hostapd_debug_log ? " -dddKt" : "", 8435 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ? 8436 " -f " : "", 8437 dut->hostapd_debug_log ? dut->hostapd_debug_log : "", 8438 dut->hostapd_entropy_log ? " -e" : "", 8439 dut->hostapd_entropy_log ? dut->hostapd_entropy_log : 8440 "", 8441 dut->use_hostapd_pid_file ? 8442 " -P " SIGMA_DUT_HOSTAPD_PID_FILE : "", 8443 dut->sigma_tmpdir); 8444 } 8445 8446 sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd command: %s", buf); 8447 if (system(buf) != 0) { 8448 send_resp(dut, conn, SIGMA_ERROR, 8449 "errorCode,Failed to start hostapd"); 8450 return 0; 8451 } 8452 8453 /* allow some time for hostapd to start before returning success */ 8454 usleep(500000); 8455 if (run_hostapd_cli(dut, "ping") != 0) { 8456 send_resp(dut, conn, SIGMA_ERROR, 8457 "errorCode,Failed to talk to hostapd"); 8458 return 0; 8459 } 8460 8461 if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) { 8462 int buf_size; 8463 8464 if (dut->ap_ba_bufsize == BA_BUFSIZE_256) 8465 buf_size = 256; 8466 else 8467 buf_size = 64; 8468 8469 if ((drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) && 8470 sta_set_addba_buf_size(dut, ifname, buf_size)) { 8471 send_resp(dut, conn, SIGMA_ERROR, 8472 "ErrorCode,set_addba_buf_size failed"); 8473 return STATUS_SENT_ERROR; 8474 } 8475 8476 sigma_dut_print(dut, DUT_MSG_INFO, 8477 "setting addba buf_size=%d", buf_size); 8478 } 8479 8480 if (drv == DRIVER_LINUX_WCN) { 8481 const char *ifname_ptr = ifname; 8482 8483 if ((dut->ap_key_mgmt == AP_OPEN && 8484 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) || 8485 (dut->ap_key_mgmt == AP_WPA2_OWE && 8486 dut->ap_tag_ssid[0][0] && 8487 dut->ap_tag_key_mgmt[0] == AP2_OPEN)) { 8488 /* OWE transition mode */ 8489 if (dut->bridge) 8490 ifname_ptr = dut->bridge; 8491 } 8492 8493 sigma_dut_print(dut, DUT_MSG_INFO, 8494 "setting ip addr %s mask %s ifname %s", 8495 ap_inet_addr, ap_inet_mask, ifname_ptr); 8496 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up", 8497 ifname_ptr, ap_inet_addr, ap_inet_mask); 8498 if (system(buf) != 0) { 8499 sigma_dut_print(dut, DUT_MSG_ERROR, 8500 "Failed to initialize the interface"); 8501 return -1; 8502 } 8503 } 8504 8505 /* Configure the driver with LDPC setting for AP mode as a new vdev is 8506 * created when hostapd is started. 8507 */ 8508 if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) 8509 wcn_config_ap_ldpc(dut, ifname); 8510 8511 if (dut->ap_l2tif) { 8512 snprintf(path, sizeof(path), 8513 "/sys/class/net/%s/brport/hairpin_mode", 8514 ifname); 8515 if (!file_exists(path)) { 8516 sigma_dut_print(dut, DUT_MSG_ERROR, 8517 "%s must be binded to the bridge for L2TIF", 8518 ifname); 8519 return -2; 8520 } 8521 8522 snprintf(buf, sizeof(buf), "echo 1 > %s", path); 8523 if (system(buf) != 0) { 8524 sigma_dut_print(dut, DUT_MSG_ERROR, 8525 "Failed to enable hairpin_mode for L2TIF"); 8526 return -2; 8527 } 8528 8529 snprintf(buf, sizeof(buf), "ebtables -P FORWARD ACCEPT"); 8530 if (system(buf) != 0) { 8531 sigma_dut_print(dut, DUT_MSG_ERROR, 8532 "Failed to set ebtables rules, RULE-9"); 8533 return -2; 8534 } 8535 8536 snprintf(buf, sizeof(buf), 8537 "ebtables -A FORWARD -p IPv4 --ip-proto icmp -i %s -j DROP", 8538 ifname); 8539 if (system(buf) != 0) { 8540 sigma_dut_print(dut, DUT_MSG_ERROR, 8541 "Failed to set ebtables rules, RULE-11"); 8542 return -2; 8543 } 8544 } 8545 8546 if (dut->ap_proxy_arp) { 8547 if (dut->ap_dgaf_disable) { 8548 if (set_ebtables_disable_dgaf(dut, "FORWARD", ifname) || 8549 set_ebtables_disable_dgaf(dut, "OUTPUT", ifname)) 8550 return -2; 8551 } else { 8552 if (set_ebtables_proxy_arp(dut, "FORWARD", ifname) || 8553 set_ebtables_proxy_arp(dut, "OUTPUT", ifname)) 8554 return -2; 8555 } 8556 8557 /* For 4.5-(c) */ 8558 snprintf(buf, sizeof(buf), 8559 "ebtables -A FORWARD -p ARP --arp-opcode 2 -i %s -j DROP", 8560 ifname); 8561 if (system(buf) != 0) { 8562 sigma_dut_print(dut, DUT_MSG_ERROR, 8563 "Failed to set ebtables rules, RULE-10"); 8564 return -2; 8565 } 8566 } 8567 8568 if (dut->ap_tdls_prohibit || dut->ap_l2tif) { 8569 /* Drop TDLS frames */ 8570 snprintf(buf, sizeof(buf), 8571 "ebtables -A FORWARD -p 0x890d -i %s -j DROP", ifname); 8572 if (system(buf) != 0) { 8573 sigma_dut_print(dut, DUT_MSG_ERROR, 8574 "Failed to set ebtables rules, RULE-13"); 8575 return -2; 8576 } 8577 } 8578 8579 if (dut->ap_fake_pkhash && 8580 run_hostapd_cli(dut, "set wps_corrupt_pkhash 1") != 0) { 8581 send_resp(dut, conn, SIGMA_ERROR, 8582 "errorCode,Could not enable FakePubKey"); 8583 return 0; 8584 } 8585 8586 if (dut->program == PROGRAM_60GHZ) { 8587 if (dut->ap_num_ese_allocs > 0) { 8588 /* wait extra time for AP to start */ 8589 sleep(2); 8590 if (ap_set_60g_ese(dut, dut->ap_num_ese_allocs, 8591 dut->ap_ese_allocs)) { 8592 send_resp(dut, conn, SIGMA_ERROR, 8593 "errorCode,Could not set ExtSch"); 8594 return 0; 8595 } 8596 } 8597 if (dut->ap_fixed_rate) { 8598 sigma_dut_print(dut, DUT_MSG_DEBUG, 8599 "forcing TX MCS index %d", 8600 dut->ap_mcs); 8601 if (ap_set_force_mcs(dut, 1, dut->ap_mcs)) { 8602 send_resp(dut, conn, SIGMA_ERROR, 8603 "errorCode,Could not force MCS"); 8604 return -2; 8605 } 8606 } 8607 } 8608 8609 if (dut->wps_forced_version) { 8610 snprintf(buf, sizeof(buf), "SET wps_version_number %d", 8611 dut->wps_forced_version); 8612 if (hapd_command(ifname, buf) < 0) { 8613 send_resp(dut, conn, SIGMA_ERROR, 8614 "errorCode,Fail to set wps_version_number"); 8615 return STATUS_SENT; 8616 } 8617 } 8618 8619 dut->hostapd_running = 1; 8620 return 1; 8621 } 8622 8623 8624 static int parse_qos_params(struct sigma_dut *dut, struct sigma_conn *conn, 8625 struct qos_params *qos, const char *cwmin, 8626 const char *cwmax, const char *aifs, 8627 const char *txop, const char *acm) 8628 { 8629 int val; 8630 8631 if (cwmin) { 8632 qos->ac = 1; 8633 val = atoi(cwmin); 8634 if (val < 0 || val > 15) { 8635 send_resp(dut, conn, SIGMA_INVALID, 8636 "errorCode,Invalid cwMin"); 8637 return 0; 8638 } 8639 qos->cwmin = val; 8640 } 8641 8642 if (cwmax) { 8643 qos->ac = 1; 8644 val = atoi(cwmax); 8645 if (val < 0 || val > 15) { 8646 send_resp(dut, conn, SIGMA_INVALID, 8647 "errorCode,Invalid cwMax"); 8648 return 0; 8649 } 8650 qos->cwmax = val; 8651 } 8652 8653 if (aifs) { 8654 qos->ac = 1; 8655 val = atoi(aifs); 8656 if (val < 1 || val > 255) { 8657 send_resp(dut, conn, SIGMA_INVALID, 8658 "errorCode,Invalid AIFS"); 8659 return 0; 8660 } 8661 qos->aifs = val; 8662 } 8663 8664 if (txop) { 8665 qos->ac = 1; 8666 val = atoi(txop); 8667 if (val < 0 || val > 0xffff) { 8668 send_resp(dut, conn, SIGMA_INVALID, 8669 "errorCode,Invalid txop"); 8670 return 0; 8671 } 8672 qos->txop = val * 32; 8673 } 8674 8675 if (acm) { 8676 qos->ac = 1; 8677 qos->acm = strcasecmp(acm, "on") == 0; 8678 } 8679 8680 return 1; 8681 } 8682 8683 8684 static enum sigma_cmd_result cmd_ap_set_apqos(struct sigma_dut *dut, 8685 struct sigma_conn *conn, 8686 struct sigma_cmd *cmd) 8687 { 8688 /* TXOP: The values provided here for VHT5G only */ 8689 if (!parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VO], 8690 get_param(cmd, "cwmin_VO"), 8691 get_param(cmd, "cwmax_VO"), 8692 get_param(cmd, "AIFS_VO"), 8693 get_param(cmd, "TXOP_VO"), 8694 get_param(cmd, "ACM_VO")) || 8695 !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VI], 8696 get_param(cmd, "cwmin_VI"), 8697 get_param(cmd, "cwmax_VI"), 8698 get_param(cmd, "AIFS_VI"), 8699 get_param(cmd, "TXOP_VI"), 8700 get_param(cmd, "ACM_VI")) || 8701 !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BE], 8702 get_param(cmd, "cwmin_BE"), 8703 get_param(cmd, "cwmax_BE"), 8704 get_param(cmd, "AIFS_BE"), 8705 get_param(cmd, "TXOP_BE"), 8706 get_param(cmd, "ACM_BE")) || 8707 !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BK], 8708 get_param(cmd, "cwmin_BK"), 8709 get_param(cmd, "cwmax_BK"), 8710 get_param(cmd, "AIFS_BK"), 8711 get_param(cmd, "TXOP_BK"), 8712 get_param(cmd, "ACM_BK"))) 8713 return 0; 8714 8715 return 1; 8716 } 8717 8718 8719 static enum sigma_cmd_result cmd_ap_set_staqos(struct sigma_dut *dut, 8720 struct sigma_conn *conn, 8721 struct sigma_cmd *cmd) 8722 { 8723 if (!parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VO], 8724 get_param(cmd, "cwmin_VO"), 8725 get_param(cmd, "cwmax_VO"), 8726 get_param(cmd, "AIFS_VO"), 8727 get_param(cmd, "TXOP_VO"), 8728 get_param(cmd, "ACM_VO")) || 8729 !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VI], 8730 get_param(cmd, "cwmin_VI"), 8731 get_param(cmd, "cwmax_VI"), 8732 get_param(cmd, "AIFS_VI"), 8733 get_param(cmd, "TXOP_VI"), 8734 get_param(cmd, "ACM_VI")) || 8735 !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BE], 8736 get_param(cmd, "cwmin_BE"), 8737 get_param(cmd, "cwmax_BE"), 8738 get_param(cmd, "AIFS_BE"), 8739 get_param(cmd, "TXOP_BE"), 8740 get_param(cmd, "ACM_BE")) || 8741 !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BK], 8742 get_param(cmd, "cwmin_BK"), 8743 get_param(cmd, "cwmax_BK"), 8744 get_param(cmd, "AIFS_BK"), 8745 get_param(cmd, "TXOP_BK"), 8746 get_param(cmd, "ACM_BK"))) 8747 return 0; 8748 8749 return 1; 8750 } 8751 8752 8753 static void cmd_ath_ap_hs2_reset(struct sigma_dut *dut) 8754 { 8755 unsigned char bssid[6]; 8756 char buf[100]; 8757 run_system(dut, "cfg -a AP_SSID=\"Hotspot 2.0\""); 8758 run_system(dut, "cfg -a AP_PRIMARY_CH=1"); 8759 run_system(dut, "cfg -a AP_SECMODE=WPA"); 8760 run_system(dut, "cfg -a AP_SECFILE=EAP"); 8761 run_system(dut, "cfg -a AP_WPA=2"); 8762 run_system(dut, "cfg -a AP_CYPHER=CCMP"); 8763 run_system(dut, "cfg -a AP_HOTSPOT=1"); 8764 run_system(dut, "cfg -a AP_HOTSPOT_ANT=2"); 8765 run_system(dut, "cfg -a AP_HOTSPOT_INTERNET=0"); 8766 run_system(dut, "cfg -a AP_HOTSPOT_VENUEGROUP=2"); 8767 run_system(dut, "cfg -a AP_HOTSPOT_VENUETYPE=8"); 8768 run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=506f9a"); 8769 run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2=001bc504bd"); 8770 if (!get_hwaddr("ath0", bssid)) { 8771 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=" 8772 "%02x:%02x:%02x:%02x:%02x:%02x", 8773 bssid[0], bssid[1], bssid[2], bssid[3], 8774 bssid[4], bssid[5]); 8775 run_system(dut, buf); 8776 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), 8777 "%02x:%02x:%02x:%02x:%02x:%02x", 8778 bssid[0], bssid[1], bssid[2], bssid[3], 8779 bssid[4], bssid[5]); 8780 } else { 8781 if (!get_hwaddr("wifi0", bssid)) { 8782 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=" 8783 "%02x:%02x:%02x:%02x:%02x:%02x", 8784 bssid[0], bssid[1], bssid[2], bssid[3], 8785 bssid[4], bssid[5]); 8786 run_system(dut, buf); 8787 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), 8788 "%02x:%02x:%02x:%02x:%02x:%02x", 8789 bssid[0], bssid[1], bssid[2], bssid[3], 8790 bssid[4], bssid[5]); 8791 } else { 8792 /* load the driver and try again */ 8793 run_system(dut, "/etc/rc.d/rc.wlan up"); 8794 8795 if (!get_hwaddr("wifi0", bssid)) { 8796 snprintf(buf, sizeof(buf), 8797 "cfg -a AP_HOTSPOT_HESSID=" 8798 "%02x:%02x:%02x:%02x:%02x:%02x", 8799 bssid[0], bssid[1], bssid[2], 8800 bssid[3], bssid[4], bssid[5]); 8801 run_system(dut, buf); 8802 snprintf(dut->ap_hessid, 8803 sizeof(dut->ap_hessid), 8804 "%02x:%02x:%02x:%02x:%02x:%02x", 8805 bssid[0], bssid[1], bssid[2], 8806 bssid[3], bssid[4], bssid[5]); 8807 } 8808 } 8809 } 8810 8811 run_system(dut, "cfg -r AP_SSID_2"); 8812 run_system(dut, "cfg -c"); 8813 /* run_system(dut, "cfg -s"); */ 8814 } 8815 8816 8817 static void ath_reset_vht_defaults(struct sigma_dut *dut) 8818 { 8819 run_system(dut, "cfg -x"); 8820 run_system(dut, "cfg -a AP_RADIO_ID=1"); 8821 run_system(dut, "cfg -a AP_PRIMARY_CH_2=36"); 8822 run_system(dut, "cfg -a AP_STARTMODE=standard"); 8823 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80"); 8824 run_system(dut, "cfg -a TX_CHAINMASK_2=7"); 8825 run_system(dut, "cfg -a RX_CHAINMASK_2=7"); 8826 run_system(dut, "cfg -a ATH_countrycode=0x348"); 8827 /* NOTE: For Beeliner we have to turn off MU-MIMO */ 8828 if (system("rm /tmp/secath*") != 0) { 8829 sigma_dut_print(dut, DUT_MSG_ERROR, 8830 "Failed to remove secath file"); 8831 } 8832 } 8833 8834 8835 static enum sigma_cmd_result cmd_ap_reset_default(struct sigma_dut *dut, 8836 struct sigma_conn *conn, 8837 struct sigma_cmd *cmd) 8838 { 8839 const char *type, *program; 8840 enum driver_type drv; 8841 char buf[128]; 8842 int i; 8843 8844 for (i = 0; i < MAX_WLAN_TAGS - 1; i++) { 8845 /* 8846 * Reset all tagged SSIDs to NULL-string and all key management 8847 * to open. 8848 */ 8849 dut->ap_tag_ssid[i][0] = '\0'; 8850 dut->ap_tag_key_mgmt[i] = AP2_OPEN; 8851 } 8852 8853 drv = get_driver_type(dut); 8854 8855 program = get_param(cmd, "program"); 8856 if (!program) 8857 program = get_param(cmd, "prog"); 8858 dut->program = sigma_program_to_enum(program); 8859 dut->device_type = AP_unknown; 8860 type = get_param(cmd, "type"); 8861 if (type && strcasecmp(type, "Testbed") == 0) 8862 dut->device_type = AP_testbed; 8863 if (type && strcasecmp(type, "DUT") == 0) 8864 dut->device_type = AP_dut; 8865 8866 dut->ap_rts = 0; 8867 dut->ap_frgmnt = 0; 8868 dut->ap_bcnint = 0; 8869 dut->ap_key_mgmt = AP_OPEN; 8870 dut->ap_ssid[0] = '\0'; 8871 dut->ap_fake_pkhash = 0; 8872 memset(dut->ap_qos, 0, sizeof(dut->ap_qos)); 8873 memset(dut->ap_sta_qos, 0, sizeof(dut->ap_sta_qos)); 8874 dut->ap_addba_reject = VALUE_NOT_SET; 8875 dut->ap_noack = VALUE_NOT_SET; 8876 dut->ap_is_dual = 0; 8877 dut->ap_mode = AP_inval; 8878 dut->ap_mode_1 = AP_inval; 8879 8880 dut->ap_allow_vht_wep = 0; 8881 dut->ap_allow_vht_tkip = 0; 8882 dut->ap_disable_protection = 0; 8883 memset(dut->ap_countrycode, 0, sizeof(dut->ap_countrycode)); 8884 dut->ap_dyn_bw_sig = VALUE_NOT_SET; 8885 dut->ap_ldpc = VALUE_NOT_SET; 8886 dut->ap_sig_rts = VALUE_NOT_SET; 8887 dut->ap_rx_amsdu = VALUE_NOT_SET; 8888 dut->ap_txBF = 0; 8889 dut->ap_mu_txBF = 0; 8890 dut->ap_chwidth = AP_AUTO; 8891 8892 dut->ap_rsn_preauth = 0; 8893 dut->ap_wpsnfc = 0; 8894 dut->ap_bss_load = -1; 8895 dut->ap_p2p_cross_connect = -1; 8896 8897 dut->ap_regulatory_mode = AP_80211D_MODE_DISABLED; 8898 dut->ap_dfs_mode = AP_DFS_MODE_DISABLED; 8899 dut->ap_chwidth_offset = SEC_CH_NO; 8900 8901 dut->mbo_pref_ap_cnt = 0; 8902 dut->ft_bss_mac_cnt = 0; 8903 dut->ap_interface_5g = 0; 8904 dut->ap_interface_2g = 0; 8905 dut->ap_pmf = AP_PMF_DISABLED; 8906 8907 dut->wsc_fragment = 0; 8908 dut->eap_fragment = 0; 8909 dut->wps_forced_version = 0; 8910 8911 if (dut->program == PROGRAM_HT || dut->program == PROGRAM_VHT) { 8912 dut->ap_wme = AP_WME_ON; 8913 dut->ap_wmmps = AP_WMMPS_ON; 8914 } else { 8915 dut->ap_wme = AP_WME_OFF; 8916 dut->ap_wmmps = AP_WMMPS_OFF; 8917 } 8918 8919 dut->ap_venue_url = 0; 8920 dut->ap_advice_of_charge = 0; 8921 dut->ap_oper_icon_metadata = 0; 8922 dut->ap_tnc_file_name = 0; 8923 dut->ap_tnc_time_stamp = 0; 8924 8925 dut->ap_akm_values = 0; 8926 free(dut->ap_sae_passwords); 8927 dut->ap_sae_passwords = NULL; 8928 8929 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 || 8930 dut->program == PROGRAM_HS2_R3 || 8931 dut->program == PROGRAM_IOTLP) { 8932 int i; 8933 8934 if (drv == DRIVER_ATHEROS) 8935 cmd_ath_ap_hs2_reset(dut); 8936 else if (drv == DRIVER_OPENWRT) 8937 cmd_owrt_ap_hs2_reset(dut); 8938 8939 dut->ap_interworking = 1; 8940 dut->ap_access_net_type = 2; 8941 dut->ap_internet = 0; 8942 dut->ap_venue_group = 2; 8943 dut->ap_venue_type = 8; 8944 dut->ap_domain_name_list[0] = '\0'; 8945 dut->ap_hs2 = 1; 8946 snprintf(dut->ap_roaming_cons, sizeof(dut->ap_roaming_cons), 8947 "506f9a;001bc504bd"); 8948 dut->ap_l2tif = 0; 8949 dut->ap_proxy_arp = 0; 8950 if (dut->bridge) { 8951 char buf[50]; 8952 8953 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", 8954 dut->bridge); 8955 if (system(buf) != 0) { 8956 sigma_dut_print(dut, DUT_MSG_DEBUG, 8957 "%s ip neigh table flushing failed", 8958 dut->bridge); 8959 } 8960 8961 snprintf(buf, sizeof(buf), "ebtables -F"); 8962 if (system(buf) != 0) { 8963 sigma_dut_print(dut, DUT_MSG_DEBUG, 8964 "%s ebtables flushing failed", 8965 dut->bridge); 8966 } 8967 } 8968 dut->ap_dgaf_disable = 0; 8969 dut->ap_p2p_cross_connect = 0; 8970 dut->ap_gas_cb_delay = 0; 8971 dut->ap_nai_realm_list = 0; 8972 dut->ap_oper_name = 0; 8973 dut->ap_venue_name = 0; 8974 for (i = 0; i < 10; i++) { 8975 dut->ap_plmn_mcc[i][0] = '\0'; 8976 dut->ap_plmn_mnc[i][0] = '\0'; 8977 } 8978 dut->ap_wan_metrics = 0; 8979 dut->ap_conn_capab = 0; 8980 dut->ap_ip_addr_type_avail = 0; 8981 dut->ap_net_auth_type = 0; 8982 dut->ap_oper_class = 0; 8983 dut->ap_pmf = 0; 8984 dut->ap_add_sha256 = 0; 8985 } 8986 8987 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 || 8988 dut->program == PROGRAM_IOTLP) { 8989 int i; 8990 const char hessid[] = "50:6f:9a:00:11:22"; 8991 8992 memcpy(dut->ap_hessid, hessid, strlen(hessid) + 1); 8993 dut->ap_osu_ssid[0] = '\0'; 8994 dut->ap_pmf = 1; 8995 dut->ap_osu_provider_list = 0; 8996 dut->ap_osu_provider_nai_list = 0; 8997 for (i = 0; i < 10; i++) { 8998 dut->ap_osu_server_uri[i][0] = '\0'; 8999 dut->ap_osu_method[i] = 0xFF; 9000 } 9001 dut->ap_qos_map_set = 0; 9002 dut->ap_tag_key_mgmt[0] = AP2_OPEN; 9003 dut->ap2_proxy_arp = 0; 9004 dut->ap2_osu = 0; 9005 dut->ap_osu_icon_tag = 0; 9006 } 9007 9008 if (dut->program == PROGRAM_VHT) { 9009 /* Set up the defaults */ 9010 dut->use_5g = 1; 9011 dut->ap_mode = AP_11ac; 9012 dut->ap_channel = 36; 9013 dut->ap_ampdu = VALUE_NOT_SET; 9014 dut->ap_ndpa_frame = 1; 9015 if (dut->device_type == AP_testbed) { 9016 dut->ap_amsdu = VALUE_DISABLED; 9017 dut->ap_ldpc = VALUE_DISABLED; 9018 dut->ap_rx_amsdu = VALUE_DISABLED; 9019 dut->ap_sgi80 = 0; 9020 } else { 9021 dut->ap_amsdu = VALUE_ENABLED; 9022 /* 9023 * As LDPC is optional, don't enable this by default 9024 * for LINUX-WCN driver. The ap_set_wireless command 9025 * can be used to enable LDPC, when needed. 9026 */ 9027 if (drv != DRIVER_LINUX_WCN) 9028 dut->ap_ldpc = VALUE_ENABLED; 9029 dut->ap_rx_amsdu = VALUE_ENABLED; 9030 dut->ap_sgi80 = 1; 9031 } 9032 dut->ap_fixed_rate = 0; 9033 dut->ap_rx_streams = 3; 9034 dut->ap_tx_streams = 3; 9035 dut->ap_vhtmcs_map = 0; 9036 dut->ap_chwidth = AP_80; 9037 dut->ap_tx_stbc = 1; 9038 dut->ap_dyn_bw_sig = VALUE_ENABLED; 9039 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 9040 dut->ap_dfs_mode = AP_DFS_MODE_ENABLED; 9041 if (get_driver_type(dut) == DRIVER_ATHEROS) 9042 ath_reset_vht_defaults(dut); 9043 } 9044 9045 if (dut->program == PROGRAM_IOTLP) { 9046 dut->wnm_bss_max_feature = VALUE_DISABLED; 9047 dut->wnm_bss_max_idle_time = 0; 9048 dut->wnm_bss_max_protection = VALUE_NOT_SET; 9049 dut->ap_proxy_arp = 1; 9050 } else { 9051 /* 9052 * Do not touch the BSS-MAX Idle time feature 9053 * if the program is not IOTLP. 9054 */ 9055 dut->wnm_bss_max_feature = VALUE_NOT_SET; 9056 dut->wnm_bss_max_idle_time = 0; 9057 dut->wnm_bss_max_protection = VALUE_NOT_SET; 9058 } 9059 9060 if (dut->program == PROGRAM_LOC) { 9061 dut->ap_rrm = 1; 9062 dut->ap_rtt = 1; 9063 dut->ap_lci = 0; 9064 dut->ap_val_lci[0] = '\0'; 9065 dut->ap_infoz[0] = '\0'; 9066 dut->ap_lcr = 0; 9067 dut->ap_val_lcr[0] = '\0'; 9068 dut->ap_neighap = 0; 9069 dut->ap_opchannel = 0; 9070 dut->ap_scan = 0; 9071 dut->ap_fqdn_held = 0; 9072 dut->ap_fqdn_supl = 0; 9073 dut->ap_interworking = 0; 9074 dut->ap_gas_cb_delay = 0; 9075 dut->ap_msnt_type = 0; 9076 } 9077 dut->ap_ft_oa = 0; 9078 dut->ap_ft_ds = VALUE_NOT_SET; 9079 dut->ap_reg_domain = REG_DOMAIN_NOT_SET; 9080 dut->ap_mobility_domain[0] = '\0'; 9081 9082 if (dut->program == PROGRAM_MBO) { 9083 dut->ap_mbo = 1; 9084 dut->ap_interworking = 1; 9085 dut->ap_ne_class = 0; 9086 dut->ap_ne_op_ch = 0; 9087 dut->ap_set_bssidpref = 1; 9088 dut->ap_btmreq_disassoc_imnt = 0; 9089 dut->ap_btmreq_term_bit = 0; 9090 dut->ap_disassoc_timer = 0; 9091 dut->ap_btmreq_bss_term_dur = 0; 9092 dut->ap_channel = 36; 9093 dut->ap_chwidth = AP_20; 9094 dut->ap_cell_cap_pref = 0; 9095 dut->ap_gas_cb_delay = 0; 9096 dut->mbo_self_ap_tuple.ap_ne_class = -1; 9097 dut->mbo_self_ap_tuple.ap_ne_pref = -1; /* Not set */ 9098 dut->mbo_self_ap_tuple.ap_ne_op_ch = -1; 9099 dut->ap_btmreq_bss_term_tsf = 0; 9100 dut->ap_assoc_delay = 0; 9101 } 9102 9103 if (dut->program == PROGRAM_OCE) { 9104 if (dut->ap_dhcp_stop) 9105 run_system(dut, "/etc/init.d/dnsmasq start"); 9106 9107 dut->ap_dhcp_stop = 0; 9108 dut->ap_oce = VALUE_ENABLED; 9109 dut->ap_broadcast_ssid = VALUE_ENABLED; 9110 dut->ap_fils_dscv_int = 20; 9111 dut->ap_filsdscv = VALUE_ENABLED; 9112 dut->ap_filshlp = VALUE_DISABLED; 9113 dut->ap_rnr = VALUE_DISABLED; 9114 dut->ap_nairealm[0] = '\0'; 9115 dut->ap_nairealm_int = 0; 9116 dut->ap_blechanutil = 0; 9117 dut->ap_ble_admit_cap = 0; 9118 dut->ap_esp = VALUE_ENABLED; 9119 dut->ap_datappdudura = 0; 9120 dut->ap_airtimefract = 0; 9121 dut->ap_blestacnt = 0; 9122 dut->ap_ul_availcap = 0; 9123 dut->ap_dl_availcap = 0; 9124 dut->ap_akm = 0; 9125 dut->ap_add_sha256 = 0; 9126 dut->ap_add_sha384 = 0; 9127 dut->ap_80plus80 = 0; 9128 } 9129 9130 dut->ap_he_ppdu = PPDU_NOT_SET; 9131 dut->ap_he_ulofdma = VALUE_NOT_SET; 9132 dut->ap_numsounddim = 0; 9133 dut->ap_bcc = VALUE_DISABLED; 9134 dut->ap_mu_edca = VALUE_DISABLED; 9135 dut->ap_he_mimo = MIMO_NOT_SET; 9136 dut->ap_he_rtsthrshld = VALUE_NOT_SET; 9137 dut->ap_mbssid = VALUE_DISABLED; 9138 dut->ap_ampdu = VALUE_NOT_SET; 9139 dut->he_mcsnssmap = 0; 9140 dut->ap_fixed_rate = 0; 9141 dut->he_mmss = 0; 9142 dut->he_set_sta_1x1 = VALUE_DISABLED; 9143 dut->he_srctrl_allow = -1; 9144 if (dut->device_type == AP_testbed) { 9145 dut->ap_he_dlofdma = VALUE_DISABLED; 9146 dut->ap_he_frag = VALUE_DISABLED; 9147 dut->ap_twtresp = VALUE_DISABLED; 9148 dut->he_ul_mcs = 7; 9149 } else { 9150 dut->ap_he_dlofdma = VALUE_NOT_SET; 9151 dut->ap_he_frag = VALUE_NOT_SET; 9152 dut->ap_ba_bufsize = BA_BUFSIZE_NOT_SET; 9153 dut->ap_twtresp = VALUE_NOT_SET; 9154 dut->he_ul_mcs = 0; 9155 } 9156 9157 if (dut->program == PROGRAM_HE) { 9158 if (dut->device_type == AP_testbed) { 9159 dut->ap_ldpc = VALUE_DISABLED; 9160 dut->ap_ba_bufsize = BA_BUFSIZE_64; 9161 dut->ap_amsdu = VALUE_DISABLED; 9162 dut->ap_txBF = 0; 9163 dut->ap_mu_txBF = 0; 9164 dut->he_sounding = VALUE_DISABLED; 9165 } else { 9166 if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) { 9167 dut->ap_txBF = 0; 9168 dut->ap_mu_txBF = 0; 9169 } else { 9170 dut->ap_txBF = 1; 9171 dut->ap_mu_txBF = 1; 9172 } 9173 dut->he_sounding = VALUE_ENABLED; 9174 if (drv == DRIVER_LINUX_WCN) { 9175 dut->ap_ldpc = VALUE_ENABLED; 9176 wcn_config_ap_ldpc(dut, get_main_ifname(dut)); 9177 #ifdef NL80211_SUPPORT 9178 if (wcn_set_he_ltf(dut, get_main_ifname(dut), 9179 QCA_WLAN_HE_LTF_AUTO)) { 9180 sigma_dut_print(dut, DUT_MSG_ERROR, 9181 "Failed to set LTF in ap_reset_default"); 9182 } 9183 #endif /* NL80211_SUPPORT */ 9184 } 9185 } 9186 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 9187 dut->ap_dfs_mode = AP_DFS_MODE_ENABLED; 9188 } 9189 9190 dut->ap_oper_chn = 0; 9191 9192 dut->ap_pmksa = 0; 9193 dut->ap_pmksa_caching = 0; 9194 9195 free(dut->rsne_override); 9196 dut->rsne_override = NULL; 9197 free(dut->rsnxe_override_eapol); 9198 dut->rsnxe_override_eapol = NULL; 9199 9200 free(dut->sae_commit_override); 9201 dut->sae_commit_override = NULL; 9202 9203 free(dut->ap_sae_groups); 9204 dut->ap_sae_groups = NULL; 9205 9206 dut->sae_anti_clogging_threshold = -1; 9207 dut->sae_reflection = 0; 9208 dut->sae_confirm_immediate = 0; 9209 dut->sae_pwe = SAE_PWE_DEFAULT; 9210 9211 dut->ap_cipher = AP_CCMP; 9212 dut->ap_group_cipher = AP_NO_GROUP_CIPHER_SET; 9213 dut->ap_group_mgmt_cipher = AP_NO_GROUP_MGMT_CIPHER_SET; 9214 dut->ap_passphrase[0] = '\0'; 9215 dut->ap_psk[0] = '\0'; 9216 dut->ap_beacon_prot = 0; 9217 dut->ap_transition_disable = 0; 9218 9219 dut->dpp_conf_id = -1; 9220 free(dut->ap_dpp_conf_addr); 9221 dut->ap_dpp_conf_addr = NULL; 9222 free(dut->ap_dpp_conf_pkhash); 9223 dut->ap_dpp_conf_pkhash = NULL; 9224 dut->ap_start_disabled = 0; 9225 9226 if (is_60g_sigma_dut(dut)) { 9227 dut->ap_mode = AP_11ad; 9228 dut->ap_channel = 2; 9229 dut->wps_disable = 0; /* WPS is enabled */ 9230 dut->ap_pmf = 0; 9231 dut->ap_num_ese_allocs = 0; 9232 dut->ap_fixed_rate = 0; 9233 9234 dut->dev_role = DEVROLE_AP; 9235 9236 sigma_dut_print(dut, DUT_MSG_DEBUG, 9237 "Setting msdu_size to MAX: 7912"); 9238 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912", 9239 get_main_ifname(dut)); 9240 9241 if (system(buf) != 0) { 9242 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s", 9243 buf); 9244 return ERROR_SEND_STATUS; 9245 } 9246 9247 if (ap_set_force_mcs(dut, 0, 1)) { 9248 sigma_dut_print(dut, DUT_MSG_ERROR, 9249 "Failed to reset force MCS"); 9250 return ERROR_SEND_STATUS; 9251 } 9252 9253 if (set_ps(get_main_ifname(dut), dut, 1)) { 9254 sigma_dut_print(dut, DUT_MSG_ERROR, 9255 "Failed to enable power save"); 9256 return ERROR_SEND_STATUS; 9257 } 9258 } 9259 9260 if (dut->program == PROGRAM_WPS && 9261 get_driver_type(dut) == DRIVER_WIL6210) { 9262 /* 9263 * In 60 GHz WPS tests, we configure the AP OOB to 9264 * secure connection with a random passphrase. 9265 */ 9266 char r[16], passphrase[65]; 9267 9268 if (random_get_bytes(r, sizeof(r))) { 9269 sigma_dut_print(dut, DUT_MSG_ERROR, 9270 "Failed to get random bytes"); 9271 return ERROR_SEND_STATUS; 9272 } 9273 if (base64_encode(r, sizeof(r), 9274 passphrase, sizeof(passphrase))) { 9275 sigma_dut_print(dut, DUT_MSG_ERROR, 9276 "Failed to generate random passphrase"); 9277 return ERROR_SEND_STATUS; 9278 } 9279 9280 dut->ap_key_mgmt = AP_WPA2_PSK; 9281 dut->ap_cipher = AP_GCMP_128; 9282 strlcpy(dut->ap_passphrase, passphrase, 9283 sizeof(dut->ap_passphrase)); 9284 sigma_dut_print(dut, DUT_MSG_DEBUG, 9285 "60G WPS: configure secure AP with random passphrase"); 9286 } 9287 9288 dut->hostapd_running = 0; 9289 9290 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 9291 return 1; 9292 9293 if (dut->use_hostapd_pid_file) { 9294 kill_hostapd_process_pid(dut); 9295 } else if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 || 9296 system("killall hostapd") == 0) { 9297 int i; 9298 /* Wait some time to allow hostapd to complete cleanup before 9299 * starting a new process */ 9300 for (i = 0; i < 10; i++) { 9301 usleep(500000); 9302 if (system("pidof hostapd") != 0) 9303 break; 9304 } 9305 } 9306 9307 if (if_nametoindex("sigmadut") > 0 && 9308 system("iw dev sigmadut del") != 0) 9309 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove " 9310 "monitor interface"); 9311 9312 return 1; 9313 } 9314 9315 9316 int sta_cfon_reset_default(struct sigma_dut *dut, struct sigma_conn *conn, 9317 struct sigma_cmd *cmd) 9318 { 9319 return cmd_ap_reset_default(dut, conn, cmd); 9320 } 9321 9322 9323 static enum sigma_cmd_result cmd_ap_get_info(struct sigma_dut *dut, 9324 struct sigma_conn *conn, 9325 struct sigma_cmd *cmd) 9326 { 9327 /* const char *name = get_param(cmd, "NAME"); */ 9328 struct stat s; 9329 char resp[200]; 9330 FILE *f; 9331 enum driver_type drv = get_driver_type(dut); 9332 int res; 9333 9334 switch (drv) { 9335 case DRIVER_ATHEROS: { 9336 /* Atheros AP */ 9337 struct utsname uts; 9338 char *version, athver[100]; 9339 9340 if (stat("/proc/athversion", &s) != 0) { 9341 if (system("/etc/rc.d/rc.wlan up") != 0) { 9342 } 9343 } 9344 9345 athver[0] = '\0'; 9346 f = fopen("/proc/athversion", "r"); 9347 if (f) { 9348 if (fgets(athver, sizeof(athver), f)) { 9349 char *pos = strchr(athver, '\n'); 9350 if (pos) 9351 *pos = '\0'; 9352 } 9353 fclose(f); 9354 } 9355 9356 if (uname(&uts) == 0) 9357 version = uts.release; 9358 else 9359 version = "Unknown"; 9360 9361 if (if_nametoindex("ath1") > 0) 9362 res = snprintf(resp, sizeof(resp), 9363 "interface,ath0_24G ath1_5G,agent,1.0,version,%s/drv:%s", 9364 version, athver); 9365 else 9366 res = snprintf(resp, sizeof(resp), 9367 "interface,ath0_24G,agent,1.0,version,%s/drv:%s", 9368 version, athver); 9369 if (res < 0 || res >= sizeof(resp)) 9370 send_resp(dut, conn, SIGMA_ERROR, NULL); 9371 else 9372 send_resp(dut, conn, SIGMA_COMPLETE, resp); 9373 return 0; 9374 } 9375 case DRIVER_LINUX_WCN: 9376 case DRIVER_MAC80211: { 9377 struct utsname uts; 9378 char *version; 9379 9380 if (uname(&uts) == 0) 9381 version = uts.release; 9382 else 9383 version = "Unknown"; 9384 9385 if (if_nametoindex("wlan1") > 0) 9386 snprintf(resp, sizeof(resp), "interface,wlan0_24G " 9387 "wlan1_5G,agent,1.0,version,%s", version); 9388 else 9389 snprintf(resp, sizeof(resp), "interface,wlan0_any," 9390 "agent,1.0,version,%s", version); 9391 9392 send_resp(dut, conn, SIGMA_COMPLETE, resp); 9393 return 0; 9394 } 9395 case DRIVER_QNXNTO: { 9396 struct utsname uts; 9397 char *version; 9398 9399 if (uname(&uts) == 0) 9400 version = uts.release; 9401 else 9402 version = "Unknown"; 9403 snprintf(resp, sizeof(resp), 9404 "interface,%s_any,agent,1.0,version,%s", 9405 dut->main_ifname ? get_main_ifname(dut) : "NA", 9406 version); 9407 send_resp(dut, conn, SIGMA_COMPLETE, resp); 9408 return 0; 9409 } 9410 case DRIVER_OPENWRT: { 9411 switch (get_openwrt_driver_type()) { 9412 case OPENWRT_DRIVER_ATHEROS: { 9413 struct utsname uts; 9414 char *version; 9415 9416 if (uname(&uts) == 0) 9417 version = uts.release; 9418 else 9419 version = "Unknown"; 9420 9421 if (if_nametoindex("ath1") > 0) 9422 snprintf(resp, sizeof(resp), 9423 "interface,ath0_5G ath1_24G,agent,1.0,version,%s", 9424 version); 9425 else 9426 snprintf(resp, sizeof(resp), 9427 "interface,ath0_any,agent,1.0,version,%s", 9428 version); 9429 9430 send_resp(dut, conn, SIGMA_COMPLETE, resp); 9431 return 0; 9432 } 9433 default: 9434 send_resp(dut, conn, SIGMA_ERROR, 9435 "errorCode,Unsupported openwrt driver"); 9436 return 0; 9437 } 9438 } 9439 default: 9440 send_resp(dut, conn, SIGMA_ERROR, 9441 "errorCode,Unsupported driver"); 9442 return 0; 9443 } 9444 } 9445 9446 9447 static enum sigma_cmd_result cmd_ap_deauth_sta(struct sigma_dut *dut, 9448 struct sigma_conn *conn, 9449 struct sigma_cmd *cmd) 9450 { 9451 /* const char *name = get_param(cmd, "NAME"); */ 9452 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 9453 const char *val, *disconnect; 9454 char buf[100]; 9455 9456 val = get_param(cmd, "MinorCode"); 9457 if (val) { 9458 /* TODO: add support for P2P minor code */ 9459 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MinorCode not " 9460 "yet supported"); 9461 return 0; 9462 } 9463 9464 val = get_param(cmd, "STA_MAC_ADDRESS"); 9465 if (val == NULL) 9466 return -1; 9467 disconnect = get_param(cmd, "disconnect"); 9468 if (disconnect && strcasecmp(disconnect, "silent") == 0) 9469 snprintf(buf, sizeof(buf), "deauth %s tx=0", val); 9470 else 9471 snprintf(buf, sizeof(buf), "deauth %s", val); 9472 if (run_hostapd_cli(dut, buf) != 0) 9473 return -2; 9474 9475 return 1; 9476 } 9477 9478 9479 #ifdef __linux__ 9480 int inject_frame(int s, const void *data, size_t len, int encrypt); 9481 int open_monitor(const char *ifname); 9482 #endif /* __linux__ */ 9483 9484 enum send_frame_type { 9485 DISASSOC, DEAUTH, SAQUERY 9486 }; 9487 enum send_frame_protection { 9488 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED 9489 }; 9490 9491 9492 static int ap_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn, 9493 enum send_frame_type frame, 9494 enum send_frame_protection protected, 9495 const char *sta_addr) 9496 { 9497 #ifdef __linux__ 9498 unsigned char buf[1000], *pos; 9499 int s, res; 9500 unsigned char addr_sta[6], addr_own[6]; 9501 char *ifname; 9502 char cbuf[100]; 9503 struct ifreq ifr; 9504 9505 if ((dut->ap_mode == AP_11a || dut->ap_mode == AP_11na || 9506 dut->ap_mode == AP_11ac) && 9507 if_nametoindex("wlan1") > 0) 9508 ifname = "wlan1"; 9509 else 9510 ifname = "wlan0"; 9511 9512 if (hwaddr_aton(sta_addr, addr_sta) < 0) 9513 return -1; 9514 9515 s = socket(AF_INET, SOCK_DGRAM, 0); 9516 if (s < 0) 9517 return -1; 9518 memset(&ifr, 0, sizeof(ifr)); 9519 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 9520 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { 9521 perror("ioctl"); 9522 close(s); 9523 return -1; 9524 } 9525 close(s); 9526 memcpy(addr_own, ifr.ifr_hwaddr.sa_data, 6); 9527 9528 if (if_nametoindex("sigmadut") == 0) { 9529 snprintf(cbuf, sizeof(cbuf), 9530 "iw dev %s interface add sigmadut type monitor", 9531 ifname); 9532 if (system(cbuf) != 0 || 9533 if_nametoindex("sigmadut") == 0) { 9534 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add " 9535 "monitor interface with '%s'", cbuf); 9536 return -2; 9537 } 9538 } 9539 9540 if (system("ifconfig sigmadut up") != 0) { 9541 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set " 9542 "monitor interface up"); 9543 return -2; 9544 } 9545 9546 pos = buf; 9547 9548 /* Frame Control */ 9549 switch (frame) { 9550 case DISASSOC: 9551 *pos++ = 0xa0; 9552 break; 9553 case DEAUTH: 9554 *pos++ = 0xc0; 9555 break; 9556 case SAQUERY: 9557 *pos++ = 0xd0; 9558 break; 9559 } 9560 9561 if (protected == INCORRECT_KEY) 9562 *pos++ = 0x40; /* Set Protected field to 1 */ 9563 else 9564 *pos++ = 0x00; 9565 9566 /* Duration */ 9567 *pos++ = 0x00; 9568 *pos++ = 0x00; 9569 9570 /* addr1 = DA (station) */ 9571 memcpy(pos, addr_sta, 6); 9572 pos += 6; 9573 /* addr2 = SA (own address) */ 9574 memcpy(pos, addr_own, 6); 9575 pos += 6; 9576 /* addr3 = BSSID (own address) */ 9577 memcpy(pos, addr_own, 6); 9578 pos += 6; 9579 9580 /* Seq# (to be filled by driver/mac80211) */ 9581 *pos++ = 0x00; 9582 *pos++ = 0x00; 9583 9584 if (protected == INCORRECT_KEY) { 9585 /* CCMP parameters */ 9586 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8); 9587 pos += 8; 9588 } 9589 9590 if (protected == INCORRECT_KEY) { 9591 switch (frame) { 9592 case DEAUTH: 9593 /* Reason code (encrypted) */ 9594 memcpy(pos, "\xa7\x39", 2); 9595 pos += 2; 9596 break; 9597 case DISASSOC: 9598 /* Reason code (encrypted) */ 9599 memcpy(pos, "\xa7\x39", 2); 9600 pos += 2; 9601 break; 9602 case SAQUERY: 9603 /* Category|Action|TransID (encrypted) */ 9604 memcpy(pos, "\x6f\xbd\xe9\x4d", 4); 9605 pos += 4; 9606 break; 9607 default: 9608 return -1; 9609 } 9610 9611 /* CCMP MIC */ 9612 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8); 9613 pos += 8; 9614 } else { 9615 switch (frame) { 9616 case DEAUTH: 9617 /* reason code = 8 */ 9618 *pos++ = 0x08; 9619 *pos++ = 0x00; 9620 break; 9621 case DISASSOC: 9622 /* reason code = 8 */ 9623 *pos++ = 0x08; 9624 *pos++ = 0x00; 9625 break; 9626 case SAQUERY: 9627 /* Category - SA Query */ 9628 *pos++ = 0x08; 9629 /* SA query Action - Request */ 9630 *pos++ = 0x00; 9631 /* Transaction ID */ 9632 *pos++ = 0x12; 9633 *pos++ = 0x34; 9634 break; 9635 } 9636 } 9637 9638 s = open_monitor("sigmadut"); 9639 if (s < 0) { 9640 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open " 9641 "monitor socket"); 9642 return 0; 9643 } 9644 9645 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY); 9646 if (res < 0) { 9647 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to " 9648 "inject frame"); 9649 close(s); 9650 return 0; 9651 } 9652 if (res < pos - buf) { 9653 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial " 9654 "frame sent"); 9655 close(s); 9656 return 0; 9657 } 9658 9659 close(s); 9660 9661 return 1; 9662 #else /* __linux__ */ 9663 send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_send_frame not " 9664 "yet supported"); 9665 return 0; 9666 #endif /* __linux__ */ 9667 } 9668 9669 9670 int ap_send_frame_hs2(struct sigma_dut *dut, struct sigma_conn *conn, 9671 struct sigma_cmd *cmd) 9672 { 9673 const char *val, *dest; 9674 char buf[100]; 9675 9676 val = get_param(cmd, "FrameName"); 9677 if (val == NULL) 9678 return -1; 9679 9680 if (strcasecmp(val, "QoSMapConfigure") == 0) { 9681 dest = get_param(cmd, "Dest"); 9682 if (!dest) 9683 return -1; 9684 9685 val = get_param(cmd, "QoS_MAP_SET"); 9686 if (val) { 9687 dut->ap_qos_map_set = atoi(val); 9688 sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d", 9689 dut->ap_qos_map_set); 9690 } 9691 9692 if (dut->ap_qos_map_set == 1) 9693 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1); 9694 else if (dut->ap_qos_map_set == 2) 9695 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2); 9696 9697 snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest); 9698 if (run_hostapd_cli(dut, buf) != 0) 9699 return -1; 9700 } 9701 9702 return 1; 9703 } 9704 9705 9706 static int ath_ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn, 9707 struct sigma_cmd *cmd) 9708 { 9709 const char *val; 9710 const char *ifname; 9711 int chwidth, nss; 9712 9713 val = get_param(cmd, "FrameName"); 9714 if (!val || strcasecmp(val, "op_md_notif_frm") != 0) { 9715 send_resp(dut, conn, SIGMA_ERROR, 9716 "errorCode,Unsupported FrameName"); 9717 return 0; 9718 } 9719 9720 /* 9721 * Sequence of commands for Opmode notification on 9722 * Peregrine based products 9723 */ 9724 ifname = get_main_ifname(dut); 9725 9726 /* Disable STBC */ 9727 run_iwpriv(dut, ifname, "tx_stbc 0"); 9728 9729 /* Check whether optional arg channel width was passed */ 9730 val = get_param(cmd, "Channel_width"); 9731 if (val) { 9732 switch (atoi(val)) { 9733 case 20: 9734 chwidth = 0; 9735 break; 9736 case 40: 9737 chwidth = 1; 9738 break; 9739 case 80: 9740 chwidth = 2; 9741 break; 9742 case 160: 9743 chwidth = 3; 9744 break; 9745 default: 9746 chwidth = 2; 9747 break; 9748 } 9749 run_iwpriv(dut, ifname, "chwidth %d", chwidth); 9750 } 9751 9752 /* Check whether optional arg NSS was passed */ 9753 val = get_param(cmd, "NSS"); 9754 if (val) { 9755 /* Convert nss to chainmask */ 9756 switch (atoi(val)) { 9757 case 1: 9758 nss = 1; 9759 break; 9760 case 2: 9761 nss = 3; 9762 break; 9763 case 3: 9764 nss = 7; 9765 break; 9766 default: 9767 /* We do not support NSS > 3 */ 9768 nss = 3; 9769 break; 9770 } 9771 run_iwpriv(dut, ifname, "rxchainmask %d", nss); 9772 } 9773 9774 /* Send the opmode notification */ 9775 run_iwpriv(dut, ifname, "opmode_notify 1"); 9776 9777 return 1; 9778 } 9779 9780 9781 static int ath_ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn, 9782 struct sigma_cmd *cmd) 9783 { 9784 const char *val; 9785 FILE *f; 9786 int rand_int = 0; 9787 9788 val = get_param(cmd, "MsntType"); 9789 if (val) { 9790 if (dut->ap_msnt_type == 0) 9791 dut->ap_msnt_type = atoi(val); 9792 9793 if (dut->ap_msnt_type != 5 && dut->ap_msnt_type != 2) { 9794 dut->ap_msnt_type = atoi(val); 9795 if (dut->ap_msnt_type == 1) { 9796 val = get_param(cmd, "RandInterval"); 9797 if (val) 9798 rand_int = atoi(val); 9799 f = fopen("/tmp/ftmrr.txt", "a"); 9800 if (!f) { 9801 sigma_dut_print(dut, DUT_MSG_ERROR, 9802 "Failed to open /tmp/ftmrr.txt"); 9803 return -1; 9804 } 9805 9806 fprintf(f, "sta_mac = %s\n", cmd->values[3]); 9807 fprintf(f, "meas_type = 0x10\nrand_inter = 0x%x\nmin_ap_count = 0x%s\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0xf\nmeas_req_mode = 0x00\n", 9808 rand_int, cmd->values[7]); 9809 fclose(f); 9810 dut->ap_msnt_type = 5; 9811 run_system(dut, "wpc -f /tmp/ftmrr.txt"); 9812 } 9813 } else if (dut->ap_msnt_type == 5) { 9814 run_system(dut, "wpc -f /tmp/ftmrr.txt"); 9815 } else if (dut->ap_msnt_type == 2) { 9816 f = fopen("/tmp/wru.txt", "w"); 9817 if (!f) { 9818 sigma_dut_print(dut, DUT_MSG_ERROR, 9819 "Failed to open /tmp/wru.txt"); 9820 return -1; 9821 } 9822 9823 fprintf(f, "sta_mac = %s\n", cmd->values[3]); 9824 fprintf(f, "meas_type = 0x08\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0x1\nmeas_req_mode = 0x00\nloc_subject = 0x01\n"); 9825 fclose(f); 9826 run_system(dut, "wpc -w /tmp/wru.txt"); 9827 } 9828 } 9829 return 1; 9830 } 9831 9832 9833 /* 9834 * The following functions parse_send_frame_params_int(), 9835 * parse_send_frame_params_str(), and parse_send_frame_params_mac() 9836 * are used by ath_ap_send_frame_bcn_rpt_req(). 9837 * Beacon Report Request is a frame used as part of the MBO program. 9838 * The command for sending beacon report has a lot of 9839 * arguments and having these functions reduces code size. 9840 * 9841 */ 9842 static int parse_send_frame_params_int(char *param, struct sigma_cmd *cmd, 9843 struct sigma_dut *dut, 9844 char *buf, size_t buf_size) 9845 { 9846 const char *str_val; 9847 int int_val; 9848 char temp[100]; 9849 9850 str_val = get_param(cmd, param); 9851 if (!str_val) { 9852 sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param); 9853 return -1; 9854 } 9855 int_val = atoi(str_val); 9856 snprintf(temp, sizeof(temp), " %d", int_val); 9857 strlcat(buf, temp, buf_size); 9858 return 0; 9859 } 9860 9861 9862 static int parse_send_frame_params_str(char *param, struct sigma_cmd *cmd, 9863 struct sigma_dut *dut, 9864 char *buf, size_t buf_size) 9865 { 9866 const char *str_val; 9867 char temp[100]; 9868 9869 str_val = get_param(cmd, param); 9870 if (!str_val) { 9871 sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param); 9872 return -1; 9873 } 9874 snprintf(temp, sizeof(temp), " %s", str_val); 9875 temp[sizeof(temp) - 1] = '\0'; 9876 strlcat(buf, temp, buf_size); 9877 return 0; 9878 } 9879 9880 9881 static int parse_send_frame_params_mac(char *param, struct sigma_cmd *cmd, 9882 struct sigma_dut *dut, 9883 char *buf, size_t buf_size) 9884 { 9885 const char *str_val; 9886 unsigned char mac[6]; 9887 char temp[100]; 9888 9889 str_val = get_param(cmd, param); 9890 if (!str_val) { 9891 sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param); 9892 return -1; 9893 } 9894 9895 if (parse_mac_address(dut, str_val, mac) < 0) { 9896 sigma_dut_print(dut, DUT_MSG_ERROR, 9897 "MAC Address not in proper format"); 9898 return -1; 9899 } 9900 snprintf(temp, sizeof(temp), " %02x:%02x:%02x:%02x:%02x:%02x", 9901 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 9902 strlcat(buf, temp, buf_size); 9903 return 0; 9904 } 9905 9906 9907 static void fill_1_or_0_based_on_presence(struct sigma_cmd *cmd, char *param, 9908 char *buf, size_t buf_size) 9909 { 9910 const char *str_val; 9911 char *value = " 1"; 9912 9913 str_val = get_param(cmd, param); 9914 if (!str_val || str_val[0] == '\0') 9915 value = " 0"; 9916 strlcat(buf, value, buf_size); 9917 9918 } 9919 9920 9921 /* 9922 * wifitool athN sendbcnrpt 9923 * <STA MAC - Plugs in from Dest_MAC> 9924 * <regclass - Plugs in from RegClass - int> 9925 * <channum - Plugs in from Channel PARAM of dev_send_frame - int> 9926 * <rand_ivl - Plugs in from RandInt - string> 9927 * <duration - Plugs in from MeaDur - integer> 9928 * <mode - Plugs in from MeaMode - string> 9929 * <req_ssid - Plugs in from SSID PARAM of dev_send_frame - string> 9930 * <rep_cond - Plugs in from RptCond - integer> 9931 * <rpt_detail - Plugs in from RptDet - integer> 9932 * <req_ie - Plugs in from ReqInfo PARAM of dev_send_frame - string> 9933 * <chanrpt_mode - Plugs in from APChanRpt - integer> 9934 * <specific_bssid - Plugs in from BSSID PARAM of dev_send_frame> 9935 * [AP channel numbers] 9936 */ 9937 static int ath_ap_send_frame_bcn_rpt_req(struct sigma_dut *dut, 9938 struct sigma_cmd *cmd, 9939 const char *ifname) 9940 { 9941 char buf[100]; 9942 int rpt_det; 9943 const char *str_val; 9944 const char *mea_mode; 9945 9946 snprintf(buf, sizeof(buf), "wifitool %s sendbcnrpt", ifname); 9947 9948 if (parse_send_frame_params_mac("Dest_MAC", cmd, dut, buf, sizeof(buf))) 9949 return -1; 9950 if (parse_send_frame_params_int("RegClass", cmd, dut, buf, sizeof(buf))) 9951 return -1; 9952 if (parse_send_frame_params_int("Channel", cmd, dut, buf, sizeof(buf))) 9953 return -1; 9954 if (parse_send_frame_params_str("RandInt", cmd, dut, buf, sizeof(buf))) 9955 return -1; 9956 if (parse_send_frame_params_int("MeaDur", cmd, dut, buf, sizeof(buf))) 9957 return -1; 9958 9959 str_val = get_param(cmd, "MeaMode"); 9960 if (!str_val) { 9961 sigma_dut_print(dut, DUT_MSG_ERROR, 9962 "MeaMode parameter not present in send bcn-rpt-req"); 9963 return -1; 9964 } 9965 if (strcasecmp(str_val, "passive") == 0) { 9966 mea_mode = " 0"; 9967 } else if (strcasecmp(str_val, "active") == 0) { 9968 mea_mode = " 1"; 9969 } else if (strcasecmp(str_val, "table") == 0) { 9970 mea_mode = " 2"; 9971 } else { 9972 sigma_dut_print(dut, DUT_MSG_ERROR, 9973 "MEA-MODE Value not correctly given"); 9974 return -1; 9975 } 9976 strlcat(buf, mea_mode, sizeof(buf)); 9977 9978 fill_1_or_0_based_on_presence(cmd, "SSID", buf, sizeof(buf)); 9979 9980 if (parse_send_frame_params_int("RptCond", cmd, dut, buf, sizeof(buf))) 9981 return -1; 9982 9983 if (parse_send_frame_params_int("RptDet", cmd, dut, buf, sizeof(buf))) 9984 return -1; 9985 str_val = get_param(cmd, "RptDet"); 9986 rpt_det = str_val ? atoi(str_val) : 0; 9987 9988 if (rpt_det) 9989 fill_1_or_0_based_on_presence(cmd, "ReqInfo", buf, sizeof(buf)); 9990 else 9991 strlcat(buf, " 0", sizeof(buf)); 9992 9993 if (rpt_det) 9994 fill_1_or_0_based_on_presence(cmd, "APChanRpt", buf, 9995 sizeof(buf)); 9996 else 9997 strlcat(buf, " 0", sizeof(buf)); 9998 9999 if (parse_send_frame_params_mac("BSSID", cmd, dut, buf, sizeof(buf))) 10000 return -1; 10001 10002 str_val = get_param(cmd, "APChanRpt"); 10003 if (str_val) { 10004 const char *pos; 10005 int ap_chanrpt; 10006 int ap_chanrpt_2 = 0; 10007 char chanrpt[100]; 10008 10009 ap_chanrpt = atoi(str_val); 10010 pos = strchr(str_val, '_'); 10011 if (pos) { 10012 pos++; 10013 ap_chanrpt_2 = atoi(pos); 10014 } 10015 if (ap_chanrpt) { 10016 snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt); 10017 strlcat(buf, chanrpt, sizeof(buf)); 10018 } 10019 if (ap_chanrpt_2) { 10020 snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt_2); 10021 strlcat(buf, chanrpt, sizeof(buf)); 10022 } 10023 } 10024 10025 run_system(dut, buf); 10026 return 0; 10027 } 10028 10029 10030 static void inform_and_sleep(struct sigma_dut *dut, int seconds) 10031 { 10032 sigma_dut_print(dut, DUT_MSG_DEBUG, "sleeping for %d seconds", seconds); 10033 sleep(seconds); 10034 sigma_dut_print(dut, DUT_MSG_DEBUG, "woke up after %d seconds", 10035 seconds); 10036 } 10037 10038 10039 static int ath_ap_send_frame_btm_req(struct sigma_dut *dut, 10040 struct sigma_cmd *cmd, const char *ifname) 10041 { 10042 unsigned char mac_addr[ETH_ALEN]; 10043 int disassoc_timer; 10044 char buf[100]; 10045 const char *val; 10046 int cand_list = 1; 10047 10048 val = get_param(cmd, "Dest_MAC"); 10049 if (!val || parse_mac_address(dut, val, mac_addr) < 0) { 10050 sigma_dut_print(dut, DUT_MSG_ERROR, 10051 "MAC Address not in proper format"); 10052 return -1; 10053 } 10054 10055 val = get_param(cmd, "Disassoc_Timer"); 10056 if (val) 10057 disassoc_timer = atoi(val); 10058 else 10059 disassoc_timer = dut->ap_disassoc_timer; 10060 if (disassoc_timer < 0) { 10061 sigma_dut_print(dut, DUT_MSG_ERROR, 10062 "Invalid Disassoc_Timer value %d", 10063 disassoc_timer); 10064 return -1; 10065 } 10066 10067 val = get_param(cmd, "Cand_List"); 10068 if (val && val[0]) 10069 cand_list = atoi(val); 10070 10071 val = get_param(cmd, "BTMQuery_Reason_Code"); 10072 if (val) 10073 run_iwpriv(dut, ifname, "mbo_trans_rs %s", val); 10074 10075 if (dut->ap_btmreq_disassoc_imnt && !dut->ap_assoc_delay) 10076 run_iwpriv(dut, ifname, "mbo_asoc_ret 1"); 10077 10078 snprintf(buf, sizeof(buf), 10079 "wifitool %s sendbstmreq %02x:%02x:%02x:%02x:%02x:%02x %d %d 15 %d %d %d %d", 10080 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], 10081 mac_addr[4], mac_addr[5], cand_list, disassoc_timer, 10082 dut->ap_btmreq_disassoc_imnt, 10083 dut->ap_btmreq_term_bit, 10084 dut->ap_btmreq_bss_term_tsf, 10085 dut->ap_btmreq_bss_term_dur); 10086 run_system(dut, buf); 10087 10088 if (dut->ap_btmreq_term_bit) { 10089 if (dut->ap_btmreq_bss_term_tsf >= 2) 10090 inform_and_sleep(dut, dut->ap_btmreq_bss_term_tsf - 2); 10091 run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x", 10092 mac_addr[0], mac_addr[1], mac_addr[2], 10093 mac_addr[3], mac_addr[4], mac_addr[5]); 10094 inform_and_sleep(dut, 2); 10095 run_system_wrapper(dut, "ifconfig %s down", ifname); 10096 inform_and_sleep(dut, 5); 10097 run_system_wrapper(dut, "ifconfig %s up", ifname); 10098 } else if (dut->ap_btmreq_disassoc_imnt) { 10099 inform_and_sleep(dut, (disassoc_timer / 1000) + 1); 10100 run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x", 10101 mac_addr[0], mac_addr[1], mac_addr[2], 10102 mac_addr[3], mac_addr[4], mac_addr[5]); 10103 } 10104 return 0; 10105 } 10106 10107 10108 static int ath_ap_send_frame_disassoc(struct sigma_dut *dut, 10109 struct sigma_cmd *cmd, const char *ifname) 10110 { 10111 unsigned char mac_addr[ETH_ALEN]; 10112 const char *val; 10113 10114 val = get_param(cmd, "Dest_MAC"); 10115 if (!val || parse_mac_address(dut, val, mac_addr) < 0) { 10116 sigma_dut_print(dut, DUT_MSG_ERROR, 10117 "MAC Address not in proper format"); 10118 return -1; 10119 } 10120 10121 run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x", 10122 mac_addr[0], mac_addr[1], mac_addr[2], 10123 mac_addr[3], mac_addr[4], mac_addr[5]); 10124 return 0; 10125 } 10126 10127 10128 static int ath_ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn, 10129 struct sigma_cmd *cmd) 10130 { 10131 const char *val; 10132 const char *ifname; 10133 10134 ifname = get_main_ifname(dut); 10135 10136 val = get_param(cmd, "FrameName"); 10137 if (!val) 10138 return -1; 10139 10140 if (strcasecmp(val, "BTMReq") == 0) 10141 ath_ap_send_frame_btm_req(dut, cmd, ifname); 10142 else if (strcasecmp(val, "BcnRptReq") == 0) 10143 ath_ap_send_frame_bcn_rpt_req(dut, cmd, ifname); 10144 else if (strcasecmp(val, "disassoc") == 0) 10145 ath_ap_send_frame_disassoc(dut, cmd, ifname); 10146 else 10147 return -1; 10148 10149 return 1; 10150 } 10151 10152 10153 static int ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn, 10154 struct sigma_cmd *cmd) 10155 { 10156 switch (get_driver_type(dut)) { 10157 case DRIVER_ATHEROS: 10158 return ath_ap_send_frame_vht(dut, conn, cmd); 10159 break; 10160 case DRIVER_OPENWRT: 10161 switch (get_openwrt_driver_type()) { 10162 case OPENWRT_DRIVER_ATHEROS: 10163 return ath_ap_send_frame_vht(dut, conn, cmd); 10164 default: 10165 send_resp(dut, conn, SIGMA_ERROR, 10166 "errorCode,Unsupported ap_send_frame with the current openwrt driver"); 10167 return 0; 10168 } 10169 default: 10170 send_resp(dut, conn, SIGMA_ERROR, 10171 "errorCode,Unsupported ap_send_frame with the current driver"); 10172 return 0; 10173 } 10174 } 10175 10176 10177 static int ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn, 10178 struct sigma_cmd *cmd) 10179 { 10180 switch (get_driver_type(dut)) { 10181 case DRIVER_ATHEROS: 10182 return ath_ap_send_frame_loc(dut, conn, cmd); 10183 case DRIVER_OPENWRT: 10184 switch (get_openwrt_driver_type()) { 10185 case OPENWRT_DRIVER_ATHEROS: 10186 return ath_ap_send_frame_loc(dut, conn, cmd); 10187 default: 10188 send_resp(dut, conn, SIGMA_ERROR, 10189 "errorCode,Unsupported ap_send_frame_loc with the current openwrt driver"); 10190 return 0; 10191 } 10192 default: 10193 send_resp(dut, conn, SIGMA_ERROR, 10194 "errorCode,Unsupported ap_send_frame_loc with the current driver"); 10195 return 0; 10196 } 10197 } 10198 10199 10200 static int ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn, 10201 struct sigma_cmd *cmd) 10202 { 10203 switch (get_driver_type(dut)) { 10204 case DRIVER_ATHEROS: 10205 return ath_ap_send_frame_mbo(dut, conn, cmd); 10206 case DRIVER_OPENWRT: 10207 switch (get_openwrt_driver_type()) { 10208 case OPENWRT_DRIVER_ATHEROS: 10209 return ath_ap_send_frame_mbo(dut, conn, cmd); 10210 default: 10211 send_resp(dut, conn, SIGMA_ERROR, 10212 "errorCode,Unsupported ap_send_frame with the current openwrt driver"); 10213 return 0; 10214 } 10215 default: 10216 send_resp(dut, conn, SIGMA_ERROR, 10217 "errorCode,Unsupported ap_send_frame with the current driver"); 10218 return 0; 10219 } 10220 } 10221 10222 10223 static int ap_send_frame_60g(struct sigma_dut *dut, 10224 struct sigma_conn *conn, 10225 struct sigma_cmd *cmd) 10226 { 10227 switch (get_driver_type(dut)) { 10228 #ifdef __linux__ 10229 case DRIVER_WIL6210: 10230 return wil6210_send_frame_60g(dut, conn, cmd); 10231 #endif /* __linux__ */ 10232 default: 10233 send_resp(dut, conn, SIGMA_ERROR, 10234 "errorCode,Unsupported sta_set_frame(60G) with the current driver"); 10235 return 0; 10236 } 10237 } 10238 10239 10240 enum sigma_cmd_result cmd_ap_send_frame(struct sigma_dut *dut, 10241 struct sigma_conn *conn, 10242 struct sigma_cmd *cmd) 10243 { 10244 /* const char *name = get_param(cmd, "NAME"); */ 10245 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 10246 const char *val; 10247 enum send_frame_type frame; 10248 enum send_frame_protection protected; 10249 char buf[100]; 10250 10251 val = get_param(cmd, "Program"); 10252 if (val) { 10253 if (strcasecmp(val, "HS2") == 0 || 10254 strcasecmp(val, "HS2-R2") == 0 || 10255 strcasecmp(val, "IOTLP") == 0) 10256 return ap_send_frame_hs2(dut, conn, cmd); 10257 if (strcasecmp(val, "VHT") == 0) 10258 return ap_send_frame_vht(dut, conn, cmd); 10259 if (strcasecmp(val, "LOC") == 0) 10260 return ap_send_frame_loc(dut, conn, cmd); 10261 if (strcasecmp(val, "MBO") == 0) 10262 return ap_send_frame_mbo(dut, conn, cmd); 10263 if (strcasecmp(val, "60GHz") == 0) 10264 return ap_send_frame_60g(dut, conn, cmd); 10265 } 10266 10267 val = get_param(cmd, "PMFFrameType"); 10268 if (val == NULL) 10269 val = get_param(cmd, "FrameName"); 10270 if (val == NULL) 10271 val = get_param(cmd, "Type"); 10272 if (val == NULL) 10273 return -1; 10274 if (strcasecmp(val, "disassoc") == 0) 10275 frame = DISASSOC; 10276 else if (strcasecmp(val, "deauth") == 0) 10277 frame = DEAUTH; 10278 else if (strcasecmp(val, "saquery") == 0) 10279 frame = SAQUERY; 10280 else { 10281 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported " 10282 "PMFFrameType"); 10283 return 0; 10284 } 10285 10286 val = get_param(cmd, "PMFProtected"); 10287 if (val == NULL) 10288 val = get_param(cmd, "Protected"); 10289 if (val == NULL) 10290 return -1; 10291 if (strcasecmp(val, "Correct-key") == 0 || 10292 strcasecmp(val, "CorrectKey") == 0) 10293 protected = CORRECT_KEY; 10294 else if (strcasecmp(val, "IncorrectKey") == 0) 10295 protected = INCORRECT_KEY; 10296 else if (strcasecmp(val, "Unprotected") == 0) 10297 protected = UNPROTECTED; 10298 else { 10299 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported " 10300 "PMFProtected"); 10301 return 0; 10302 } 10303 10304 val = get_param(cmd, "stationID"); 10305 if (val == NULL) 10306 return -1; 10307 10308 if (protected == INCORRECT_KEY || 10309 (protected == UNPROTECTED && frame == SAQUERY)) 10310 return ap_inject_frame(dut, conn, frame, protected, val); 10311 10312 switch (frame) { 10313 case DISASSOC: 10314 snprintf(buf, sizeof(buf), "disassoc %s test=%d", 10315 val, protected == CORRECT_KEY); 10316 break; 10317 case DEAUTH: 10318 snprintf(buf, sizeof(buf), "deauth %s test=%d", 10319 val, protected == CORRECT_KEY); 10320 break; 10321 case SAQUERY: 10322 snprintf(buf, sizeof(buf), "sa_query %s", val); 10323 break; 10324 } 10325 10326 if (run_hostapd_cli(dut, buf) != 0) 10327 return -2; 10328 10329 return 1; 10330 } 10331 10332 10333 static enum sigma_cmd_result cmd_ap_get_mac_address(struct sigma_dut *dut, 10334 struct sigma_conn *conn, 10335 struct sigma_cmd *cmd) 10336 { 10337 #if defined( __linux__) 10338 /* const char *name = get_param(cmd, "NAME"); */ 10339 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 10340 char resp[100]; 10341 unsigned char addr[6]; 10342 char ifname[50]; 10343 struct ifreq ifr; 10344 int s, wlan_tag = 1; 10345 const char *val; 10346 10347 val = get_param(cmd, "WLAN_TAG"); 10348 if (val) { 10349 wlan_tag = atoi(val); 10350 if (wlan_tag < 1 || wlan_tag > 3) { 10351 /* 10352 * The only valid WLAN Tags as of now as per the latest 10353 * WFA scripts are 1, 2, and 3. 10354 */ 10355 send_resp(dut, conn, SIGMA_ERROR, 10356 "errorCode,Unsupported WLAN_TAG"); 10357 return 0; 10358 } 10359 } 10360 10361 get_if_name(dut, ifname, sizeof(ifname), wlan_tag); 10362 10363 s = socket(AF_INET, SOCK_DGRAM, 0); 10364 if (s < 0) 10365 return -1; 10366 memset(&ifr, 0, sizeof(ifr)); 10367 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 10368 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { 10369 perror("ioctl"); 10370 close(s); 10371 snprintf(resp, sizeof(resp), 10372 "errorCode,Could not find interface %s", ifname); 10373 send_resp(dut, conn, SIGMA_ERROR, resp); 10374 return 0; 10375 } 10376 close(s); 10377 memcpy(addr, ifr.ifr_hwaddr.sa_data, 6); 10378 10379 snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x", 10380 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 10381 send_resp(dut, conn, SIGMA_COMPLETE, resp); 10382 return 0; 10383 #elif defined( __QNXNTO__) 10384 char resp[50]; 10385 unsigned char addr[6]; 10386 10387 if (!dut->main_ifname) { 10388 send_resp(dut, conn, SIGMA_ERROR, "ifname is null"); 10389 return 0; 10390 } 10391 10392 if (get_hwaddr(get_main_ifname(dut), addr) != 0) { 10393 send_resp(dut, conn, SIGMA_ERROR, 10394 "errorCode,Failed to get address"); 10395 return 0; 10396 } 10397 snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x", 10398 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 10399 send_resp(dut, conn, SIGMA_COMPLETE, resp); 10400 return 0; 10401 #else /* __linux__ */ 10402 send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_get_mac_address not " 10403 "yet supported"); 10404 return 0; 10405 #endif /* __linux__ */ 10406 } 10407 10408 10409 int sta_cfon_get_mac_address(struct sigma_dut *dut, struct sigma_conn *conn, 10410 struct sigma_cmd *cmd) 10411 { 10412 return cmd_ap_get_mac_address(dut, conn, cmd); 10413 } 10414 10415 10416 static enum sigma_cmd_result cmd_ap_set_pmf(struct sigma_dut *dut, 10417 struct sigma_conn *conn, 10418 struct sigma_cmd *cmd) 10419 { 10420 /* 10421 * Ignore the command since the parameters are already handled through 10422 * ap_set_security. 10423 */ 10424 10425 return 1; 10426 } 10427 10428 10429 static enum sigma_cmd_result cmd_ap_set_hs2(struct sigma_dut *dut, 10430 struct sigma_conn *conn, 10431 struct sigma_cmd *cmd) 10432 { 10433 /* const char *name = get_param(cmd, "NAME"); */ 10434 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 10435 const char *val, *dest; 10436 char *pos, buf[100]; 10437 int i, wlan_tag = 1, res; 10438 10439 sigma_dut_print(dut, DUT_MSG_INFO, "ap_set_hs2: Processing the " 10440 "following parameters"); 10441 for (i = 0; i < cmd->count; i++) { 10442 sigma_dut_print(dut, DUT_MSG_INFO, "%s %s", cmd->params[i], 10443 (cmd->values[i] ? cmd->values[i] : "NULL")); 10444 } 10445 10446 val = get_param(cmd, "ICMPv4_ECHO"); 10447 if (val && atoi(val)) { 10448 snprintf(buf, sizeof(buf), "ebtables -F"); 10449 if (system(buf) != 0) { 10450 sigma_dut_print(dut, DUT_MSG_ERROR, 10451 "Failed to set ebtables rules, RULE-12"); 10452 } 10453 return 1; 10454 } 10455 10456 val = get_param(cmd, "WLAN_TAG"); 10457 if (val) { 10458 wlan_tag = atoi(val); 10459 if (wlan_tag != 1 && wlan_tag != 2) { 10460 send_resp(dut, conn, SIGMA_INVALID, 10461 "errorCode,Invalid WLAN_TAG"); 10462 return 0; 10463 } 10464 } 10465 10466 if (wlan_tag == 2) { 10467 val = get_param(cmd, "PROXY_ARP"); 10468 if (val) 10469 dut->ap2_proxy_arp = atoi(val); 10470 10471 val = get_param(cmd, "OSU"); 10472 if (val) 10473 dut->ap2_osu = atoi(val); 10474 return 1; 10475 } 10476 10477 dest = get_param(cmd, "STA_MAC"); 10478 if (dest) { 10479 /* This is a special/ugly way of using this command. 10480 * If "Dest" MAC is included, assume that this command 10481 * is being issued after ap_config_commit for dynamically 10482 * setting the QoS Map Set. 10483 */ 10484 val = get_param(cmd, "QoS_MAP_SET"); 10485 if (val) { 10486 dut->ap_qos_map_set = atoi(val); 10487 sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d", 10488 dut->ap_qos_map_set); 10489 } 10490 10491 if (dut->ap_qos_map_set == 1) 10492 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1); 10493 else if (dut->ap_qos_map_set == 2) 10494 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2); 10495 10496 snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest); 10497 if (run_hostapd_cli(dut, buf) != 0) 10498 return -1; 10499 } 10500 10501 val = get_param(cmd, "DGAF_DISABLE"); 10502 if (val) 10503 dut->ap_dgaf_disable = atoi(val); 10504 10505 dut->ap_interworking = 1; 10506 10507 val = get_param(cmd, "INTERWORKING"); 10508 if (val == NULL) 10509 val = get_param(cmd, "INTERNETWORKING"); 10510 if (val != NULL && atoi(val) == 0) { 10511 dut->ap_interworking = 0; 10512 dut->ap_hs2 = 0; 10513 return 1; 10514 } 10515 10516 val = get_param(cmd, "ACCS_NET_TYPE"); 10517 if (val) { 10518 if (strcasecmp(val, "Chargeable_Public_Network") == 0 || 10519 strcasecmp(val, "Chargable_Public_Network") == 0 || 10520 strcasecmp(val, "Chargable Public Network") == 0) 10521 dut->ap_access_net_type = 2; 10522 else 10523 dut->ap_access_net_type = atoi(val); 10524 } 10525 10526 val = get_param(cmd, "INTERNET"); 10527 if (val) 10528 dut->ap_internet = atoi(val); 10529 10530 val = get_param(cmd, "VENUE_GRP"); 10531 if (val) { 10532 if (strcasecmp(val, "Business") == 0) 10533 dut->ap_venue_group = 2; 10534 else 10535 dut->ap_venue_group = atoi(val); 10536 sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d", 10537 dut->ap_venue_name); 10538 } 10539 10540 val = get_param(cmd, "VENUE_TYPE"); 10541 if (val) { 10542 if (strcasecmp(val, "R&D") == 0) 10543 dut->ap_venue_type = 8; 10544 else 10545 dut->ap_venue_type = atoi(val); 10546 sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_type %d", 10547 dut->ap_venue_type); 10548 } 10549 10550 val = get_param(cmd, "HESSID"); 10551 if (val) { 10552 if (strlen(val) >= sizeof(dut->ap_hessid)) { 10553 send_resp(dut, conn, SIGMA_ERROR, 10554 "errorCode,Invalid HESSID"); 10555 return 0; 10556 } 10557 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), "%s", val); 10558 sigma_dut_print(dut, DUT_MSG_INFO, "ap_hessid %s", 10559 dut->ap_hessid); 10560 } 10561 10562 val = get_param(cmd, "ROAMING_CONS"); 10563 if (val) { 10564 if (strlen(val) >= sizeof(dut->ap_roaming_cons)) { 10565 send_resp(dut, conn, SIGMA_ERROR, 10566 "errorCode,Invalid ROAMING_CONS"); 10567 return 0; 10568 } 10569 if (strcasecmp(val, "Disabled") == 0) { 10570 dut->ap_roaming_cons[0] = '\0'; 10571 } else { 10572 snprintf(dut->ap_roaming_cons, 10573 sizeof(dut->ap_roaming_cons), "%s", val); 10574 } 10575 sigma_dut_print(dut, DUT_MSG_INFO, "ap_roaming_cons %s", 10576 dut->ap_roaming_cons); 10577 } 10578 10579 val = get_param(cmd, "ANQP"); 10580 if (val) 10581 dut->ap_anqpserver_on = atoi(val); 10582 10583 val = get_param(cmd, "NAI_REALM_LIST"); 10584 if (val) { 10585 dut->ap_nai_realm_list = atoi(val); 10586 sigma_dut_print(dut, DUT_MSG_INFO, "ap_nai_realm_list %d", 10587 dut->ap_nai_realm_list); 10588 } 10589 10590 val = get_param(cmd, "3GPP_INFO"); 10591 if (val) { 10592 /* What kind of encoding format is used?! */ 10593 send_resp(dut, conn, SIGMA_ERROR, "errorCode,3GPP_INFO " 10594 "not yet supported (contents not fully defined)"); 10595 return 0; 10596 } 10597 10598 val = get_param(cmd, "DOMAIN_LIST"); 10599 if (val) { 10600 if (strlen(val) >= sizeof(dut->ap_domain_name_list)) { 10601 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Too long " 10602 "DOMAIN_LIST"); 10603 return 0; 10604 } 10605 snprintf(dut->ap_domain_name_list, 10606 sizeof(dut->ap_domain_name_list), "%s", val); 10607 pos = dut->ap_domain_name_list; 10608 while (*pos) { 10609 if (*pos == ';') 10610 *pos = ','; 10611 pos++; 10612 } 10613 sigma_dut_print(dut, DUT_MSG_INFO, "ap_domain_name_list %s", 10614 dut->ap_domain_name_list); 10615 } 10616 10617 val = get_param(cmd, "OPER_NAME"); 10618 if (val) { 10619 dut->ap_oper_name = atoi(val); 10620 sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_name %d", 10621 dut->ap_oper_name); 10622 } 10623 10624 val = get_param(cmd, "VENUE_NAME"); 10625 if (val) { 10626 dut->ap_venue_name = atoi(val); 10627 sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d", 10628 dut->ap_venue_name); 10629 } 10630 10631 val = get_param(cmd, "GAS_CB_DELAY"); 10632 if (val) { 10633 dut->ap_gas_cb_delay = atoi(val); 10634 sigma_dut_print(dut, DUT_MSG_INFO, "ap_gas_cb_delay %d", 10635 dut->ap_gas_cb_delay); 10636 } 10637 10638 val = get_param(cmd, "MIH"); 10639 if (val && atoi(val) > 0) { 10640 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MIH not " 10641 "supported"); 10642 return 0; 10643 } 10644 10645 val = get_param(cmd, "L2_TRAFFIC_INSPECT"); 10646 if (val) { 10647 dut->ap_l2tif = atoi(val); 10648 sigma_dut_print(dut, DUT_MSG_INFO, "ap_l2tif %d", 10649 dut->ap_l2tif); 10650 } 10651 10652 val = get_param(cmd, "BCST_UNCST"); 10653 if (val) { 10654 send_resp(dut, conn, SIGMA_ERROR, 10655 "errorCode,BCST_UNCST not yet supported"); 10656 return 0; 10657 } 10658 10659 val = get_param(cmd, "PLMN_MCC"); 10660 if (val) { 10661 char mcc[100], *start, *end; 10662 int i = 0; 10663 if (strlen(val) >= sizeof(mcc)) { 10664 send_resp(dut, conn, SIGMA_ERROR, 10665 "errorCode,PLMN_MCC too long"); 10666 return 0; 10667 } 10668 strlcpy(mcc, val, sizeof(mcc)); 10669 start = mcc; 10670 while ((end = strchr(start, ';'))) { 10671 /* process all except the last */ 10672 *end = '\0'; 10673 if (strlen(start) != 3) { 10674 send_resp(dut, conn, SIGMA_ERROR, 10675 "errorCode,Invalid PLMN_MCC"); 10676 return 0; 10677 } 10678 res = snprintf(dut->ap_plmn_mcc[i], 10679 sizeof(dut->ap_plmn_mcc[i]), "%s", 10680 start); 10681 if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i])) 10682 return ERROR_SEND_STATUS; 10683 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s", 10684 dut->ap_plmn_mcc[i]); 10685 i++; 10686 start = end + 1; 10687 *end = ';'; 10688 } 10689 if (strlen(start) != 3) { 10690 send_resp(dut, conn, SIGMA_ERROR, 10691 "errorCode,Invalid PLMN_MCC"); 10692 return 0; 10693 } 10694 /* process last or only one */ 10695 res = snprintf(dut->ap_plmn_mcc[i], 10696 sizeof(dut->ap_plmn_mcc[i]), "%s", start); 10697 if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i])) 10698 return ERROR_SEND_STATUS; 10699 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s", 10700 dut->ap_plmn_mcc[i]); 10701 } 10702 10703 val = get_param(cmd, "PLMN_MNC"); 10704 if (val) { 10705 char mnc[100], *start, *end; 10706 int i = 0; 10707 if (strlen(val) >= sizeof(mnc)) { 10708 send_resp(dut, conn, SIGMA_ERROR, 10709 "errorCode,PLMN_MNC too long"); 10710 return 0; 10711 } 10712 strlcpy(mnc, val, sizeof(mnc)); 10713 start = mnc; 10714 while ((end = strchr(start, ';'))) { 10715 *end = '\0'; 10716 if (strlen(start) != 2 && strlen(start) != 3) { 10717 send_resp(dut, conn, SIGMA_ERROR, 10718 "errorCode,Invalid PLMN_MNC"); 10719 return 0; 10720 } 10721 res = snprintf(dut->ap_plmn_mnc[i], 10722 sizeof(dut->ap_plmn_mnc[i]), "%s", 10723 start); 10724 if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i])) 10725 return ERROR_SEND_STATUS; 10726 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s", 10727 dut->ap_plmn_mnc[i]); 10728 i++; 10729 start = end + 1; 10730 *end = ';'; 10731 } 10732 if (strlen(start) != 2 && strlen(start) != 3) { 10733 send_resp(dut, conn, SIGMA_ERROR, 10734 "errorCode,Invalid PLMN_MNC"); 10735 return 0; 10736 } 10737 res = snprintf(dut->ap_plmn_mnc[i], 10738 sizeof(dut->ap_plmn_mnc[i]), "%s", start); 10739 if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i])) 10740 return ERROR_SEND_STATUS; 10741 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s", 10742 dut->ap_plmn_mnc[i]); 10743 } 10744 10745 val = get_param(cmd, "PROXY_ARP"); 10746 if (val) { 10747 dut->ap_proxy_arp = atoi(val); 10748 sigma_dut_print(dut, DUT_MSG_INFO, "ap_proxy_arp %d", 10749 dut->ap_proxy_arp); 10750 } 10751 10752 val = get_param(cmd, "WAN_METRICS"); 10753 if (val) { 10754 dut->ap_wan_metrics = atoi(val); 10755 sigma_dut_print(dut, DUT_MSG_INFO, "ap_wan_metrics %d", 10756 dut->ap_wan_metrics); 10757 } 10758 10759 val = get_param(cmd, "CONN_CAP"); 10760 if (val) { 10761 dut->ap_conn_capab = atoi(val); 10762 sigma_dut_print(dut, DUT_MSG_INFO, "ap_conn_capab %d", 10763 dut->ap_conn_capab); 10764 } 10765 10766 val = get_param(cmd, "IP_ADD_TYPE_AVAIL"); 10767 if (val) { 10768 dut->ap_ip_addr_type_avail = atoi(val); 10769 sigma_dut_print(dut, DUT_MSG_INFO, "ap_ip_addr_type_avail %d", 10770 dut->ap_ip_addr_type_avail); 10771 } 10772 10773 val = get_param(cmd, "NET_AUTH_TYPE"); 10774 if (val) { 10775 dut->ap_net_auth_type = atoi(val); 10776 sigma_dut_print(dut, DUT_MSG_INFO, "ap_net_auth_type %d", 10777 dut->ap_net_auth_type); 10778 } 10779 10780 val = get_param(cmd, "OP_CLASS"); 10781 if (val == NULL) 10782 val = get_param(cmd, "OPER_CLASS"); 10783 if (val) { 10784 dut->ap_oper_class = atoi(val); 10785 sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_class %d", 10786 dut->ap_oper_class); 10787 } 10788 10789 val = get_param(cmd, "OSU_PROVIDER_LIST"); 10790 if (val) { 10791 dut->ap_osu_provider_list = atoi(val); 10792 sigma_dut_print(dut, DUT_MSG_INFO, "ap_osu_provider_list %d", 10793 dut->ap_osu_provider_list); 10794 } 10795 10796 val = get_param(cmd, "OSU_PROVIDER_NAI_LIST"); 10797 if (val) { 10798 dut->ap_osu_provider_nai_list = atoi(val); 10799 sigma_dut_print(dut, DUT_MSG_INFO, 10800 "ap_osu_provider_nai_list %d", 10801 dut->ap_osu_provider_nai_list); 10802 } 10803 10804 val = get_param(cmd, "OSU_SERVER_URI"); 10805 if (val) { 10806 i = 0; 10807 do { 10808 int len; 10809 const char *uri = val; 10810 val = strchr(val, ' '); 10811 len = val ? (val++ - uri) : (int) strlen(uri); 10812 if (len > 0 && len < 256) { 10813 memcpy(dut->ap_osu_server_uri[i], uri, len); 10814 dut->ap_osu_server_uri[i][len] = '\0'; 10815 sigma_dut_print(dut, DUT_MSG_INFO, 10816 "ap_osu_server_uri[%d] %s", i, 10817 dut->ap_osu_server_uri[i]); 10818 } 10819 } while (val && ++i < 10); 10820 } 10821 10822 val = get_param(cmd, "OSU_METHOD"); 10823 if (val) { 10824 i = 0; 10825 do { 10826 int len; 10827 const char *method = val; 10828 val = strchr(val, ' '); 10829 len = val ? (val++ - method) : (int) strlen(method); 10830 if (len > 0) { 10831 if (strncasecmp(method, "SOAP", len) == 0) 10832 dut->ap_osu_method[i] = 1; 10833 else if (strncasecmp(method, "OMADM", len) == 0) 10834 dut->ap_osu_method[i] = 0; 10835 else 10836 return -2; 10837 } 10838 } while (val && ++i < 10); 10839 } 10840 10841 val = get_param(cmd, "OSU_SSID"); 10842 if (val) { 10843 if (strlen(val) > 0 && strlen(val) <= 32) { 10844 strlcpy(dut->ap_osu_ssid, val, 10845 sizeof(dut->ap_osu_ssid)); 10846 sigma_dut_print(dut, DUT_MSG_INFO, 10847 "ap_osu_ssid %s", 10848 dut->ap_osu_ssid); 10849 } 10850 } 10851 10852 val = get_param(cmd, "OSU_ICON_TAG"); 10853 if (val) 10854 dut->ap_osu_icon_tag = atoi(val); 10855 10856 val = get_param(cmd, "QoS_MAP_SET"); 10857 if (val) { 10858 dut->ap_qos_map_set = atoi(val); 10859 sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d", 10860 dut->ap_qos_map_set); 10861 } 10862 10863 val = get_param(cmd, "BSS_LOAD"); 10864 if (val) { 10865 dut->ap_bss_load = atoi(val); 10866 sigma_dut_print(dut, DUT_MSG_INFO, "ap_bss_load %d", 10867 dut->ap_bss_load); 10868 } 10869 10870 val = get_param(cmd, "Venue_URL"); 10871 if (val) 10872 dut->ap_venue_url = atoi(val); 10873 10874 val = get_param(cmd, "Advice_of_Charge"); 10875 if (val) 10876 dut->ap_advice_of_charge = atoi(val); 10877 10878 val = get_param(cmd, "Operator_Icon_Metadata"); 10879 if (val) 10880 dut->ap_oper_icon_metadata = atoi(val); 10881 10882 val = get_param(cmd, "TnC_File_Name"); 10883 if (val) 10884 dut->ap_tnc_file_name = atoi(val); 10885 10886 val = get_param(cmd, "TnC_File_Time_Stamp"); 10887 if (val) 10888 dut->ap_tnc_time_stamp = strtol(val, NULL, 10); 10889 10890 return 1; 10891 } 10892 10893 10894 void nfc_status(struct sigma_dut *dut, const char *state, const char *oper) 10895 { 10896 char buf[100]; 10897 10898 if (!file_exists("nfc-status")) 10899 return; 10900 10901 snprintf(buf, sizeof(buf), "./nfc-status %s %s", state, oper); 10902 run_system(dut, buf); 10903 } 10904 10905 10906 static int run_nfc_command(struct sigma_dut *dut, const char *cmd, 10907 const char *info) 10908 { 10909 int res; 10910 10911 printf("\n\n\n=====[ NFC operation ]=========================\n\n"); 10912 printf("%s\n\n", info); 10913 10914 nfc_status(dut, "START", info); 10915 res = run_system(dut, cmd); 10916 nfc_status(dut, res ? "FAIL" : "SUCCESS", info); 10917 if (res) { 10918 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s': %d", 10919 cmd, res); 10920 return res; 10921 } 10922 10923 return 0; 10924 } 10925 10926 10927 static int ap_nfc_write_config_token(struct sigma_dut *dut, 10928 struct sigma_conn *conn, 10929 struct sigma_cmd *cmd) 10930 { 10931 int res; 10932 char buf[300]; 10933 10934 run_system(dut, "killall wps-ap-nfc.py"); 10935 unlink("nfc-success"); 10936 snprintf(buf, sizeof(buf), 10937 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-config", 10938 dut->summary_log ? "--summary " : "", 10939 dut->summary_log ? dut->summary_log : ""); 10940 res = run_nfc_command(dut, buf, 10941 "Touch NFC Tag to write WPS configuration token"); 10942 if (res || !file_exists("nfc-success")) { 10943 send_resp(dut, conn, SIGMA_ERROR, 10944 "ErrorCode,Failed to write tag"); 10945 return 0; 10946 } 10947 10948 return 1; 10949 } 10950 10951 10952 static int ap_nfc_wps_read_passwd(struct sigma_dut *dut, 10953 struct sigma_conn *conn, 10954 struct sigma_cmd *cmd) 10955 { 10956 int res; 10957 char buf[300]; 10958 10959 run_system(dut, "killall wps-ap-nfc.py"); 10960 10961 unlink("nfc-success"); 10962 snprintf(buf, sizeof(buf), 10963 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success", 10964 dut->summary_log ? "--summary " : "", 10965 dut->summary_log ? dut->summary_log : ""); 10966 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it"); 10967 if (res || !file_exists("nfc-success")) { 10968 send_resp(dut, conn, SIGMA_ERROR, 10969 "ErrorCode,Failed to read tag"); 10970 return 0; 10971 } 10972 10973 return 1; 10974 } 10975 10976 10977 static int ap_nfc_write_password_token(struct sigma_dut *dut, 10978 struct sigma_conn *conn, 10979 struct sigma_cmd *cmd) 10980 { 10981 int res; 10982 char buf[300]; 10983 10984 run_system(dut, "killall wps-ap-nfc.py"); 10985 unlink("nfc-success"); 10986 snprintf(buf, sizeof(buf), 10987 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-password", 10988 dut->summary_log ? "--summary " : "", 10989 dut->summary_log ? dut->summary_log : ""); 10990 res = run_nfc_command(dut, buf, 10991 "Touch NFC Tag to write WPS password token"); 10992 if (res || !file_exists("nfc-success")) { 10993 send_resp(dut, conn, SIGMA_ERROR, 10994 "ErrorCode,Failed to write tag"); 10995 return 0; 10996 } 10997 10998 if (run_hostapd_cli(dut, "wps_nfc_token enable") != 0) { 10999 send_resp(dut, conn, SIGMA_ERROR, 11000 "ErrorCode,Failed to enable NFC password token"); 11001 return 0; 11002 } 11003 11004 return 1; 11005 } 11006 11007 11008 static int ap_nfc_wps_connection_handover(struct sigma_dut *dut, 11009 struct sigma_conn *conn, 11010 struct sigma_cmd *cmd) 11011 { 11012 int res; 11013 char buf[300]; 11014 11015 run_system(dut, "killall wps-ap-nfc.py"); 11016 unlink("nfc-success"); 11017 snprintf(buf, sizeof(buf), 11018 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success", 11019 dut->summary_log ? "--summary " : "", 11020 dut->summary_log ? dut->summary_log : ""); 11021 res = run_nfc_command(dut, buf, 11022 "Touch NFC Device to respond to WPS connection handover"); 11023 if (res) { 11024 send_resp(dut, conn, SIGMA_ERROR, 11025 "ErrorCode,Failed to enable NFC for connection " 11026 "handover"); 11027 return 0; 11028 } 11029 if (!file_exists("nfc-success")) { 11030 send_resp(dut, conn, SIGMA_ERROR, 11031 "ErrorCode,Failed to complete NFC connection handover"); 11032 return 0; 11033 } 11034 11035 return 1; 11036 } 11037 11038 11039 static enum sigma_cmd_result cmd_ap_nfc_action(struct sigma_dut *dut, 11040 struct sigma_conn *conn, 11041 struct sigma_cmd *cmd) 11042 { 11043 /* const char *name = get_param(cmd, "Name"); */ 11044 /* const char *intf = get_param(cmd, "Interface"); */ 11045 const char *oper = get_param(cmd, "Operation"); 11046 11047 if (oper == NULL) 11048 return -1; 11049 11050 if (strcasecmp(oper, "WRITE_CONFIG") == 0) 11051 return ap_nfc_write_config_token(dut, conn, cmd); 11052 if (strcasecmp(oper, "WRITE_PASSWD") == 0) 11053 return ap_nfc_write_password_token(dut, conn, cmd); 11054 if (strcasecmp(oper, "WPS_READ_PASSWD") == 0) 11055 return ap_nfc_wps_read_passwd(dut, conn, cmd); 11056 if (strcasecmp(oper, "WPS_CONN_HNDOVR") == 0) 11057 return ap_nfc_wps_connection_handover(dut, conn, cmd); 11058 11059 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported operation"); 11060 return 0; 11061 } 11062 11063 11064 static enum sigma_cmd_result cmd_ap_wps_read_pin(struct sigma_dut *dut, 11065 struct sigma_conn *conn, 11066 struct sigma_cmd *cmd) 11067 { 11068 char *pin = "12345670"; /* TODO: use random PIN */ 11069 char resp[100]; 11070 11071 snprintf(resp, sizeof(resp), "PIN,%s", pin); 11072 send_resp(dut, conn, SIGMA_COMPLETE, resp); 11073 11074 return 0; 11075 } 11076 11077 11078 static enum sigma_cmd_result cmd_ap_wps_enter_pin(struct sigma_dut *dut, 11079 struct sigma_conn *conn, 11080 struct sigma_cmd *cmd) 11081 { 11082 const char *pin = get_param(cmd, "PIN"); 11083 char wps_pin[11]; 11084 11085 if (!pin) 11086 return -1; 11087 11088 sigma_dut_print(dut, DUT_MSG_DEBUG, 11089 "Authorize a client to join with WPS PIN %s", pin); 11090 11091 strlcpy(wps_pin, pin, sizeof(wps_pin)); 11092 /* we need to tolerate extra '-' characters entered */ 11093 str_remove_chars(wps_pin, '-'); 11094 strlcpy(dut->wps_pin, wps_pin, sizeof(dut->wps_pin)); 11095 dut->wps_method = WFA_CS_WPS_PIN_KEYPAD; 11096 11097 return 1; 11098 } 11099 11100 11101 static enum sigma_cmd_result cmd_ap_wps_set_pbc(struct sigma_dut *dut, 11102 struct sigma_conn *conn, 11103 struct sigma_cmd *cmd) 11104 { 11105 sigma_dut_print(dut, DUT_MSG_DEBUG, 11106 "Selecting the push button configuration method"); 11107 11108 dut->wps_method = WFA_CS_WPS_PBC; 11109 11110 return 1; 11111 } 11112 11113 11114 int ap_wps_registration(struct sigma_dut *dut, struct sigma_conn *conn, 11115 struct sigma_cmd *cmd) 11116 { 11117 char buf[100], resp[256]; 11118 const char *intf = get_param(cmd, "interface"); 11119 const char *config_method = get_param(cmd, "WPSConfigMethod"); 11120 11121 if (config_method && strcasecmp(config_method, "PBC") == 0) 11122 dut->wps_method = WFA_CS_WPS_PBC; 11123 11124 if (!intf) 11125 intf = get_main_ifname(dut); 11126 11127 if (dut->wps_method == WFA_CS_WPS_NOT_READY) { 11128 send_resp(dut, conn, SIGMA_ERROR, 11129 "ErrorCode,WPS parameters not yet set"); 11130 return STATUS_SENT; 11131 } 11132 11133 if (dut->wps_method == WFA_CS_WPS_PBC) 11134 snprintf(buf, sizeof(buf), "WPS_PBC"); 11135 else /* WFA_CS_WPS_PIN_KEYPAD */ 11136 snprintf(buf, sizeof(buf), "WPS_PIN any %s", dut->wps_pin); 11137 11138 /* Run WPS command */ 11139 if (hapd_command(intf, buf) < 0) { 11140 /* command fails immediately if overlapped session detected */ 11141 snprintf(resp, sizeof(resp), "WpsState,OverlapSession"); 11142 send_resp(dut, conn, SIGMA_COMPLETE, resp); 11143 return STATUS_SENT; 11144 } 11145 11146 /* In AP mode return immediately and do not wait for WPS registration */ 11147 return SUCCESS_SEND_STATUS; 11148 } 11149 11150 11151 static enum sigma_cmd_result cmd_ap_get_parameter(struct sigma_dut *dut, 11152 struct sigma_conn *conn, 11153 struct sigma_cmd *cmd) 11154 { 11155 char value[256], resp[512]; 11156 const char *param = get_param(cmd, "parameter"); 11157 const char *ifname = get_param(cmd, "Interface"); 11158 const char *var; 11159 11160 if (!ifname) 11161 ifname = get_main_ifname(dut); 11162 11163 if (!param) { 11164 send_resp(dut, conn, SIGMA_ERROR, 11165 "ErrorCode,Parameter not specified"); 11166 return 0; 11167 } 11168 11169 if (strcasecmp(param, "SSID") == 0) { 11170 if (get_hapd_config(ifname, "ssid", value, sizeof(value))) { 11171 sigma_dut_print(dut, DUT_MSG_ERROR, 11172 "Failed to get SSID"); 11173 return -2; 11174 } 11175 snprintf(resp, sizeof(resp), "SSID,%s", value); 11176 } else if (strcasecmp(param, "PSK") == 0) { 11177 if (get_hapd_config(ifname, "passphrase", value, 11178 sizeof(value))) { 11179 sigma_dut_print(dut, DUT_MSG_ERROR, 11180 "Failed to get PSK"); 11181 return -2; 11182 } 11183 snprintf(resp, sizeof(resp), "PSK,%s", value); 11184 } else if (strcasecmp(param, "PMK") == 0) { 11185 var = get_param(cmd, "STA_MAC_Address"); 11186 if (!var) 11187 return INVALID_SEND_STATUS; 11188 snprintf(resp, sizeof(resp), "GET_PMK %s", var); 11189 if (hapd_command_resp(ifname, resp, &resp[4], 11190 sizeof(resp) - 4) < 0) { 11191 send_resp(dut, conn, SIGMA_ERROR, 11192 "ErrorCode,GET_PMK failed"); 11193 return STATUS_SENT_ERROR; 11194 } 11195 memcpy(resp, "PMK,", 4); 11196 } else { 11197 send_resp(dut, conn, SIGMA_ERROR, 11198 "ErrorCode,Unsupported parameter"); 11199 return 0; 11200 } 11201 11202 send_resp(dut, conn, SIGMA_COMPLETE, resp); 11203 return 0; 11204 } 11205 11206 11207 static int ath_vht_op_mode_notif(struct sigma_dut *dut, const char *ifname, 11208 const char *val) 11209 { 11210 char *token, *result; 11211 int nss = 0, chwidth = 0; 11212 char *saveptr; 11213 11214 /* 11215 * The following commands should be invoked to generate 11216 * VHT op mode notification 11217 */ 11218 11219 /* Extract the NSS info */ 11220 token = strdup(val); 11221 if (!token) 11222 return -1; 11223 result = strtok_r(token, ";", &saveptr); 11224 if (result) { 11225 int count = atoi(result); 11226 11227 /* We do not support NSS > 3 */ 11228 if (count < 0 || count > 3) { 11229 free(token); 11230 return -1; 11231 } 11232 11233 /* Convert nss to chainmask */ 11234 while (count--) 11235 nss = (nss << 1) | 1; 11236 11237 run_iwpriv(dut, ifname, "rxchainmask %d", nss); 11238 } 11239 11240 /* Extract the Channel width info */ 11241 result = strtok_r(NULL, ";", &saveptr); 11242 if (result) { 11243 switch (atoi(result)) { 11244 case 20: 11245 chwidth = 0; 11246 break; 11247 case 40: 11248 chwidth = 1; 11249 break; 11250 case 80: 11251 chwidth = 2; 11252 break; 11253 case 160: 11254 chwidth = 3; 11255 break; 11256 default: 11257 chwidth = 2; 11258 break; 11259 } 11260 run_iwpriv(dut, ifname, "chwidth %d", chwidth); 11261 } 11262 11263 /* Send the opmode notification */ 11264 run_iwpriv(dut, ifname, "opmode_notify 1"); 11265 free(token); 11266 11267 return 0; 11268 } 11269 11270 11271 static int ath_vht_nss_mcs(struct sigma_dut *dut, const char *ifname, 11272 const char *val) 11273 { 11274 /* String (nss_operating_mode; mcs_operating_mode) */ 11275 int nss, mcs; 11276 char *token, *result; 11277 char *saveptr; 11278 11279 token = strdup(val); 11280 if (!token) 11281 return -1; 11282 result = strtok_r(token, ";", &saveptr); 11283 if (!result) { 11284 sigma_dut_print(dut, DUT_MSG_ERROR, 11285 "VHT NSS not specified"); 11286 goto end; 11287 } 11288 if (strcasecmp(result, "def") != 0) { 11289 nss = atoi(result); 11290 11291 if (nss == 4) 11292 ath_disable_txbf(dut, ifname); 11293 11294 run_iwpriv(dut, ifname, "nss %d", nss); 11295 } else { 11296 if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1) 11297 run_iwpriv(dut, ifname, "nss 1"); 11298 if (dut->device_type == AP_testbed && 11299 dut->program == PROGRAM_HE) { 11300 nss = dut->ap_tx_streams; 11301 run_iwpriv(dut, ifname, "nss %d", nss); 11302 } 11303 } 11304 11305 result = strtok_r(NULL, ";", &saveptr); 11306 if (!result) { 11307 sigma_dut_print(dut, DUT_MSG_ERROR, 11308 "VHT MCS not specified"); 11309 goto end; 11310 } 11311 if (strcasecmp(result, "def") == 0) { 11312 if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1) 11313 run_iwpriv(dut, ifname, "vhtmcs 7"); 11314 else 11315 run_iwpriv(dut, ifname, "set11NRates 0"); 11316 if (dut->device_type == AP_testbed && 11317 dut->program == PROGRAM_HE) 11318 run_iwpriv(dut, ifname, "he_mcs 7"); 11319 } else { 11320 mcs = atoi(result); 11321 if (dut->program == PROGRAM_HE) 11322 run_iwpriv(dut, ifname, "he_mcs %d", mcs); 11323 else 11324 run_iwpriv(dut, ifname, "vhtmcs %d", mcs); 11325 } 11326 11327 end: 11328 free(token); 11329 return 0; 11330 } 11331 11332 11333 static int ath_vht_chnum_band(struct sigma_dut *dut, const char *ifname, 11334 const char *val) 11335 { 11336 char *token, *result; 11337 int channel = 36; 11338 int chwidth = 80; 11339 char *saveptr; 11340 11341 /* Extract the channel info */ 11342 token = strdup(val); 11343 if (!token) 11344 return -1; 11345 result = strtok_r(token, ";", &saveptr); 11346 if (result) 11347 channel = atoi(result); 11348 11349 /* Extract the channel width info */ 11350 result = strtok_r(NULL, ";", &saveptr); 11351 if (result) 11352 chwidth = atoi(result); 11353 11354 /* Issue the channel switch command */ 11355 run_iwpriv(dut, ifname, "doth_ch_chwidth %d 10 %d", channel, chwidth); 11356 11357 free(token); 11358 return 0; 11359 } 11360 11361 11362 static int ath_ndpa_stainfo_mac(struct sigma_dut *dut, const char *ifname, 11363 const char *val) 11364 { 11365 char buf[80]; 11366 unsigned char mac_addr[6]; 11367 11368 if (parse_mac_address(dut, val, mac_addr) < 0) 11369 return -1; 11370 11371 snprintf(buf, sizeof(buf), 11372 "wifitool %s beeliner_fw_test 92 0x%02x%02x%02x%02x", 11373 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3]); 11374 run_system(dut, buf); 11375 11376 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 93 0x%02x%02x", 11377 ifname, mac_addr[4], mac_addr[5]); 11378 run_system(dut, buf); 11379 11380 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 94 1", ifname); 11381 run_system(dut, buf); 11382 11383 return 0; 11384 } 11385 11386 11387 void novap_reset(struct sigma_dut *dut, const char *ifname, int reset) 11388 { 11389 run_iwpriv(dut, ifname, "novap_reset %d", reset); 11390 } 11391 11392 11393 static struct mbo_pref_ap * mbo_find_nebor_ap_entry(struct sigma_dut *dut, 11394 const uint8_t *mac_addr) 11395 { 11396 int i; 11397 11398 for (i = 0; i < dut->mbo_pref_ap_cnt; i++) { 11399 if (memcmp(mac_addr, dut->mbo_pref_aps[i].mac_addr, 11400 ETH_ALEN) == 0) 11401 return &dut->mbo_pref_aps[i]; 11402 } 11403 return NULL; 11404 } 11405 11406 11407 static void mbo_add_nebor_entry(struct sigma_dut *dut, const uint8_t *mac_addr, 11408 int ap_ne_class, int ap_ne_op_ch, 11409 int ap_ne_pref) 11410 { 11411 struct mbo_pref_ap *entry; 11412 uint8_t self_mac[ETH_ALEN]; 11413 char ifname[50]; 11414 11415 get_if_name(dut, ifname, sizeof(ifname), 1); 11416 get_hwaddr(ifname, self_mac); 11417 11418 if (memcmp(mac_addr, self_mac, ETH_ALEN) == 0) 11419 entry = &dut->mbo_self_ap_tuple; 11420 else 11421 entry = mbo_find_nebor_ap_entry(dut, mac_addr); 11422 11423 if (!entry) { 11424 if (dut->mbo_pref_ap_cnt >= MBO_MAX_PREF_BSSIDS) { 11425 sigma_dut_print(dut, DUT_MSG_ERROR, 11426 "Nebor AP List is full. Not adding"); 11427 return; 11428 } 11429 entry = &dut->mbo_pref_aps[dut->mbo_pref_ap_cnt]; 11430 dut->mbo_pref_ap_cnt++; 11431 memcpy(entry->mac_addr, mac_addr, ETH_ALEN); 11432 entry->ap_ne_class = -1; 11433 entry->ap_ne_op_ch = -1; 11434 entry->ap_ne_pref = -1; 11435 } 11436 if (ap_ne_class != -1) 11437 entry->ap_ne_class = ap_ne_class; 11438 if (ap_ne_op_ch != -1) 11439 entry->ap_ne_op_ch = ap_ne_op_ch; 11440 if (ap_ne_pref != -1) 11441 entry->ap_ne_pref = ap_ne_pref; 11442 } 11443 11444 11445 static int ath_set_nebor_bssid(struct sigma_dut *dut, const char *ifname, 11446 struct sigma_cmd *cmd) 11447 { 11448 unsigned char mac_addr[ETH_ALEN]; 11449 const char *val; 11450 /* 11451 * -1 is invalid value for the following 11452 * to differentiate between unset and set values 11453 * -1 => implies not set by CAPI 11454 */ 11455 int ap_ne_class = -1, ap_ne_op_ch = -1, ap_ne_pref = -1; 11456 int list_offset = dut->mbo_pref_ap_cnt; 11457 11458 if (list_offset >= MBO_MAX_PREF_BSSIDS) { 11459 sigma_dut_print(dut, DUT_MSG_ERROR, 11460 "AP Pref Entry list is full"); 11461 return -1; 11462 } 11463 11464 val = get_param(cmd, "Nebor_Op_Class"); 11465 if (val) 11466 ap_ne_class = atoi(val); 11467 11468 val = get_param(cmd, "Nebor_Op_Ch"); 11469 if (val) 11470 ap_ne_op_ch = atoi(val); 11471 11472 val = get_param(cmd, "Nebor_Pref"); 11473 if (val) 11474 ap_ne_pref = atoi(val); 11475 11476 val = get_param(cmd, "Nebor_BSSID"); 11477 if (!val || parse_mac_address(dut, val, mac_addr) < 0) 11478 return -1; 11479 11480 mbo_add_nebor_entry(dut, mac_addr, ap_ne_class, ap_ne_op_ch, 11481 ap_ne_pref); 11482 apply_mbo_pref_ap_list(dut); 11483 return 0; 11484 } 11485 11486 11487 static enum sigma_cmd_result he_ltf(struct sigma_dut *dut, 11488 struct sigma_conn *conn, 11489 const char *ifname, const char *val) 11490 { 11491 const char *var; 11492 11493 if (dut->ap_he_ulofdma == VALUE_ENABLED) 11494 var = "he_ul_ltf"; 11495 else 11496 var = "he_ltf"; 11497 11498 if (strcmp(val, "6.4") == 0) { 11499 run_iwpriv(dut, ifname, "%s 2", var); 11500 } else if (strcmp(val, "12.8") == 0) { 11501 run_iwpriv(dut, ifname, "%s 3", var); 11502 } else if (strcmp(val, "3.2") == 0) { 11503 run_iwpriv(dut, ifname, "%s 1", var); 11504 } else { 11505 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported LTF"); 11506 return STATUS_SENT_ERROR; 11507 } 11508 11509 return SUCCESS_SEND_STATUS; 11510 } 11511 11512 11513 static enum sigma_cmd_result he_shortgi(struct sigma_dut *dut, 11514 struct sigma_conn *conn, 11515 const char *ifname, 11516 const char *val) 11517 { 11518 const char *var; 11519 11520 if (dut->ap_he_ulofdma == VALUE_ENABLED) 11521 var = "he_ul_shortgi"; 11522 else 11523 var = "shortgi"; 11524 11525 if (strcmp(val, "0.8") == 0) { 11526 run_iwpriv(dut, ifname, "%s 0", var); 11527 } else if (strcmp(val, "1.6") == 0) { 11528 run_iwpriv(dut, ifname, "%s 2", var); 11529 } else if (strcmp(val, "3.2") == 0) { 11530 run_iwpriv(dut, ifname, "%s 3", var); 11531 } else { 11532 send_resp(dut, conn, SIGMA_ERROR, 11533 "errorCode,Unsupported shortGI"); 11534 return STATUS_SENT_ERROR; 11535 } 11536 11537 return SUCCESS_SEND_STATUS; 11538 } 11539 11540 11541 static enum sigma_cmd_result he_ar_gi_ltf_mask(struct sigma_dut *dut, 11542 struct sigma_conn *conn, 11543 const char *ifname, 11544 const char *val) 11545 { 11546 11547 uint32_t he_ar_gi_ltf; 11548 uint16_t he_ar_gi, he_ar_ltf; 11549 11550 if (strcmp(val, "0.4") == 0) { 11551 he_ar_gi = 0x01; 11552 } else if (strcmp(val, "0.8") == 0) { 11553 he_ar_gi = 0x02; 11554 } else if (strcmp(val, "1.6") == 0) { 11555 he_ar_gi = 0x04; 11556 } else if (strcmp(val, "3.2") == 0) { 11557 he_ar_gi = 0x08; 11558 } else { 11559 send_resp(dut, conn, SIGMA_ERROR, 11560 "errorCode,Unsupported shortGI"); 11561 return STATUS_SENT_ERROR; 11562 } 11563 11564 if (dut->ar_ltf && strcmp(dut->ar_ltf, "6.4") == 0) { 11565 he_ar_ltf = 0x02; 11566 } else if (dut->ar_ltf && strcmp(dut->ar_ltf, "12.8") == 0) { 11567 he_ar_ltf = 0x04; 11568 } else if (dut->ar_ltf && strcmp(dut->ar_ltf, "3.2") == 0) { 11569 he_ar_ltf = 0x01; 11570 } else { 11571 send_resp(dut, conn, SIGMA_ERROR, 11572 "errorCode,Unsupported LTF"); 11573 return STATUS_SENT_ERROR; 11574 } 11575 11576 he_ar_gi_ltf = (he_ar_gi << 8) | he_ar_ltf; 11577 run_iwpriv(dut, ifname, "he_ar_gi_ltf %lu", he_ar_gi_ltf); 11578 11579 return SUCCESS_SEND_STATUS; 11580 } 11581 11582 11583 static enum sigma_cmd_result he_rualloctones(struct sigma_dut *dut, 11584 struct sigma_conn *conn, 11585 const char *ifname, 11586 const char *val) 11587 { 11588 char *token, *result; 11589 int value; 11590 char *saveptr; 11591 int rualloc_type; 11592 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS; 11593 11594 token = strdup(val); 11595 if (!token) 11596 return -1; 11597 result = strtok_r(token, ":", &saveptr); 11598 if (!result) { 11599 free(token); 11600 send_resp(dut, conn, SIGMA_ERROR, 11601 "errorCode,RUAllocTones not specified"); 11602 return STATUS_SENT_ERROR; 11603 } 11604 11605 /* 11606 * ru_allocation_type can take the values of: 11607 * 1 - DL OFDMA data RU allocation 11608 * 3 - UL OFDMA data RU allocation 11609 */ 11610 rualloc_type = dut->ap_he_ulofdma == VALUE_ENABLED ? 3 : 1; 11611 11612 11613 value = atoi(result); 11614 if (value == 106) { 11615 enum value_not_set_enabled_disabled ap_he_rualloc_106_80 = 11616 VALUE_NOT_SET; 11617 11618 result = strtok_r(NULL, ":", &saveptr); 11619 if (result) { 11620 result = strtok_r(NULL, ":", &saveptr); 11621 if (result) 11622 ap_he_rualloc_106_80 = VALUE_ENABLED; 11623 else 11624 ap_he_rualloc_106_80 = VALUE_DISABLED; 11625 } 11626 if (ap_he_rualloc_106_80 == VALUE_ENABLED) { 11627 run_system_wrapper(dut, 11628 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 2 1 2 2 2 3 2", 11629 ifname, rualloc_type); 11630 } else { 11631 run_system_wrapper(dut, 11632 "wifitool %s setUnitTestCmd 0x4b 5 %d 0 2 1 2", 11633 ifname, rualloc_type); 11634 } 11635 } else if (value == 242) { 11636 run_system_wrapper( 11637 dut, 11638 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 3 1 3 2 3 3 3", 11639 ifname, rualloc_type); 11640 } else if (value == 26) { 11641 run_system_wrapper( 11642 dut, 11643 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 0 2 0 5 0 7 0", 11644 ifname, rualloc_type); 11645 } else if (value == 52) { 11646 run_system_wrapper( 11647 dut, 11648 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 1 1 1 2 1 3 1", 11649 ifname, rualloc_type); 11650 } else if (value == 484) { 11651 run_system_wrapper( 11652 dut, 11653 "wifitool %s setUnitTestCmd 0x4b 5 %d 0 4 1 4", 11654 ifname, rualloc_type); 11655 } else if (value == 996) { 11656 run_system_wrapper(dut, 11657 "wifitool %s setUnitTestCmd 0x4b 3 %d 0 5", 11658 ifname, rualloc_type); 11659 } else { 11660 send_resp(dut, conn, SIGMA_ERROR, 11661 "errorCode,Unsupported RUAllocTones"); 11662 ret = STATUS_SENT_ERROR; 11663 } 11664 11665 free(token); 11666 return ret; 11667 } 11668 11669 11670 static void ath_set_trigger_type_0(struct sigma_dut *dut, const char *ifname) 11671 { 11672 /* TriggerType "0" for Basic trigger */ 11673 if (dut->ap_channel >= 36) { 11674 /* 1 and 2 here is interpreted to 5g and 2g (bitmasks) */ 11675 run_system_wrapper(dut, 11676 "wifitool %s setUnitTestCmd 0x47 2 42 1", 11677 ifname); 11678 } else { 11679 run_system_wrapper(dut, 11680 "wifitool %s setUnitTestCmd 0x47 2 42 2", 11681 ifname); 11682 } 11683 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 6", 11684 ifname); 11685 } 11686 11687 11688 static void ath_set_trigger_type_1(struct sigma_dut *dut, const char *ifname) 11689 { 11690 /* TriggerType "1" for MU BRP */ 11691 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 1", 11692 ifname); 11693 mubrp_commands(dut, ifname); 11694 } 11695 11696 11697 static void ath_set_trigger_type_2(struct sigma_dut *dut, const char *ifname) 11698 { 11699 /* TriggerType "2" for MU BAR */ 11700 if (dut->ap_channel >= 36) { 11701 /* RU allocation RU 242 - DL OFDMA data */ 11702 run_system_wrapper(dut, 11703 "wifitool %s setUnitTestCmd 0x4b 5 9 0 3 1 3 2 3 3 3", 11704 ifname); 11705 /* RU allocation RU 52 - UL BA */ 11706 run_system_wrapper(dut, 11707 "wifitool %s setUnitTestCmd 0x4b 5 9 0 2 1 2 2 2 3 2", 11708 ifname); 11709 } else { 11710 /* RU allocation RU 52 - DL ofdma data */ 11711 run_system_wrapper(dut, 11712 "wifitool %s setUnitTestCmd 0x4b 5 9 0 1 1 1 2 1 3 1", 11713 ifname); 11714 } 11715 /* Force TBPPDU duration to 400 us */ 11716 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 400", 11717 ifname); 11718 /* 0 to enable MU BAR, 1 to enable SU BAR */ 11719 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 49 0", 11720 ifname); 11721 /* MU BAR */ 11722 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 64 0", 11723 ifname); 11724 } 11725 11726 11727 static void ath_set_trigger_type_3(struct sigma_dut *dut, const char *ifname) 11728 { 11729 /* TriggerType "3" for MU RTS */ 11730 /* Send MU RTS Trigger - '1' is to enable MU RTS */ 11731 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 101 1", 11732 ifname); 11733 } 11734 11735 11736 static void ath_set_trigger_type_4(struct sigma_dut *dut, const char *ifname, 11737 const char *basedev) 11738 { 11739 /* TriggerType "4" for BSRP */ 11740 run_system_wrapper(dut, "cfg80211tool %s he_ul_trig_int 200", basedev); 11741 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 1000", 11742 ifname); 11743 if (dut->ap_channel >= 36) { 11744 run_system_wrapper(dut, 11745 "wifitool %s setUnitTestCmd 0x47 2 42 1", 11746 ifname); 11747 } else { 11748 run_system_wrapper(dut, 11749 "wifitool %s setUnitTestCmd 0x47 2 42 2", 11750 ifname); 11751 } 11752 /* Send BSRP command */ 11753 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 7", 11754 ifname); 11755 } 11756 11757 11758 static enum sigma_cmd_result ath_ap_set_rfeature(struct sigma_dut *dut, 11759 struct sigma_conn *conn, 11760 struct sigma_cmd *cmd) 11761 { 11762 const char *val; 11763 const char *ifname; 11764 enum sigma_cmd_result res; 11765 const char *basedev = "wifi0"; 11766 int trigtype; 11767 int he_ackpolicymac = 0; 11768 char *num_ss = NULL; 11769 char *nss[4] = { NULL, NULL, NULL, NULL }; 11770 char *aid[4] = { NULL, NULL, NULL, NULL }; 11771 char *aid_ss = NULL; 11772 int omctrl_rxnss = 0, omctrl_chwidth = 0; 11773 int param; 11774 unsigned char mac_addr[ETH_ALEN]; 11775 11776 memset(mac_addr, 0x00, ETH_ALEN); 11777 11778 ifname = get_main_ifname(dut); 11779 11780 if (sigma_radio_ifname[0]) 11781 basedev = sigma_radio_ifname[0]; 11782 11783 /* Disable vap reset between the commands */ 11784 novap_reset(dut, ifname, 1); 11785 11786 val = get_param(cmd, "Opt_md_notif_ie"); 11787 if (val && ath_vht_op_mode_notif(dut, ifname, val) < 0) 11788 return ERROR_SEND_STATUS; 11789 11790 /* TODO: Optional arguments */ 11791 11792 val = get_param(cmd, "nss_mcs_opt"); 11793 if (val && ath_vht_nss_mcs(dut, ifname, val) < 0) 11794 return ERROR_SEND_STATUS; 11795 11796 val = get_param(cmd, "chnum_band"); 11797 if (val && ath_vht_chnum_band(dut, ifname, val) < 0) 11798 return ERROR_SEND_STATUS; 11799 11800 val = get_param(cmd, "RTS_FORCE"); 11801 if (val) 11802 ath_config_rts_force(dut, ifname, val); 11803 11804 val = get_param(cmd, "DYN_BW_SGNL"); 11805 if (val) 11806 ath_config_dyn_bw_sig(dut, ifname, val); 11807 11808 val = get_param(cmd, "CTS_WIDTH"); 11809 if (val) 11810 ath_set_cts_width(dut, ifname, val); 11811 11812 val = get_param(cmd, "Ndpa_stainfo_mac"); 11813 if (val && ath_ndpa_stainfo_mac(dut, ifname, val) < 0) 11814 return ERROR_SEND_STATUS; 11815 11816 val = get_param(cmd, "txBandwidth"); 11817 if (val && ath_set_width(dut, conn, ifname, val) < 0) 11818 return ERROR_SEND_STATUS; 11819 11820 val = get_param(cmd, "Assoc_Disallow"); 11821 if (val) 11822 ath_set_assoc_disallow(dut, ifname, val); 11823 11824 11825 ath_set_nebor_bssid(dut, ifname, cmd); 11826 val = get_param(cmd, "BTMReq_DisAssoc_Imnt"); 11827 if (val) { 11828 dut->ap_btmreq_disassoc_imnt = atoi(val); 11829 dut->ap_disassoc_timer = 1000; 11830 } 11831 11832 val = get_param(cmd, "BTMReq_Term_Bit"); 11833 if (val) 11834 dut->ap_btmreq_term_bit = atoi(val); 11835 11836 val = get_param(cmd, "Assoc_Delay"); 11837 if (val) { 11838 dut->ap_assoc_delay = 1; 11839 run_iwpriv(dut, ifname, "mbo_asoc_ret %s", val); 11840 } 11841 11842 val = get_param(cmd, "Disassoc_Timer"); 11843 if (val) 11844 dut->ap_disassoc_timer = atoi(val); 11845 11846 val = get_param(cmd, "BSS_Term_Duration"); 11847 if (val) 11848 dut->ap_btmreq_bss_term_dur = atoi(val); 11849 11850 val = get_param(cmd, "BSS_Term_TSF"); 11851 if (val) 11852 dut->ap_btmreq_bss_term_tsf = atoi(val); 11853 11854 val = get_param(cmd, "TxPower"); 11855 if (val) 11856 ath_set_txpower(dut, ifname, val); 11857 11858 val = get_param(cmd, "DownlinkAvailCap"); 11859 if (val) 11860 dut->ap_dl_availcap = atoi(val); 11861 11862 val = get_param(cmd, "UplinkAvailCap"); 11863 if (val) { 11864 dut->ap_ul_availcap = atoi(val); 11865 run_iwpriv(dut, ifname, "oce_wan_mtr %d %d", 11866 dut->ap_dl_availcap, dut->ap_ul_availcap); 11867 } 11868 11869 val = get_param(cmd, "RSSIthreshold"); 11870 if (val) { 11871 int rssithreshold; 11872 11873 run_iwpriv(dut, ifname, "oce_asoc_rej 1"); 11874 rssithreshold = atoi(val); 11875 run_iwpriv(dut, ifname, "oce_asoc_rssi %d", rssithreshold); 11876 } 11877 11878 val = get_param(cmd, "RetryDelay"); 11879 if (val) { 11880 int retrydelay; 11881 11882 run_iwpriv(dut, ifname, "oce_asoc_rej 1"); 11883 retrydelay = atoi(val); 11884 run_iwpriv(dut, ifname, "oce_asoc_dly %d", retrydelay); 11885 } 11886 11887 val = get_param(cmd, "LTF"); 11888 if (val) { 11889 if (dut->ap_fixed_rate) { 11890 res = he_ltf(dut, conn, ifname, val); 11891 if (res != SUCCESS_SEND_STATUS) 11892 return res; 11893 } else { 11894 free(dut->ar_ltf); 11895 dut->ar_ltf = strdup(val); 11896 if (!dut->ar_ltf) 11897 return ERROR_SEND_STATUS; 11898 } 11899 } 11900 11901 val = get_param(cmd, "GI"); 11902 if (val) { 11903 if (dut->ap_fixed_rate) 11904 res = he_shortgi(dut, conn, ifname, val); 11905 else 11906 res = he_ar_gi_ltf_mask(dut, conn, ifname, val); 11907 if (res != SUCCESS_SEND_STATUS) 11908 return res; 11909 } 11910 11911 val = get_param(cmd, "RUAllocTones"); 11912 if (val) { 11913 res = he_rualloctones(dut, conn, ifname, val); 11914 if (res != SUCCESS_SEND_STATUS) 11915 return res; 11916 } 11917 11918 val = get_param(cmd, "MPDU_MU_SpacingFactor"); 11919 if (val) 11920 run_system_wrapper(dut, 11921 "wifitool %s setUnitTestCmd 0x48 2 119, %s", 11922 ifname, val); 11923 11924 val = get_param(cmd, "PPDUTxType"); 11925 if (val) { 11926 if (strcasecmp(val, "HE-SU") == 0) { 11927 /* Change PPDU format type to HE-SU MCS 1 */ 11928 run_system_wrapper(dut, 11929 "wifitool %s setUnitTestCmd 0x48 2 89 0x401", 11930 ifname); 11931 } else if (strcasecmp(val, "legacy") == 0) { 11932 /* Change PPDU format type to non-HT */ 11933 run_system_wrapper(dut, 11934 "wifitool %s setUnitTestCmd 0x48 2 89 3", 11935 ifname); 11936 } else { 11937 send_resp(dut, conn, SIGMA_ERROR, 11938 "errorCode,Unsupported PPDUTxType"); 11939 return STATUS_SENT_ERROR; 11940 } 11941 } 11942 11943 val = get_param(cmd, "TXOPDuration"); 11944 if (val) { 11945 if (strcasecmp(val, "UNSPECIFIED") == 0) { 11946 /* The hardware is hardcoded with 0x7f; do nothing */ 11947 } else { 11948 send_resp(dut, conn, SIGMA_ERROR, 11949 "errorCode,Unsupported TXOPDuration"); 11950 return STATUS_SENT_ERROR; 11951 } 11952 } 11953 11954 val = get_param(cmd, "Trig_Usrinfo_UL-MCS"); 11955 if (val) 11956 run_iwpriv(dut, ifname, "he_ul_mcs %d", atoi(val)); 11957 11958 val = get_param(cmd, "Trig_Usrinfo_UL-Target-RSSI"); 11959 if (val) { 11960 /* Set target RSSI to -55 dBm */ 11961 run_system_wrapper(dut, 11962 "wifitool %s setUnitTestCmd 0x4b 2 7 %d", 11963 ifname, atoi(val) - 110); 11964 } 11965 11966 val = get_param(cmd, "Trig_Interval"); 11967 if (val) 11968 run_iwpriv(dut, basedev, "he_ul_trig_int %d", atoi(val)); 11969 11970 val = get_param(cmd, "Trig_ComInfo_ULLength"); 11971 if (val) 11972 run_system_wrapper(dut, 11973 "wifitool %s setUnitTestCmd 0x48 2 141 %d", 11974 ifname, atoi(val)); 11975 11976 val = get_param(cmd, "DisableTriggerType"); 11977 if (val) { 11978 trigtype = atoi(val); 11979 switch (trigtype) { 11980 case 0: 11981 /* DisableTriggerType "0" for basic trigger */ 11982 run_system_wrapper(dut, 11983 "wifitool %s setUnitTestCmd 0x47 2 42 0", 11984 ifname); 11985 break; 11986 default: 11987 /* Nothing to be done for now */ 11988 break; 11989 } 11990 } 11991 11992 val = get_param(cmd, "Trigger_TxBF"); 11993 if (val) { 11994 if (strcasecmp(val, "enable") == 0) { 11995 run_iwpriv(dut, ifname, "he_sounding_mode 0x9"); 11996 } else if (strcasecmp(val, "disable") == 0) { 11997 run_iwpriv(dut, ifname, "he_sounding_mode 0x1"); 11998 } else { 11999 send_resp(dut, conn, SIGMA_ERROR, 12000 "errorCode,Unsupported trigger_txbf"); 12001 return STATUS_SENT_ERROR; 12002 } 12003 } 12004 12005 val = get_param(cmd, "Trig_UsrInfo_RUAlloc"); 12006 if (val) { 12007 res = he_rualloctones(dut, conn, ifname, val); 12008 if (res != SUCCESS_SEND_STATUS) 12009 return res; 12010 } 12011 12012 val = get_param(cmd, "TriggerCoding"); 12013 if (val) { 12014 if (strcasecmp(val, "BCC") == 0) { 12015 /* In case of LDPC enable this command can force BCC if 12016 * RU size <= 242 */ 12017 run_iwpriv(dut, ifname, "he_ul_ldpc 0"); 12018 } else if (strcasecmp(val, "LDPC") == 0) { 12019 novap_reset(dut, ifname, 0); 12020 run_iwpriv(dut, ifname, "he_ul_ldpc 1"); 12021 novap_reset(dut, ifname, 1); 12022 } else { 12023 send_resp(dut, conn, SIGMA_ERROR, 12024 "errorCode,Unsupported TriggerCoding"); 12025 return STATUS_SENT_ERROR; 12026 } 12027 } 12028 12029 val = get_param(cmd, "AckPolicy_MAC"); 12030 if (val) { 12031 if (parse_mac_address(dut, val, mac_addr) < 0) { 12032 send_resp(dut, conn, SIGMA_ERROR, 12033 "errorCode,MAC Address not in proper format"); 12034 return STATUS_SENT_ERROR; 12035 } 12036 he_ackpolicymac = 1; 12037 } 12038 12039 val = get_param(cmd, "AckPolicy"); 12040 if (val) { 12041 int ap_he_ackpolicy; 12042 12043 ap_he_ackpolicy = atoi(val); 12044 if (ap_he_ackpolicy == 0 && he_ackpolicymac) { 12045 /* Disable all-BAR ackpolicy for MU-MIMO */ 12046 run_system_wrapper(dut, 12047 "wifitool %s setUnitTestCmd 0x48 2 62 0", 12048 ifname); 12049 /* Disable all-BAR ackpolicy first */ 12050 run_system_wrapper(dut, 12051 "wifitool %s setUnitTestCmd 0x48 2 64 0", 12052 ifname); 12053 /* Set normal ack policy for the STA with the specified 12054 * MAC address in DL-TX case */ 12055 run_system_wrapper(dut, 12056 "wifitool %s setUnitTestCmd 0x4b 8 8 1 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", 12057 ifname, mac_addr[0], mac_addr[1], 12058 mac_addr[2], mac_addr[3], 12059 mac_addr[4], mac_addr[5]); 12060 } else if (ap_he_ackpolicy == 3) { 12061 /* Enable all-BAR ackpolicy for MU-MIMO DL */ 12062 run_system_wrapper(dut, 12063 "wifitool %s setUnitTestCmd 0x48 2 62 1", 12064 ifname); 12065 /* Enable all-BAR ackpolicy */ 12066 run_system_wrapper(dut, 12067 "wifitool %s setUnitTestCmd 0x48 2 64 1", 12068 ifname); 12069 } else if (ap_he_ackpolicy == 4) { 12070 /* Enable htp-ack ackpolicy */ 12071 run_system_wrapper(dut, 12072 "wifitool %s setUnitTestCmd 0x47 2 99 1", 12073 ifname); 12074 } else { 12075 send_resp(dut, conn, SIGMA_ERROR, 12076 "errorCode,Invalid AckPolicy setting"); 12077 return STATUS_SENT_ERROR; 12078 } 12079 } 12080 12081 val = get_param(cmd, "Trig_ComInfo_GI-LTF"); 12082 if (val) { 12083 int trig_gi_ltf; 12084 12085 trig_gi_ltf = atoi(val); 12086 if (trig_gi_ltf == 0) { 12087 he_ltf(dut, conn, ifname, "3.2"); 12088 he_shortgi(dut, conn, ifname, "1.6"); 12089 } else if (trig_gi_ltf == 1) { 12090 he_ltf(dut, conn, ifname, "6.4"); 12091 he_shortgi(dut, conn, ifname, "1.6"); 12092 } else if (trig_gi_ltf == 2) { 12093 he_ltf(dut, conn, ifname, "12.8"); 12094 he_shortgi(dut, conn, ifname, "3.2"); 12095 } else { 12096 send_resp(dut, conn, SIGMA_ERROR, 12097 "errorCode,Unsupported Trig_ComInfo_GI-LTF"); 12098 return STATUS_SENT_ERROR; 12099 } 12100 } 12101 12102 val = get_param(cmd, "Trig_ComInfo_BW"); 12103 if (val) { 12104 int chwidth; 12105 12106 chwidth = atoi(val); 12107 /* Set the channel width */ 12108 run_iwpriv(dut, ifname, "chwidth %d", chwidth); 12109 } 12110 12111 val = get_param(cmd, "NumSS"); 12112 if (val) { 12113 int i = 0; 12114 char *numss_val; 12115 char *saveptr; 12116 12117 num_ss = strdup(val); 12118 if (!num_ss) 12119 return ERROR_SEND_STATUS; 12120 12121 numss_val = strtok_r(num_ss, " ", &saveptr); 12122 for (i = 0; numss_val && i < 4; i++) { 12123 nss[i] = numss_val; 12124 numss_val = strtok_r(NULL, " ", &saveptr); 12125 } 12126 } 12127 12128 val = get_param(cmd, "NumSS_MAC"); 12129 if (val) { 12130 char *sta_mac_str; 12131 char *saveptr; 12132 char *sta_mac_list_str; 12133 12134 sta_mac_list_str = strdup(val); 12135 if (!sta_mac_list_str) { 12136 free(num_ss); 12137 return ERROR_SEND_STATUS; 12138 } 12139 12140 sta_mac_str = strtok_r(sta_mac_list_str, " ", &saveptr); 12141 if (sta_mac_str && nss[0]) { 12142 run_system_wrapper(dut, 12143 "wifitool %s chmask_persta %s %s", 12144 ifname, sta_mac_str, nss[0]); 12145 } 12146 12147 sta_mac_str = strtok_r(NULL, " ", &saveptr); 12148 if (sta_mac_str && nss[1]) { 12149 run_system_wrapper(dut, 12150 "wifitool %s chmask_persta %s %s", 12151 ifname, sta_mac_str, nss[1]); 12152 } 12153 12154 sta_mac_str = strtok_r(NULL, " ", &saveptr); 12155 if (sta_mac_str && nss[2]) { 12156 run_system_wrapper(dut, 12157 "wifitool %s chmask_persta %s %s", 12158 ifname, sta_mac_str, nss[2]); 12159 } 12160 12161 sta_mac_str = strtok_r(NULL, " ", &saveptr); 12162 if (sta_mac_str && nss[3]) { 12163 run_system_wrapper(dut, 12164 "wifitool %s chmask_persta %s %s", 12165 ifname, sta_mac_str, nss[3]); 12166 } 12167 12168 free(sta_mac_list_str); 12169 } 12170 12171 free(num_ss); 12172 num_ss = NULL; 12173 12174 val = get_param(cmd, "AID"); 12175 if (val) { 12176 int i = 0; 12177 char *aid_val; 12178 char *saveptr; 12179 12180 aid_ss = strdup(val); 12181 if (!aid_ss) 12182 return ERROR_SEND_STATUS; 12183 12184 aid_val = strtok_r(aid_ss, " ", &saveptr); 12185 for (i = 0; aid_val && i < 4; i++) { 12186 aid[i] = aid_val; 12187 aid_val = strtok_r(NULL, " ", &saveptr); 12188 } 12189 } 12190 12191 val = get_param(cmd, "AddbaReq"); 12192 if (val) { 12193 if (strcasecmp(val, "enable") == 0) { 12194 run_iwpriv(dut, ifname, "setaddbaoper 1"); 12195 run_system_wrapper(dut, 12196 "wifitool %s sendaddba %s 0 64", 12197 ifname, aid[0]); 12198 } else { 12199 send_resp(dut, conn, SIGMA_ERROR, 12200 "errorCode,Unsupported AddbaReq value"); 12201 free(aid_ss); 12202 return STATUS_SENT_ERROR; 12203 } 12204 } 12205 12206 val = get_param(cmd, "AddbaResp"); 12207 if (val) { 12208 if (aid_ss && strcasecmp(val, "accepted") == 0) { 12209 int aid_1 = atoi(aid_ss); 12210 12211 if (aid_1 == 1) 12212 aid_1 = 2; 12213 else 12214 aid_1 = aid_1 - 1; 12215 12216 /* There is no mechanism in place to reject Add BA Req 12217 * from all STAs and selectively accept Add BA Req from 12218 * a specified STA. Instead, it can accept Add BA Req 12219 * from all STAs and selectively reject from specified 12220 * STAs. Make changes for the same using the below 12221 * commands. */ 12222 run_system_wrapper(dut, ifname, "setaddbaoper 1"); 12223 run_system_wrapper(dut, "wifitool %s refusealladdbas 0", 12224 ifname); 12225 run_system_wrapper(dut, 12226 "wifitool %s setaddbaresp %d 0 37", 12227 ifname, aid_1); 12228 } else { 12229 send_resp(dut, conn, SIGMA_ERROR, 12230 "errorCode,Unsupported Addbaresp value"); 12231 free(aid_ss); 12232 return STATUS_SENT_ERROR; 12233 } 12234 } 12235 12236 val = get_param(cmd, "Trig_UsrInfo_SSAlloc_RA-RU"); 12237 if (val) { 12238 char *ssalloc_str; 12239 char *saveptr; 12240 char *ssalloc_list_str; 12241 12242 ssalloc_list_str = strdup(val); 12243 if (!ssalloc_list_str) { 12244 free(aid_ss); 12245 return ERROR_SEND_STATUS; 12246 } 12247 12248 ssalloc_str = strtok_r(ssalloc_list_str, ":", &saveptr); 12249 if (ssalloc_str && aid[0]) { 12250 run_system_wrapper(dut, "wifitool %s peer_nss %s %s", 12251 ifname, aid[0], ssalloc_str); 12252 } 12253 12254 ssalloc_str = strtok_r(NULL, " ", &saveptr); 12255 if (ssalloc_str && aid[1]) { 12256 run_system_wrapper(dut, "wifitool %s peer_nss %s %s", 12257 ifname, aid[1], ssalloc_str); 12258 } 12259 12260 ssalloc_str = strtok_r(NULL, " ", &saveptr); 12261 if (ssalloc_str && aid[2]) { 12262 run_system_wrapper(dut, "wifitool %s peer_nss %s %s", 12263 ifname, aid[2], ssalloc_str); 12264 } 12265 12266 ssalloc_str = strtok_r(NULL, " ", &saveptr); 12267 if (ssalloc_str && aid[3]) { 12268 run_system_wrapper(dut, "wifitool %s peer_nss %s %s", 12269 ifname, aid[3], ssalloc_str); 12270 } 12271 12272 free(ssalloc_list_str); 12273 } 12274 12275 free(aid_ss); 12276 aid_ss = NULL; 12277 12278 val = get_param(cmd, "OMCtrl_RxNSS"); 12279 if (val) 12280 omctrl_rxnss = atoi(val); 12281 12282 val = get_param(cmd, "OMCtrl_ChnlWidth"); 12283 if (val) 12284 omctrl_chwidth = atoi(val); 12285 12286 val = get_param(cmd, "Client_mac"); 12287 if (val) { 12288 if (parse_mac_address(dut, val, mac_addr) < 0) { 12289 send_resp(dut, conn, SIGMA_ERROR, 12290 "errorCode,MAC Address not in proper format"); 12291 return STATUS_SENT_ERROR; 12292 } 12293 12294 /* setUnitTestCmd 13 7 1 mac3mac2mac1mac0 mac5mac4 <rx_nss> 12295 * <bw> <ulmu> <tx_nss> */ 12296 run_system_wrapper(dut, 12297 "wifitool %s setUnitTestCmd 13 7 1 0x%02x%02x%02x%02x 0x%02x%02x %d %d 1 %d", 12298 ifname, mac_addr[3], mac_addr[2], 12299 mac_addr[1], mac_addr[0], mac_addr[5], 12300 mac_addr[4], omctrl_rxnss, 12301 omctrl_chwidth, omctrl_rxnss); 12302 } 12303 12304 val = get_param(cmd, "TriggerType"); 12305 if (val) { 12306 trigtype = atoi(val); 12307 switch (trigtype) { 12308 case 0: 12309 ath_set_trigger_type_0(dut, ifname); 12310 break; 12311 case 1: 12312 ath_set_trigger_type_1(dut, ifname); 12313 break; 12314 case 2: 12315 ath_set_trigger_type_2(dut, ifname); 12316 break; 12317 case 3: 12318 ath_set_trigger_type_3(dut, ifname); 12319 break; 12320 case 4: 12321 ath_set_trigger_type_4(dut, ifname, basedev); 12322 break; 12323 default: 12324 send_resp(dut, conn, SIGMA_ERROR, 12325 "errorCode,TriggerType not supported"); 12326 return STATUS_SENT_ERROR; 12327 } 12328 } 12329 12330 val = get_param(cmd, "HE_TXOPDurRTSThr"); 12331 if (val) 12332 run_iwpriv(dut, ifname, "he_rtsthrshld %d", atoi(val)); 12333 12334 val = get_param(cmd, "NAV_Update"); 12335 if (val) { 12336 if (strcasecmp(val, "disable") == 0) { 12337 run_iwpriv(dut, basedev, "nav_config 1 0"); 12338 } else if (strcasecmp(val, "enable") == 0) { 12339 /* Do nothing */ 12340 } else { 12341 send_resp(dut, conn, SIGMA_ERROR, 12342 "errorCode,Unsupported NAV update"); 12343 return STATUS_SENT_ERROR; 12344 } 12345 } 12346 12347 /* Configure WMM Parameter Elements */ 12348 val = get_param(cmd, "STA_WMMPE_ECWmin_BE"); 12349 if (val) { 12350 param = atoi(val); 12351 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BE, param); 12352 } 12353 12354 val = get_param(cmd, "STA_WMMPE_ECWmin_BK"); 12355 if (val) { 12356 param = atoi(val); 12357 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BK, param); 12358 } 12359 12360 val = get_param(cmd, "STA_WMMPE_ECWmin_VI"); 12361 if (val) { 12362 param = atoi(val); 12363 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VI, param); 12364 } 12365 12366 val = get_param(cmd, "STA_WMMPE_ECWmin_VO"); 12367 if (val) { 12368 param = atoi(val); 12369 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VO, param); 12370 } 12371 12372 val = get_param(cmd, "STA_WMMPE_ECWmax_BE"); 12373 if (val) { 12374 param = atoi(val); 12375 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BE, param); 12376 } 12377 12378 val = get_param(cmd, "STA_WMMPE_ECWmax_BK"); 12379 if (val) { 12380 param = atoi(val); 12381 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BK, param); 12382 } 12383 12384 val = get_param(cmd, "STA_WMMPE_ECWmax_VI"); 12385 if (val) { 12386 param = atoi(val); 12387 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VI, param); 12388 } 12389 12390 val = get_param(cmd, "STA_WMMPE_ECWmax_VO"); 12391 if (val) { 12392 param = atoi(val); 12393 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VO, param); 12394 } 12395 12396 val = get_param(cmd, "STA_WMMPE_AIFSN_BE"); 12397 if (val) { 12398 param = atoi(val); 12399 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BE, param); 12400 } 12401 12402 val = get_param(cmd, "STA_WMMPE_AIFSN_BK"); 12403 if (val) { 12404 param = atoi(val); 12405 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BK, param); 12406 } 12407 12408 val = get_param(cmd, "STA_WMMPE_AIFSN_VI"); 12409 if (val) { 12410 param = atoi(val); 12411 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VI, param); 12412 } 12413 12414 val = get_param(cmd, "STA_WMMPE_AIFSN_VO"); 12415 if (val) { 12416 param = atoi(val); 12417 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VO, param); 12418 } 12419 12420 12421 val = get_param(cmd, "STA_WMMPE_TXOP_BE"); 12422 if (val) { 12423 param = atoi(val); 12424 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BE, param); 12425 } 12426 12427 val = get_param(cmd, "STA_WMMPE_TOXP_BK"); 12428 if (val) { 12429 param = atoi(val); 12430 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BK, param); 12431 } 12432 12433 val = get_param(cmd, "STA_WMMPE_TXOP_VI"); 12434 if (val) { 12435 param = atoi(val); 12436 run_iwpriv(dut, ifname, "txoplimit %d %d", AP_AC_VI, param); 12437 } 12438 12439 val = get_param(cmd, "STA_WMMPE_TXOP_VO"); 12440 if (val) { 12441 param = atoi(val); 12442 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_VO, param); 12443 } 12444 12445 /* Configure MU EDCA */ 12446 val = get_param(cmd, "STA_MUEDCA_ECWmin_BE"); 12447 if (val) { 12448 param = atoi(val); 12449 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BE, param); 12450 } 12451 12452 val = get_param(cmd, "STA_MUEDCA_ECWmin_BK"); 12453 if (val) { 12454 param = atoi(val); 12455 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BK, param); 12456 } 12457 12458 val = get_param(cmd, "STA_MUEDCA_ECWmin_VI"); 12459 if (val) { 12460 param = atoi(val); 12461 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VI, param); 12462 } 12463 12464 val = get_param(cmd, "STA_MUEDCA_ECWmin_VO"); 12465 if (val) { 12466 param = atoi(val); 12467 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VO, param); 12468 } 12469 12470 val = get_param(cmd, "STA_MUEDCA_ECWmax_BE"); 12471 if (val) { 12472 param = atoi(val); 12473 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BE, param); 12474 } 12475 12476 val = get_param(cmd, "STA_MUEDCA_ECWmax_BK"); 12477 if (val) { 12478 param = atoi(val); 12479 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BK, param); 12480 } 12481 12482 val = get_param(cmd, "STA_MUEDCA_ECWmax_VI"); 12483 if (val) { 12484 param = atoi(val); 12485 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VI, param); 12486 } 12487 12488 val = get_param(cmd, "STA_MUEDCA_ECWmax_VO"); 12489 if (val) { 12490 param = atoi(val); 12491 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VO, param); 12492 } 12493 12494 val = get_param(cmd, "STA_MUEDCA_AIFSN_BE"); 12495 if (val) { 12496 param = atoi(val); 12497 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BE, param); 12498 } 12499 12500 val = get_param(cmd, "STA_MUEDCA_AIFSN_BK"); 12501 if (val) { 12502 param = atoi(val); 12503 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BK, param); 12504 } 12505 12506 val = get_param(cmd, "STA_MUEDCA_AIFSN_VI"); 12507 if (val) { 12508 param = atoi(val); 12509 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VI, param); 12510 } 12511 12512 val = get_param(cmd, "STA_MUEDCA_AIFSN_VO"); 12513 if (val) { 12514 param = atoi(val); 12515 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VO, param); 12516 } 12517 12518 val = get_param(cmd, "STA_MUEDCA_Timer_BE"); 12519 if (val) { 12520 param = atoi(val); 12521 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BE, param); 12522 } 12523 12524 val = get_param(cmd, "STA_MUEDCA_Timer_BK"); 12525 if (val) { 12526 param = atoi(val); 12527 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BK, param); 12528 } 12529 12530 val = get_param(cmd, "STA_MUEDCA_Timer_VI"); 12531 if (val) { 12532 param = atoi(val); 12533 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VI, param); 12534 } 12535 12536 val = get_param(cmd, "STA_MUEDCA_Timer_VO"); 12537 if (val) { 12538 param = atoi(val); 12539 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VO, param); 12540 } 12541 12542 return SUCCESS_SEND_STATUS; 12543 } 12544 12545 12546 static int wcn_vht_chnum_band(struct sigma_dut *dut, const char *ifname, 12547 const char *val) 12548 { 12549 char *token, *result; 12550 int channel = 36; 12551 char *saveptr; 12552 12553 /* Extract the channel info */ 12554 token = strdup(val); 12555 if (!token) 12556 return -1; 12557 result = strtok_r(token, ";", &saveptr); 12558 if (result) 12559 channel = atoi(result); 12560 12561 /* Issue the channel switch command */ 12562 run_iwpriv(dut, ifname, "setChanChange %d", channel); 12563 12564 free(token); 12565 return 0; 12566 } 12567 12568 12569 static enum sigma_cmd_result wcn_ap_set_rfeature(struct sigma_dut *dut, 12570 struct sigma_conn *conn, 12571 struct sigma_cmd *cmd) 12572 { 12573 const char *val; 12574 const char *ifname; 12575 12576 ifname = get_main_ifname(dut); 12577 12578 val = get_param(cmd, "chnum_band"); 12579 if (val && wcn_vht_chnum_band(dut, ifname, val) < 0) 12580 return ERROR_SEND_STATUS; 12581 12582 val = get_param(cmd, "txBandwidth"); 12583 if (val) { 12584 int old_ch_bw = dut->ap_chwidth; 12585 12586 if (strcasecmp(val, "Auto") == 0) { 12587 dut->ap_chwidth = 0; 12588 } else if (strcasecmp(val, "20") == 0) { 12589 dut->ap_chwidth = 0; 12590 } else if (strcasecmp(val, "40") == 0) { 12591 dut->ap_chwidth = 1; 12592 } else if (strcasecmp(val, "80") == 0) { 12593 dut->ap_chwidth = 2; 12594 } else if (strcasecmp(val, "160") == 0) { 12595 dut->ap_chwidth = 3; 12596 } else { 12597 send_resp(dut, conn, SIGMA_ERROR, 12598 "ErrorCode,WIDTH not supported"); 12599 return STATUS_SENT_ERROR; 12600 } 12601 if (old_ch_bw != dut->ap_chwidth) { 12602 if (cmd_ap_config_commit(dut, conn, cmd) <= 0) 12603 return STATUS_SENT_ERROR; 12604 } else { 12605 sigma_dut_print(dut, DUT_MSG_DEBUG, "No change in BW"); 12606 } 12607 } 12608 12609 val = get_param(cmd, "GI"); 12610 if (val) { 12611 int fix_rate_sgi; 12612 12613 if (strcmp(val, "0.8") == 0) { 12614 run_iwpriv(dut, ifname, "enable_short_gi 9"); 12615 fix_rate_sgi = 1; 12616 } else if (strcmp(val, "1.6") == 0) { 12617 run_iwpriv(dut, ifname, "enable_short_gi 10"); 12618 fix_rate_sgi = 2; 12619 } else if (strcmp(val, "3.2") == 0) { 12620 run_iwpriv(dut, ifname, "enable_short_gi 11"); 12621 fix_rate_sgi = 3; 12622 } else { 12623 send_resp(dut, conn, SIGMA_ERROR, 12624 "errorCode,GI value not supported"); 12625 return STATUS_SENT_ERROR; 12626 } 12627 run_iwpriv(dut, ifname, "enable_short_gi %d", fix_rate_sgi); 12628 } 12629 12630 val = get_param(cmd, "LTF"); 12631 if (val) { 12632 #ifdef NL80211_SUPPORT 12633 if (strcmp(val, "3.2") == 0) { 12634 wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_1X); 12635 } if (strcmp(val, "6.4") == 0) { 12636 wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_2X); 12637 } else if (strcmp(val, "12.8") == 0) { 12638 wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_4X); 12639 } else { 12640 send_resp(dut, conn, SIGMA_ERROR, 12641 "errorCode,LTF value not supported"); 12642 return STATUS_SENT; 12643 } 12644 #else /* NL80211_SUPPORT */ 12645 sigma_dut_print(dut, DUT_MSG_ERROR, 12646 "LTF cannot be set without NL80211_SUPPORT defined"); 12647 return ERROR_SEND_STATUS; 12648 #endif /* NL80211_SUPPORT */ 12649 } 12650 12651 return SUCCESS_SEND_STATUS; 12652 } 12653 12654 12655 static int mac80211_vht_chnum_band(struct sigma_dut *dut, const char *ifname, 12656 const char *val) 12657 { 12658 char *token, *result; 12659 int channel = 36, chwidth = 80, center_freq_idx, center_freq, 12660 channel_freq; 12661 char buf[100]; 12662 char *saveptr; 12663 int res; 12664 12665 /* Extract the channel info */ 12666 token = strdup(val); 12667 if (!token) 12668 return -1; 12669 result = strtok_r(token, ";", &saveptr); 12670 if (result) 12671 channel = atoi(result); 12672 12673 /* Extract the channel width info */ 12674 result = strtok_r(NULL, ";", &saveptr); 12675 if (result) 12676 chwidth = atoi(result); 12677 12678 center_freq_idx = get_oper_centr_freq_seq_idx(chwidth, channel); 12679 if (center_freq_idx < 0) { 12680 free(token); 12681 return -1; 12682 } 12683 12684 center_freq = get_5g_channel_freq(center_freq_idx); 12685 channel_freq = get_5g_channel_freq(channel); 12686 12687 /* Issue the channel switch command */ 12688 res = snprintf(buf, sizeof(buf), 12689 " -i %s chan_switch 10 %d sec_channel_offset=1 center_freq1=%d bandwidth=%d blocktx vht", 12690 ifname, channel_freq, center_freq, chwidth); 12691 if (res < 0 || res >= sizeof(buf) || run_hostapd_cli(dut, buf) != 0) { 12692 sigma_dut_print(dut, DUT_MSG_ERROR, 12693 "hostapd_cli chan_switch failed"); 12694 } 12695 12696 free(token); 12697 return 0; 12698 } 12699 12700 12701 static int mac80211_ap_set_rfeature(struct sigma_dut *dut, 12702 struct sigma_conn *conn, 12703 struct sigma_cmd *cmd) 12704 { 12705 const char *val; 12706 const char *ifname; 12707 12708 ifname = get_main_ifname(dut); 12709 12710 val = get_param(cmd, "RTS_FORCE"); 12711 if (val) 12712 mac80211_config_rts_force(dut, ifname, val); 12713 12714 val = get_param(cmd, "chnum_band"); 12715 if (val && mac80211_vht_chnum_band(dut, ifname, val) < 0) 12716 return -1; 12717 12718 return 1; 12719 } 12720 12721 12722 #ifdef __linux__ 12723 static int wil6210_ap_set_rfeature(struct sigma_dut *dut, 12724 struct sigma_conn *conn, 12725 struct sigma_cmd *cmd) 12726 { 12727 const char *val; 12728 12729 val = get_param(cmd, "ExtSchIE"); 12730 if (val && !strcasecmp(val, "Enable")) { 12731 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS]; 12732 int count = MAX_ESE_ALLOCS; 12733 12734 if (sta_extract_60g_ese(dut, cmd, allocs, &count)) 12735 return -1; 12736 if (wil6210_set_ese(dut, count, allocs)) 12737 return -1; 12738 return 1; 12739 } 12740 12741 send_resp(dut, conn, SIGMA_ERROR, 12742 "errorCode,Invalid ap_set_rfeature(60G)"); 12743 return 0; 12744 } 12745 #endif /* __linux__ */ 12746 12747 12748 static enum sigma_cmd_result cmd_ap_set_rfeature(struct sigma_dut *dut, 12749 struct sigma_conn *conn, 12750 struct sigma_cmd *cmd) 12751 { 12752 /* const char *name = get_param(cmd, "NAME"); */ 12753 /* const char *type = get_param(cmd, "Type"); */ 12754 const char *val; 12755 char buf[100]; 12756 12757 val = get_param(cmd, "ReassocResp_RSNXE_Used"); 12758 if (val) { 12759 const char *ifname = get_hostapd_ifname(dut); 12760 12761 if (atoi(val) == 0) 12762 snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 2"); 12763 else 12764 snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 1"); 12765 if (hapd_command(ifname, buf) < 0) { 12766 send_resp(dut, conn, SIGMA_ERROR, 12767 "ErrorCode,Failed to set ft_rsnxe_used"); 12768 return STATUS_SENT_ERROR; 12769 } 12770 } 12771 12772 switch (get_driver_type(dut)) { 12773 case DRIVER_ATHEROS: 12774 return ath_ap_set_rfeature(dut, conn, cmd); 12775 case DRIVER_OPENWRT: 12776 switch (get_openwrt_driver_type()) { 12777 case OPENWRT_DRIVER_ATHEROS: 12778 return ath_ap_set_rfeature(dut, conn, cmd); 12779 default: 12780 send_resp(dut, conn, SIGMA_ERROR, 12781 "errorCode,Unsupported ap_set_rfeature with the current openwrt driver"); 12782 return 0; 12783 } 12784 case DRIVER_LINUX_WCN: 12785 case DRIVER_WCN: 12786 return wcn_ap_set_rfeature(dut, conn, cmd); 12787 case DRIVER_MAC80211: 12788 return mac80211_ap_set_rfeature(dut, conn, cmd); 12789 #ifdef __linux__ 12790 case DRIVER_WIL6210: 12791 return wil6210_ap_set_rfeature(dut, conn, cmd); 12792 #endif /* __linux__ */ 12793 default: 12794 send_resp(dut, conn, SIGMA_ERROR, 12795 "errorCode,Unsupported ap_set_rfeature with the current driver"); 12796 return 0; 12797 } 12798 } 12799 12800 12801 static enum sigma_cmd_result cmd_accesspoint(struct sigma_dut *dut, 12802 struct sigma_conn *conn, 12803 struct sigma_cmd *cmd) 12804 { 12805 /* const char *name = get_param(cmd, "NAME"); */ 12806 return 1; 12807 } 12808 12809 12810 static enum sigma_cmd_result 12811 cmd_ap_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn, 12812 struct sigma_cmd *cmd) 12813 { 12814 const char *val; 12815 12816 val = get_param(cmd, "Oper_Chn"); 12817 if (val) { 12818 dut->ap_oper_chn = 1; 12819 dut->ap_channel = atoi(val); 12820 } 12821 12822 val = get_param(cmd, "DPPConfiguratorAddress"); 12823 if (val) { 12824 free(dut->ap_dpp_conf_addr); 12825 dut->ap_dpp_conf_addr = strdup(val); 12826 } 12827 12828 val = get_param(cmd, "DPPConfiguratorPKHash"); 12829 if (val) { 12830 free(dut->ap_dpp_conf_pkhash); 12831 dut->ap_dpp_conf_pkhash = strdup(val); 12832 } 12833 12834 return 1; 12835 } 12836 12837 12838 void ap_register_cmds(void) 12839 { 12840 sigma_dut_reg_cmd("ap_ca_version", NULL, cmd_ap_ca_version); 12841 sigma_dut_reg_cmd("ap_set_wireless", NULL, cmd_ap_set_wireless); 12842 sigma_dut_reg_cmd("ap_send_addba_req", NULL, cmd_ap_send_addba_req); 12843 sigma_dut_reg_cmd("ap_set_11n_wireless", NULL, cmd_ap_set_wireless); 12844 sigma_dut_reg_cmd("ap_set_11n", NULL, cmd_ap_set_wireless); 12845 sigma_dut_reg_cmd("ap_set_11d", NULL, cmd_ap_set_wireless); 12846 sigma_dut_reg_cmd("ap_set_11h", NULL, cmd_ap_set_wireless); 12847 sigma_dut_reg_cmd("ap_set_security", NULL, cmd_ap_set_security); 12848 sigma_dut_reg_cmd("ap_set_apqos", NULL, cmd_ap_set_apqos); 12849 sigma_dut_reg_cmd("ap_set_staqos", NULL, cmd_ap_set_staqos); 12850 sigma_dut_reg_cmd("ap_set_radius", NULL, cmd_ap_set_radius); 12851 sigma_dut_reg_cmd("ap_reboot", NULL, cmd_ap_reboot); 12852 sigma_dut_reg_cmd("ap_config_commit", NULL, cmd_ap_config_commit); 12853 sigma_dut_reg_cmd("ap_reset_default", NULL, cmd_ap_reset_default); 12854 sigma_dut_reg_cmd("ap_get_info", NULL, cmd_ap_get_info); 12855 sigma_dut_reg_cmd("ap_deauth_sta", NULL, cmd_ap_deauth_sta); 12856 sigma_dut_reg_cmd("ap_send_frame", NULL, cmd_ap_send_frame); 12857 sigma_dut_reg_cmd("ap_get_mac_address", NULL, cmd_ap_get_mac_address); 12858 sigma_dut_reg_cmd("ap_set_pmf", NULL, cmd_ap_set_pmf); 12859 sigma_dut_reg_cmd("ap_set_hs2", NULL, cmd_ap_set_hs2); 12860 sigma_dut_reg_cmd("ap_set_rfeature", NULL, cmd_ap_set_rfeature); 12861 sigma_dut_reg_cmd("ap_nfc_action", NULL, cmd_ap_nfc_action); 12862 sigma_dut_reg_cmd("ap_wps_read_pin", NULL, cmd_ap_wps_read_pin); 12863 sigma_dut_reg_cmd("ap_wps_enter_pin", NULL, cmd_ap_wps_enter_pin); 12864 sigma_dut_reg_cmd("ap_wps_set_pbc", NULL, cmd_ap_wps_set_pbc); 12865 sigma_dut_reg_cmd("ap_get_parameter", NULL, cmd_ap_get_parameter); 12866 sigma_dut_reg_cmd("AccessPoint", NULL, cmd_accesspoint); 12867 sigma_dut_reg_cmd("ap_preset_testparameters", NULL, 12868 cmd_ap_preset_testparameters); 12869 } 12870